[med-svn] [r-cran-rniftilib] 05/11: Imported Upstream version 0.0-32
Andreas Tille
tille at debian.org
Sat Jan 23 07:53:56 UTC 2016
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository r-cran-rniftilib.
commit 0754c0664c55e604da6b0d81b817f879b5146c78
Author: Andreas Tille <tille at debian.org>
Date: Sat Jan 23 08:47:50 2016 +0100
Imported Upstream version 0.0-32
---
DESCRIPTION | 18 +
MD5 | 31 +
NAMESPACE | 10 +
R/FirstLib.R | 17 +
R/nifti.R | 174 +
aclocal.m4 | 14 +
ax_check_zlib.m4 | 124 +
config.h.in | 62 +
configure | 5655 +++++++++++++++++++++++++++
debian/README.test | 7 -
debian/changelog | 5 -
debian/compat | 1 -
debian/control | 19 -
debian/copyright | 28 -
debian/rules | 13 -
debian/source/format | 1 -
debian/watch | 2 -
man/nifti.Rd | 126 +
man/nifti_compiled_with_zlib.Rd | 28 +
man/nifti_datatype_string.Rd | 31 +
man/nifti_disp_lib_version.Rd | 24 +
man/nifti_image_alloc_data.Rd | 35 +
man/nifti_image_copy_info.Rd | 36 +
man/nifti_image_free.Rd | 32 +
man/nifti_image_new.Rd | 36 +
man/nifti_image_read.Rd | 50 +
man/nifti_image_setdatatype.Rd | 69 +
man/nifti_image_unload.Rd | 31 +
man/nifti_image_write.Rd | 32 +
man/nifti_interpolate3D.Rd | 42 +
man/nifti_read_subregion_image.Rd | 43 +
man/nifti_set_filenames.Rd | 38 +
man/nifti_units_string.Rd | 31 +
src/Makevars.in | 2 +
src/Rnifti.c | 1687 +++++++++
src/nifti1.h | 1490 ++++++++
src/nifti1_io.c | 7569 +++++++++++++++++++++++++++++++++++++
src/nifti1_io.h | 555 +++
src/znzlib.c | 327 ++
src/znzlib.h | 129 +
40 files changed, 18548 insertions(+), 76 deletions(-)
diff --git a/DESCRIPTION b/DESCRIPTION
new file mode 100644
index 0000000..f951338
--- /dev/null
+++ b/DESCRIPTION
@@ -0,0 +1,18 @@
+Package: Rniftilib
+Version: 0.0-32
+Date: 2012-02-28
+Title: Rniftilib - R Interface to NIFTICLIB (V2.0.0: 2010-07-20)
+Author: Oliver Granert <o.granert <at> neurologie.uni-kiel.de>
+Maintainer: Oliver Granert <o.granert at neurologie.uni-kiel.de>
+Depends: R (>= 1.8.0)
+Suggests:
+Description: R interface to nifticlib (nifticlib-2.0.0) (read/write
+ ANALYZE(TM)7.5/NIfTI-1 volume images)
+License: GPL (>= 2)
+URL: http://rniftilib.r-forge.r-project.org/
+Repository: CRAN
+Repository/R-Forge/Project: rniftilib
+Repository/R-Forge/Revision: 56
+Repository/R-Forge/DateTimeStamp: 2013-01-09 08:02:10
+Date/Publication: 2013-01-09 22:53:32
+Packaged: 2013-01-09 11:17:13 UTC; rforge
diff --git a/MD5 b/MD5
new file mode 100644
index 0000000..5bf9df8
--- /dev/null
+++ b/MD5
@@ -0,0 +1,31 @@
+884c037c94842902da2a3c8a0c65d0f6 *DESCRIPTION
+76e0dcf8e7f673276552a8716f8a0dcb *NAMESPACE
+242236e11d4a2cd05c4b9b12491d44a9 *R/FirstLib.R
+77a59777688961dc624920f16efbb0b4 *R/nifti.R
+273c6e72840b936f5344c4f86e5ff14f *aclocal.m4
+b1aa4ae453e5e1977ac0499b8b063239 *ax_check_zlib.m4
+8ff747358eb34ea32927437a911ad4a2 *config.h.in
+2c560e99c34240970cc606923ee44ac9 *configure
+0a296d28c735d73c45dc405c35fdeb7c *man/nifti.Rd
+646418076b2ece81a187867f9ad7e0f5 *man/nifti_compiled_with_zlib.Rd
+fff00980dc6554bfd269740fd5050eb5 *man/nifti_datatype_string.Rd
+e7b2e14e203d6e445d82866164ead19d *man/nifti_disp_lib_version.Rd
+5e49bd6a3dbcf915b37fc04c86b8e84a *man/nifti_image_alloc_data.Rd
+6e9695d6e29816a883e2053b9648636c *man/nifti_image_copy_info.Rd
+900db6e48804ebf0a57cb08cbeb5d38b *man/nifti_image_free.Rd
+37900ab79fec037a1915854c96e28cda *man/nifti_image_new.Rd
+dbb7f78a624af299f39c396379f2ac2c *man/nifti_image_read.Rd
+dca29b72df0b858cbd3511474c4283a6 *man/nifti_image_setdatatype.Rd
+a3a92959c7f6806f681283c4fd427538 *man/nifti_image_unload.Rd
+87d7526759fe7d1c091fe2fbfcc4c538 *man/nifti_image_write.Rd
+0f1d716c3f6237f006ab37c88078da2b *man/nifti_interpolate3D.Rd
+f3980cbeedddc3204acb559a52d6b4a9 *man/nifti_read_subregion_image.Rd
+c19b86a1ebb48e09b8ad54f619b73994 *man/nifti_set_filenames.Rd
+5e403154b3dde7ffeda36f528809a3e5 *man/nifti_units_string.Rd
+57bed97ab321fc58adda3494b98176b6 *src/Makevars.in
+2f8293076dac8388836c9ce0fd3c13fe *src/Rnifti.c
+1bc087b9e954b8b395d9379d43158f6e *src/nifti1.h
+4e47ac05ed5c500902736b7f7fe8c78d *src/nifti1_io.c
+3ffa2b1885d2ed474f2f0bca5fa6d4af *src/nifti1_io.h
+9d845690f5382b6c3bea879e91821b09 *src/znzlib.c
+582b9f5d055aad992611f091fc13a26b *src/znzlib.h
diff --git a/NAMESPACE b/NAMESPACE
new file mode 100644
index 0000000..0f8ac48
--- /dev/null
+++ b/NAMESPACE
@@ -0,0 +1,10 @@
+useDynLib(Rniftilib)
+export(nifti.image.new, nifti.image.alloc.data, nifti.image.unload, nifti.image.free)
+export(nifti.image.copy.info, nifti.set.filenames)
+export(nifti.image.read, nifti.image.write)
+export(is.nifti, nifti.image.setdatatype)
+export(nifti.read.subregion.image, nifti.interpolate3d)
+export(plot.nifti, print.nifti)
+export(nifti.compiled.with.zlib, nifti.disp.lib.version)
+export(nifti.units.string, nifti.datatype.string)
+export("$.nifti","$<-.nifti","[.nifti","[<-.nifti","dim.nifti","dim<-.nifti")
diff --git a/R/FirstLib.R b/R/FirstLib.R
new file mode 100644
index 0000000..bfc68fd
--- /dev/null
+++ b/R/FirstLib.R
@@ -0,0 +1,17 @@
+## FirstLib: initialization of Rniftilib
+##.First.lib <- function(lib, pkg)
+##{
+## library.dynam("Rniftilib", pkg, lib)
+##}
+
+## LastLib: cleanup of Rniftilib
+##.Last.lib <- function(libpath)
+##{
+## library.dynam.unload("Rniftilib", libpath)
+##}
+
+.onLoad <- function(libname, pkgname)
+{
+ .Call("Rnifti_init", libname, PACKAGE=pkgname)
+}
+
diff --git a/R/nifti.R b/R/nifti.R
new file mode 100644
index 0000000..5276bfe
--- /dev/null
+++ b/R/nifti.R
@@ -0,0 +1,174 @@
+nifti.image.new <- function()
+{
+ .Call("Rnifti_image_new", PACKAGE="Rniftilib")
+}
+
+nifti.image.alloc.data <- function(nim)
+{
+ .Call("Rnifti_image_alloc_data", nim, PACKAGE="Rniftilib")
+}
+
+nifti.image.unload <- function(nim)
+{
+ .Call("Rnifti_image_unload", nim, PACKAGE="Rniftilib")
+}
+
+nifti.image.free <- function(nim)
+{
+ .Call("Rnifti_image_free", nim, PACKAGE="Rniftilib")
+}
+
+nifti.image.copy.info <- function(nim)
+{
+ .Call("Rnifti_image_copy_info", nim, PACKAGE="Rniftilib")
+}
+
+nifti.set.filenames <- function(nim, prefix, check=1, set_byte_order=1)
+{
+ .Call("Rnifti_set_filenames", nim, prefix, check, set_byte_order,
+ PACKAGE="Rniftilib")
+}
+
+nifti.image.read <- function(file, read_data=1, rm.NaN=TRUE)
+{
+ .Call("Rnifti_image_read", file, read_data, rm.NaN, PACKAGE="Rniftilib")
+}
+
+nifti.image.write <- function(nim)
+{
+ .Call("Rnifti_image_write", nim, PACKAGE="Rniftilib")
+}
+
+nifti.image.getdim.save <- function(nim, index)
+{
+ d <- dim(nim)
+ retval <- 1
+ if (length(d) >= index)
+ retval <- d[index]
+ retval
+}
+
+is.nifti <- function(x)
+{
+ is(x,"nifti")
+}
+
+"[.nifti" <- function(x,
+ dim1=1:nifti.image.getdim.save(x,1),
+ dim2=1:nifti.image.getdim.save(x,2),
+ dim3=1:nifti.image.getdim.save(x,3),
+ dim4=1:nifti.image.getdim.save(x,4),
+ dim5=1:nifti.image.getdim.save(x,5),
+ dim6=1:nifti.image.getdim.save(x,6),
+ dim7=1:nifti.image.getdim.save(x,7))
+{
+ .Call("Rnifti_image_getpixel", x, dim1-1, dim2-1, dim3-1, dim4-1, dim5-1, dim6-1, dim7-1,
+ PACKAGE="Rniftilib")
+}
+
+"[<-.nifti" <- function(x,
+ dim1=1:nifti.image.getdim.save(x,1),
+ dim2=1:nifti.image.getdim.save(x,2),
+ dim3=1:nifti.image.getdim.save(x,3),
+ dim4=1:nifti.image.getdim.save(x,4),
+ dim5=1:nifti.image.getdim.save(x,5),
+ dim6=1:nifti.image.getdim.save(x,6),
+ dim7=1:nifti.image.getdim.save(x,7),
+ value)
+{
+ .Call("Rnifti_image_setpixel", x, dim1-1, dim2-1, dim3-1, dim4-1, dim5-1, dim6-1, dim7-1, value,
+ PACKAGE="Rniftilib")
+}
+
+"$.nifti" <- function(x, sym)
+{
+ .Call("Rnifti_image_getattribute", x, sym, PACKAGE="Rniftilib")
+}
+
+"$<-.nifti" <- function(x, sym, value)
+{
+ .Call("Rnifti_image_setattribute", x, sym, value, PACKAGE="Rniftilib")
+}
+
+nifti.image.setdatatype <- function(nim, value)
+{
+ .Call("Rnifti_image_setdatatype", nim, value, PACKAGE="Rniftilib")
+}
+
+# EXPERIMENTAL function
+nifti.read.subregion.image <- function(nim, start_index, region_size)
+{
+ .Call("Rnifti_read_subregion_image", nim, start_index, region_size, PACKAGE="Rniftilib")
+}
+
+nifti.interpolate3d <- function(nim, x, y, z, t=1)
+{
+ iX <- floor(x)
+ iY <- floor(y)
+ iZ <- floor(z)
+ coex <- x-iX
+ coey <- y-iY
+ coez <- z-iZ
+
+ if (iX <=0 || iY <= 0 || iZ <= 0
+ || iX+1 > nifti.image.getdim.save(nim,1)
+ || iY+1 > nifti.image.getdim.save(nim,2)
+ || iZ+1 > nifti.image.getdim.save(nim,3))
+ return(0)
+
+ p1 <- (1-coex)*(1-coey)*(1-coez)*nim[iX,iY,iZ,t]
+ p2 <- (1-coex)*(1-coey)*( coez)*nim[iX,iY,iZ+1,t]
+ p3 <- (1-coex)*( coey)*(1-coez)*nim[iX,iY+1,iZ,t]
+ p4 <- (1-coex)*( coey)*( coez)*nim[iX,iY+1,iZ+1,t]
+ p5 <- ( coex)*(1-coey)*(1-coez)*nim[iX+1,iY,iZ,t]
+ p6 <- ( coex)*(1-coey)*( coez)*nim[iX+1,iY,iZ+1,t]
+ p7 <- ( coex)*( coey)*(1-coez)*nim[iX+1,iY+1,iZ,t]
+ p8 <- ( coex)*( coey)*( coez)*nim[iX+1,iY+1,iZ+1,t]
+ return(p1+p2+p3+p4+p5+p6+p7+p8)
+}
+
+# generic functions to integrate the nifti methods into R environment
+plot.nifti <- function(x,
+ dim1=1:nifti.image.getdim.save(x,1),
+ dim2=1:nifti.image.getdim.save(x,2),
+ dim3=1,
+ dim4=1,...)
+{
+ image(dim1,dim2,x[dim1,dim2,dim3,dim4],col=gray(1:255/255),...)
+}
+
+print.nifti <- function(x, ...)
+{
+ .Call("Rnifti_image_printinfo", x, PACKAGE="Rniftilib")
+}
+
+"dim.nifti" <- function(x)
+{
+ .Call("Rnifti_image_getattribute", x, "dim", PACKAGE="Rniftilib")
+}
+
+"dim<-.nifti" <- function(x, value)
+{
+ .Call("Rnifti_image_setattribute", x, "dim", value, PACKAGE="Rniftilib")
+}
+
+nifti.compiled.with.zlib <- function()
+{
+ .Call("Rnifti_compiled_with_zlib", PACKAGE="Rniftilib")
+}
+
+nifti.disp.lib.version <- function()
+{
+ .Call("Rnifti_disp_lib_version", PACKAGE="Rniftilib")
+}
+
+nifti.units.string <- function(value)
+{
+ .Call("Rnifti_units_string", value, PACKAGE="Rniftilib")
+}
+
+nifti.datatype.string <- function(value)
+{
+ .Call("Rnifti_datatype_string", value, PACKAGE="Rniftilib")
+}
+
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..24e6a83
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,14 @@
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_include([ax_check_zlib.m4])
diff --git a/ax_check_zlib.m4 b/ax_check_zlib.m4
new file mode 100644
index 0000000..8ba2f5d
--- /dev/null
+++ b/ax_check_zlib.m4
@@ -0,0 +1,124 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_zlib.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_ZLIB()
+#
+# DESCRIPTION
+#
+# This macro searches for an installed zlib library. If nothing was
+# specified when calling configure, it searches first in /usr/local and
+# then in /usr. If the --with-zlib=DIR is specified, it will try to find
+# it in DIR/include/zlib.h and DIR/lib/libz.a. If --without-zlib is
+# specified, the library is not searched at all.
+#
+# If either the header file (zlib.h) or the library (libz) is not found,
+# the configuration exits on error, asking for a valid zlib installation
+# directory or --without-zlib.
+#
+# The macro defines the symbol HAVE_LIBZ if the library is found. You
+# should use autoheader to include a definition for this symbol in a
+# config.h file. Sample usage in a C/C++ source is as follows:
+#
+# #ifdef HAVE_LIBZ
+# #include <zlib.h>
+# #endif /* HAVE_LIBZ */
+#
+# LICENSE
+#
+# Copyright (c) 2008 Loic Dachary <loic at senga.org>
+#
+# 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 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 7
+
+AU_ALIAS([CHECK_ZLIB], [AX_CHECK_ZLIB])
+AC_DEFUN([AX_CHECK_ZLIB],
+#
+# Handle user hints
+#
+[AC_MSG_CHECKING(if zlib is wanted)
+AC_ARG_WITH(zlib,
+[ --with-zlib=DIR root directory path of zlib installation [defaults to
+ /usr/local or /usr if not found in /usr/local]
+ --without-zlib to disable zlib usage completely],
+[if test "$withval" != no ; then
+ AC_MSG_RESULT(yes)
+ if test -d "$withval"
+ then
+ ZLIB_HOME="$withval"
+ else
+ AC_MSG_WARN([Sorry, $withval does not exist, checking usual places])
+ fi
+else
+ AC_MSG_RESULT(no)
+fi],
+[AC_MSG_RESULT(yes)])
+
+ZLIB_HOME=/usr/local
+if test ! -f "${ZLIB_HOME}/include/zlib.h"
+then
+ ZLIB_HOME=/usr
+fi
+
+#
+# Locate zlib, if wanted
+#
+if test -n "${ZLIB_HOME}"
+then
+ ZLIB_OLD_LDFLAGS=$LDFLAGS
+ ZLIB_OLD_CPPFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib"
+ CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include"
+ AC_LANG_SAVE
+ AC_LANG_C
+ AC_CHECK_LIB(z, inflateEnd, [zlib_cv_libz=yes], [zlib_cv_libz=no])
+ AC_CHECK_HEADER(zlib.h, [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no])
+ AC_LANG_RESTORE
+ if test "$zlib_cv_libz" = "yes" -a "$zlib_cv_zlib_h" = "yes"
+ then
+ #
+ # If both library and header were found, use them
+ #
+ AC_CHECK_LIB(z, inflateEnd)
+ AC_MSG_CHECKING(zlib in ${ZLIB_HOME})
+ AC_MSG_RESULT(ok)
+ else
+ #
+ # If either header or library was not found, revert and bomb
+ #
+ AC_MSG_CHECKING(zlib in ${ZLIB_HOME})
+ LDFLAGS="$ZLIB_OLD_LDFLAGS"
+ CPPFLAGS="$ZLIB_OLD_CPPFLAGS"
+ AC_MSG_RESULT(failed)
+ AC_MSG_ERROR(either specify a valid zlib installation with --with-zlib=DIR or disable zlib usage with --without-zlib)
+ fi
+fi
+
+])
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..f76e3b8
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,62 @@
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `z' library (-lz). */
+#undef HAVE_LIBZ
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+ to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
diff --git a/configure b/configure
new file mode 100755
index 0000000..fe54a7d
--- /dev/null
+++ b/configure
@@ -0,0 +1,5655 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.63 for Rniftilib configuration script 0.0.30.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+ if (eval ":") 2>/dev/null; then
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+
+ if test $as_have_required = yes && (eval ":
+(as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=\$LINENO
+ as_lineno_2=\$LINENO
+ test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+ test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+ :
+else
+ as_candidate_shells=
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ case $as_dir in
+ /*)
+ for as_base in sh bash ksh sh5; do
+ as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+ done;;
+ esac
+done
+IFS=$as_save_IFS
+
+
+ for as_shell in $as_candidate_shells $SHELL; do
+ # Try only shells that exist, to save several forks.
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { ("$as_shell") 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+_ASEOF
+}; then
+ CONFIG_SHELL=$as_shell
+ as_have_required=yes
+ if { "$as_shell" 2> /dev/null <<\_ASEOF
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+:
+(as_func_return () {
+ (exit $1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+ break
+fi
+
+fi
+
+ done
+
+ if test "x$CONFIG_SHELL" != x; then
+ for as_var in BASH_ENV ENV
+ do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+ done
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+ if test $as_have_required = no; then
+ echo This script requires a shell more modern than all the
+ echo shells that I found on your system. Please install a
+ echo modern shell, or manually run the script under such a
+ echo shell if you do have one.
+ { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+ (exit \$1)
+}
+as_func_success () {
+ as_func_return 0
+}
+as_func_failure () {
+ as_func_return 1
+}
+as_func_ret_success () {
+ return 0
+}
+as_func_ret_failure () {
+ return 1
+}
+
+exitcode=0
+if as_func_success; then
+ :
+else
+ exitcode=1
+ echo as_func_success failed.
+fi
+
+if as_func_failure; then
+ exitcode=1
+ echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+ :
+else
+ exitcode=1
+ echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+ exitcode=1
+ echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+ :
+else
+ exitcode=1
+ echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+ echo No shell found that supports shell functions.
+ echo Please tell bug-autoconf at gnu.org about your system,
+ echo including any error possibly output before this message.
+ echo This can help us improve future autoconf versions.
+ echo Configuration will now proceed without shell functions.
+}
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME='Rniftilib configuration script'
+PACKAGE_TARNAME='rniftilib-configuration-script'
+PACKAGE_VERSION='0.0.30'
+PACKAGE_STRING='Rniftilib configuration script 0.0.30'
+PACKAGE_BUGREPORT=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+INCLUDE
+LIBOBJS
+EGREP
+GREP
+CPP
+ac_ct_CC
+CFLAGS
+CC
+OBJEXT
+EXEEXT
+ac_ct_CXX
+CPPFLAGS
+LDFLAGS
+CXXFLAGS
+CXX
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_zlib
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CXX
+CXXFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CCC
+CC
+CFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2
+ { (exit 1); exit 1; }; }
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) { $as_echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { $as_echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2
+ { (exit 1); exit 1; }; } ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ { $as_echo "$as_me: error: working directory cannot be determined" >&2
+ { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ { $as_echo "$as_me: error: pwd does not report name of working directory" >&2
+ { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2
+ { (exit 1); exit 1; }; }
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures Rniftilib configuration script 0.0.30 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root
+ [DATAROOTDIR/doc/rniftilib-configuration-script]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of Rniftilib configuration script 0.0.30:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-zlib=DIR root directory path of zlib installation defaults to
+ /usr/local or /usr if not found in /usr/local
+ --without-zlib to disable zlib usage completely
+
+Some influential environment variables:
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CC C compiler command
+ CFLAGS C compiler flags
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+Rniftilib configuration script configure 0.0.30
+generated by GNU Autoconf 2.63
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Rniftilib configuration script $as_me 0.0.30, which was
+generated by GNU Autoconf 2.63. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+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 || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args '$ac_arg'"
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test -r "$ac_site_file"; then
+ { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+: ${R_HOME=`R RHOME`}
+if test -z "${R_HOME}"; then
+ echo "could not determine R_HOME"
+ exit 1
+fi
+CC=`"${R_HOME}/bin/R" CMD config CC`
+CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS`
+CPPFLAGS=`"${R_HOME}/bin/R" CMD config CPPFLAGS`
+
+# Checks for programs.
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5
+$as_echo_n "checking for C++ compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+
+{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: C++ compiler cannot create executables
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: C++ compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5
+$as_echo_n "checking whether the C++ compiler works... " >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CXXFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cxx_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:$LINENO: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:$LINENO: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler --version >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -v >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compiler -V >&5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_compiler_gnu=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ CFLAGS=""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_g=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_prog_cc_c89=$ac_arg
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:$LINENO: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:$LINENO: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Checks for header files.
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:$LINENO: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ :
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ # Broken: success on invalid input.
+continue
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:$LINENO: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ ac_count=`expr $ac_count + 1`
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_header_stdc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_stdc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -rf conftest.dSYM
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+# Checks for libraries.
+
+# Checks for typedefs, structures, and compiler characteristics.
+{ $as_echo "$as_me:$LINENO: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if test "${ac_cv_c_inline+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_c_inline=$ac_kw
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+
+# Checks for library functions.
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ eval "$as_ac_Header=yes"
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+as_val=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in stdlib.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ $as_echo_n "(cached) " >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+as_val=`eval 'as_val=${'$as_ac_Header'}
+ $as_echo "$as_val"'`
+ if test "x$as_val" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5
+$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
+if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_malloc_0_nonnull=no
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *malloc ();
+#endif
+
+int
+main ()
+{
+return ! malloc (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_malloc_0_nonnull=yes
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_malloc_0_nonnull=no
+fi
+rm -rf conftest.dSYM
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5
+$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
+if test $ac_cv_func_malloc_0_nonnull = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MALLOC 1
+_ACEOF
+
+else
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_MALLOC 0
+_ACEOF
+
+ case " $LIBOBJS " in
+ *" malloc.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
+ ;;
+esac
+
+
+cat >>confdefs.h <<\_ACEOF
+#define malloc rpl_malloc
+_ACEOF
+
+fi
+
+
+
+
+#
+# Handle user hints
+#
+{ $as_echo "$as_me:$LINENO: checking if zlib is wanted" >&5
+$as_echo_n "checking if zlib is wanted... " >&6; }
+
+# Check whether --with-zlib was given.
+if test "${with_zlib+set}" = set; then
+ withval=$with_zlib; if test "$withval" != no ; then
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ if test -d "$withval"
+ then
+ ZLIB_HOME="$withval"
+ else
+ { $as_echo "$as_me:$LINENO: WARNING: Sorry, $withval does not exist, checking usual places" >&5
+$as_echo "$as_me: WARNING: Sorry, $withval does not exist, checking usual places" >&2;}
+ fi
+else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+else
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+
+
+ZLIB_HOME=/usr/local
+if test ! -f "${ZLIB_HOME}/include/zlib.h"
+then
+ ZLIB_HOME=/usr
+fi
+
+#
+# Locate zlib, if wanted
+#
+if test -n "${ZLIB_HOME}"
+then
+ ZLIB_OLD_LDFLAGS=$LDFLAGS
+ ZLIB_OLD_CPPFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib"
+ CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ { $as_echo "$as_me:$LINENO: checking for inflateEnd in -lz" >&5
+$as_echo_n "checking for inflateEnd in -lz... " >&6; }
+if test "${ac_cv_lib_z_inflateEnd+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inflateEnd ();
+int
+main ()
+{
+return inflateEnd ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_z_inflateEnd=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_z_inflateEnd=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_z_inflateEnd" >&5
+$as_echo "$ac_cv_lib_z_inflateEnd" >&6; }
+if test "x$ac_cv_lib_z_inflateEnd" = x""yes; then
+ zlib_cv_libz=yes
+else
+ zlib_cv_libz=no
+fi
+
+ if test "${ac_cv_header_zlib_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for zlib.h" >&5
+$as_echo_n "checking for zlib.h... " >&6; }
+if test "${ac_cv_header_zlib_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
+$as_echo "$ac_cv_header_zlib_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking zlib.h usability" >&5
+$as_echo_n "checking zlib.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <zlib.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking zlib.h presence" >&5
+$as_echo_n "checking zlib.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <zlib.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: zlib.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: zlib.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: zlib.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: zlib.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: zlib.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: zlib.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: zlib.h: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for zlib.h" >&5
+$as_echo_n "checking for zlib.h... " >&6; }
+if test "${ac_cv_header_zlib_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_zlib_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
+$as_echo "$ac_cv_header_zlib_h" >&6; }
+
+fi
+if test "x$ac_cv_header_zlib_h" = x""yes; then
+ zlib_cv_zlib_h=yes
+else
+ zlib_cv_zlib_h=no
+fi
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ if test "$zlib_cv_libz" = "yes" -a "$zlib_cv_zlib_h" = "yes"
+ then
+ #
+ # If both library and header were found, use them
+ #
+
+{ $as_echo "$as_me:$LINENO: checking for inflateEnd in -lz" >&5
+$as_echo_n "checking for inflateEnd in -lz... " >&6; }
+if test "${ac_cv_lib_z_inflateEnd+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inflateEnd ();
+int
+main ()
+{
+return inflateEnd ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_lib_z_inflateEnd=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_z_inflateEnd=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_z_inflateEnd" >&5
+$as_echo "$ac_cv_lib_z_inflateEnd" >&6; }
+if test "x$ac_cv_lib_z_inflateEnd" = x""yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+ LIBS="-lz $LIBS"
+
+fi
+
+ { $as_echo "$as_me:$LINENO: checking zlib in ${ZLIB_HOME}" >&5
+$as_echo_n "checking zlib in ${ZLIB_HOME}... " >&6; }
+ { $as_echo "$as_me:$LINENO: result: ok" >&5
+$as_echo "ok" >&6; }
+ else
+ #
+ # If either header or library was not found, revert and bomb
+ #
+ { $as_echo "$as_me:$LINENO: checking zlib in ${ZLIB_HOME}" >&5
+$as_echo_n "checking zlib in ${ZLIB_HOME}... " >&6; }
+ LDFLAGS="$ZLIB_OLD_LDFLAGS"
+ CPPFLAGS="$ZLIB_OLD_CPPFLAGS"
+ { $as_echo "$as_me:$LINENO: result: failed" >&5
+$as_echo "failed" >&6; }
+ { { $as_echo "$as_me:$LINENO: error: either specify a valid zlib installation with --with-zlib=DIR or disable zlib usage with --without-zlib" >&5
+$as_echo "$as_me: error: either specify a valid zlib installation with --with-zlib=DIR or disable zlib usage with --without-zlib" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
+
+
+
+
+ac_config_files="$ac_config_files src/Makevars"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) $as_unset $ac_var ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in
+ *posix*) set -o posix ;;
+esac
+
+fi
+
+
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line after each line using $LINENO; the second 'sed'
+ # does the real work. The second script uses 'N' to pair each
+ # line-number line with the line containing $LINENO, and appends
+ # trailing '-' during substitution so that $LINENO is not a special
+ # case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # scripts with optimization help from Paolo Bonzini. Blame Lee
+ # E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+ case `echo 'x\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ *) ECHO_C='\c';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by Rniftilib configuration script $as_me 0.0.30, which was
+generated by GNU Autoconf 2.63. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTION]... [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf at gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+Rniftilib configuration script config.status 0.0.30
+configured by $0, generated by GNU Autoconf 2.63,
+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_FILES="$CONFIG_FILES '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ { $as_echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { $as_echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "src/Makevars") CONFIG_FILES="$CONFIG_FILES src/Makevars" ;;
+
+ *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} ||
+{
+ $as_echo "$as_me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr='
'
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5
+$as_echo "$as_me: error: could not setup config files machinery" >&2;}
+ { (exit 1); exit 1; }; }
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_t"; then
+ break
+ elif $ac_last_try; then
+ { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5
+$as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5
+$as_echo "$as_me: error: could not setup config headers machinery" >&2;}
+ { (exit 1); exit 1; }; }
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5
+$as_echo "$as_me: error: invalid tag $ac_tag" >&2;}
+ { (exit 1); exit 1; }; };;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ ac_file_inputs="$ac_file_inputs '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:$LINENO: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ { as_dir="$ac_dir"
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+$as_echo "$as_me: error: cannot create directory $as_dir" >&2;}
+ { (exit 1); exit 1; }; }; }
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+ } >"$tmp/config.h" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$tmp/config.h" "$ac_file" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5
+$as_echo "$as_me: error: could not create $ac_file" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5
+$as_echo "$as_me: error: could not create -" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ ;;
+
+
+ esac
+
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;}
+ { (exit 1); exit 1; }; }
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/debian/README.test b/debian/README.test
deleted file mode 100644
index f994348..0000000
--- a/debian/README.test
+++ /dev/null
@@ -1,7 +0,0 @@
-r-cran-niftilib for Debian
---------------------------
-
-This package can be tested by loading it into R with the command
-'library(Rniftilib)' in order to confirm its integrity.
-
- -- Andreas Tille <tille at debian.org> Wed, 24 Jul 2013 08:14:10 +0200
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index 9ceb995..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,5 +0,0 @@
-r-cran-rniftilib (0.0-32-1) unstable; urgency=low
-
- * Initial release (closes: #717715)
-
- -- Andreas Tille <tille at debian.org> Wed, 24 Jul 2013 08:14:10 +0200
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index ec63514..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/debian/control b/debian/control
deleted file mode 100644
index d60f881..0000000
--- a/debian/control
+++ /dev/null
@@ -1,19 +0,0 @@
-Source: r-cran-rniftilib
-Section: gnu-r
-Priority: optional
-Maintainer: Debian Med Packaging Team <debian-med-packaging at lists.alioth.debian.org>
-Uploaders: Andreas Tille <tille at debian.org>
-Build-Depends: debhelper (>= 9), r-base-dev, cdbs
-Standards-Version: 3.9.4
-Homepage: http://cran.r-project.org/web/packages/Rniftilib
-Vcs-Browser: http://anonscm.debian.org/viewvc/debian-med/trunk/packages/R/r-cran-rniftilib/trunk/
-Vcs-Svn: svn://anonscm.debian.org/debian-med/trunk/packages/R/r-cran-rniftilib/trunk/
-
-Package: r-cran-rniftilib
-Architecture: any
-Depends: ${shlibs:Depends},
- ${misc:Depends},
- ${R:Depends}
-Description: GNU/R interface to NIFTICLIB
- R interface to nifticlib (nifticlib-2.0.0) (read/write
- ANALYZE(TM)7.5/NIfTI-1 volume images)
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index 2cd903b..0000000
--- a/debian/copyright
+++ /dev/null
@@ -1,28 +0,0 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: Rniftilib
-Source: http://cran.r-project.org/src/contrib/
-
-Files: *
-Copyright: 2011-2013 Oliver Granert <o.granert at neurologie.uni-kiel.de>
-License: GPL-2.0+
-
-Files: debian/*
-Copyright: 2013 Andreas Tille <tille at debian.org>
-License: GPL-2.0+
-
-License: GPL-2.0+
- This package 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 package 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, see <http://www.gnu.org/licenses/>
- .
- On Debian systems, the complete text of the GNU General
- Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index f1e58a0..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile -*-
-
-### unfortunately this does not enable hardening
-# export DEB_BUILD_MAINT_OPTIONS = hardening=+all
-# DPKG_EXPORT_BUILDFLAGS = 1
-# include /usr/share/dpkg/buildflags.mk
-
-include /usr/share/R/debian/r-cran.mk
-
-get-orig-source:
- mkdir -p ../tarballs
- uscan --verbose --force-download --destdir=../tarballs
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index ad73784..0000000
--- a/debian/watch
+++ /dev/null
@@ -1,2 +0,0 @@
-version=3
-http://cran.r-project.org/src/contrib/Rniftilib_([\d.-]*)\.tar\.gz
diff --git a/man/nifti.Rd b/man/nifti.Rd
new file mode 100644
index 0000000..43c43de
--- /dev/null
+++ b/man/nifti.Rd
@@ -0,0 +1,126 @@
+\name{nifti}
+\alias{nifti}
+\alias{[.nifti}
+\alias{dim.nifti}
+\alias{dim<-.nifti}
+\alias{$.nifti}
+\alias{print.nifti}
+\alias{plot.nifti}
+\alias{[<-.nifti}
+\alias{$<-.nifti}
+\alias{is.nifti}
+\alias{nifti.image.getdim.save}
+\title{NIfTI object}
+\description{
+ A NIfTI object contains the image description and data of an image
+ volume.
+ Voxels can be accessed by the bracket [dim1,dim2,dim3,...,dim7] operator.
+}
+\usage{
+ \method{[}{nifti}(x,
+ dim1=1:nifti.image.getdim.save(x,1),
+ dim2=1:nifti.image.getdim.save(x,2),
+ dim3=1:nifti.image.getdim.save(x,3),
+ dim4=1:nifti.image.getdim.save(x,4),
+ dim5=1:nifti.image.getdim.save(x,5),
+ dim6=1:nifti.image.getdim.save(x,6),
+ dim7=1:nifti.image.getdim.save(x,7))
+ \method{$}{nifti}(x, sym)
+ \method{dim}{nifti}(x)
+ \method{print}{nifti}(x,...)
+ \method{plot}{nifti}(x, dim1=1:nifti.image.getdim.save(x,1), dim2=1:nifti.image.getdim.save(x,2),dim3=1, dim4=1,...)
+ is.nifti(x)
+}
+\arguments{
+ \item{x}{NIfTI image object (class nifti)}
+ \item{sym}{ \tabular{rl}{
+ \code{qto.xyz}\tab voxel to mm transformation (R style indexing!)\cr
+ \code{qto.ijk}\tab mm to voxel transformation (R style indexing!)\cr
+ \code{sto.xyz}\tab voxel to mm transformation (R style indexing!)\cr
+ \code{sto.ijk}\tab mm to voxel transformation (R style indexing!)\cr
+ \code{qto_xyz}\tab voxel to mm transformation (C style indexing!)\cr
+ \code{qto_ijk}\tab mm to voxel transformation (C style indexing!)\cr
+ \code{sto_xyz}\tab voxel to mm transformation (C style indexing!)\cr
+ \code{sto_ijk}\tab mm to voxel transformation (C style indexing!)\cr
+ \code{toffset}\tab \cr
+ \code{descrip}\tab description (up to 80 characters)\cr
+ \code{fname}\tab header filename (store image information)\cr
+ \code{iname}\tab image filename (store image data)\cr
+ \code{slice.duration}\tab time for 1 slice\cr
+ \code{qform.code}\tab \code{NIFTI.XFORM.UNKNOWN} (0) \cr
+ \tab \code{NIFTI.XFORM.SCANNER.ANAT} (1) \cr
+ \tab \code{NIFTI.XFORM.ALIGNED.ANAT} (2) \cr
+ \tab \code{NIFTI.XFORM.TALAIRACH} (3) \cr
+ \tab \code{NIFTI.XFORM.MNI.152} (4)\cr
+ \tab \code{qform code: >No<} for unknown tags \cr
+ \code{sform.code}\tab \code{NIFTI.XFORM.UNKNOWN} (0) \cr
+ \tab \code{NIFTI.XFORM.SCANNER.ANAT} (1)\cr
+ \tab \code{NIFTI.XFORM.ALIGNED.ANAT} (2)\cr
+ \tab \code{NIFTI.XFORM.TALAIRACH} (3) \cr
+ \tab \code{NIFTI.XFORM.MNI.152} (4) \cr
+ \tab \code{sform code: >No<} for unknown tags \cr
+ \code{quatern.b}\tab \cr
+ \code{quatern.c}\tab \cr
+ \code{quatern.d}\tab \cr
+ \code{qoffset.x}\tab \cr
+ \code{qoffset.y}\tab \cr
+ \code{qoffset.z}\tab \cr
+ \code{qfac}\tab \cr
+ \code{dim}\tab image volume size in voxel \cr
+ \code{pixdim}\tab grid spacings. \cr
+ \code{datatype}\tab data type (set also field \code{nbyper})\cr
+ \code{nbyper}\tab bytes per voxel, matches datatype (read only) \cr
+ \code{nifti.type}\tab \code{NIFTI.FTYPE.ANALYZE} (0) : .hdr + .img files \cr
+ \tab \code{NIFTI.FTYPE.NIFTI1.1}(1) : .nii file \cr
+ \tab \code{NIFTI.FTYPE.NIFTI1.2} (2) : .hdr + .img files \cr
+ \tab \code{NIFTI.FTYPE.ASCII} (3) : ? \cr
+ \code{sizeof_hdr}\tab MUST be 348\cr
+ \code{scl.slope} \tab nifti1: Data scaling: slope. analyze 7.5: float funused1 \cr
+ \code{scl.inter} \tab nifti1: Data scaling: offset. analyze 7.5: float funused2 \cr
+ \code{xyz_units} \tab \code{NIFTI_UNITS_UNKNOWN} "" (0) \cr
+ \tab \code{NIFTI_UNITS_METER} "m" (1) \cr
+ \tab \code{NIFTI_UNITS_MM} "mm" (2) \cr
+ \tab \code{NIFTI_UNITS_MICRON} "um" (3) \cr
+ \tab \code{NIFTI_UNITS_SEC} "s" (8) \cr
+ \tab \code{NIFTI_UNITS_MSEC} "ms" (16) \cr
+ \tab \code{NIFTI_UNITS_USEC} "us" (24) \cr
+ \tab \code{NIFTI_UNITS_HZ} "Hz" (32) \cr
+ \tab \code{NIFTI_UNITS_PPM} "ppm" (40) \cr
+ \tab \code{NIFTI_UNITS_RADS} "rad/s" (48) \cr
+ \tab see also \code{\link{nifti.units.string}}\cr
+ \code{time_units}\tab \code{NIFTI_UNITS_UNKNOWN} "" (0) \cr
+ \tab \code{NIFTI_UNITS_METER} "m" (1) \cr
+ \tab \code{NIFTI_UNITS_MM} "mm" (2) \cr
+ \tab \code{NIFTI_UNITS_MICRON} "um" (3) \cr
+ \tab \code{NIFTI_UNITS_SEC} "s" (8) \cr
+ \tab \code{NIFTI_UNITS_MSEC} "ms" (16) \cr
+ \tab \code{NIFTI_UNITS_USEC} "us" (24) \cr
+ \tab \code{NIFTI_UNITS_HZ} "Hz" (32) \cr
+ \tab \code{NIFTI_UNITS_PPM} "ppm" (40) \cr
+ \tab \code{NIFTI_UNITS_RADS} "rad/s" (48) \cr
+ \tab see also \code{\link{nifti.units.string}}
+ }}
+ \item{dim1}{vector of voxel indices (x)}
+ \item{dim2}{vector of voxel indices (y)}
+ \item{dim3}{vector of voxel indices (z)}
+ \item{dim4}{vector of voxel indices (t)}
+ \item{dim5}{vector of voxel indices}
+ \item{dim6}{vector of voxel indices}
+ \item{dim7}{vector of voxel indices}
+ \item{...}{additional arguments for plotting (e.g. \code{\link{image}}) and printing}
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+\author{
+ Oliver Granert <o.granert <at> neurologie.uni-kiel.de>
+}
+\seealso{
+ \code{\link{nifti.image.read}},
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.new}}
+}
+\keyword{package}
+\keyword{data}
+\keyword{manip}
diff --git a/man/nifti_compiled_with_zlib.Rd b/man/nifti_compiled_with_zlib.Rd
new file mode 100644
index 0000000..0ca2da7
--- /dev/null
+++ b/man/nifti_compiled_with_zlib.Rd
@@ -0,0 +1,28 @@
+\name{nifti.compiled.with.zlib}
+\alias{nifti.compiled.with.zlib}
+\title{Check support for compressed NIfTI files.}
+\description{
+Return whether the given Rniftilib C-library was compiled with \code{HAVE_ZLIB} set.
+}
+\usage{
+nifti.compiled.with.zlib()
+}
+\value{
+ \item{TRUE}{library supports compressed files (.gz)}
+ \item{FALSE}{compressed files are not supported}
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+\seealso{
+ \code{\link{nifti.image.new}},
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.read}}
+}
+
+\examples{
+nifti.compiled.with.zlib() # return logical value (TRUE or FALSE)
+}
+\keyword{manip}
+\keyword{data}
\ No newline at end of file
diff --git a/man/nifti_datatype_string.Rd b/man/nifti_datatype_string.Rd
new file mode 100644
index 0000000..f31f8d0
--- /dev/null
+++ b/man/nifti_datatype_string.Rd
@@ -0,0 +1,31 @@
+\name{nifti.datatype.string}
+\alias{nifti.datatype.string}
+\title{Return string for NIfTI-1 datatype code value.}
+\description{
+Return a string for the datatype of a NIFTI data type.
+}
+\usage{
+nifti.datatype.string(value)
+}
+\arguments{
+ \item{value}{NIfTI-1 datatype}
+}
+\details{
+Return a string for the datatype of a NIFTI data type (e.g. "INT8" signed integer data type).
+}
+\value{
+String for the given data type value.
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+
+\seealso{
+ \code{\link{nifti.units.string}},
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.read}}
+}
+
+\keyword{manip}
+\keyword{data}
diff --git a/man/nifti_disp_lib_version.Rd b/man/nifti_disp_lib_version.Rd
new file mode 100644
index 0000000..1951972
--- /dev/null
+++ b/man/nifti_disp_lib_version.Rd
@@ -0,0 +1,24 @@
+\name{nifti.disp.lib.version}
+\alias{nifti.disp.lib.version}
+\title{NIfTI library version.}
+\description{
+Return NIfTI library version and date as a character string.
+}
+\usage{
+nifti.disp.lib.version()
+}
+\value{
+ String containing library version and compilation date.
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+\seealso{
+ \code{\link{nifti.image.new}},
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.read}}
+}
+\keyword{manip}
+\keyword{data}
+
diff --git a/man/nifti_image_alloc_data.Rd b/man/nifti_image_alloc_data.Rd
new file mode 100644
index 0000000..d995a10
--- /dev/null
+++ b/man/nifti_image_alloc_data.Rd
@@ -0,0 +1,35 @@
+\name{nifti.image.alloc.data}
+\alias{nifti.image.alloc.data}
+\title{Allocate data block for NIfTI image}
+\description{
+Allocate data block for NIfTI image using the information from the header.
+}
+\usage{
+nifti.image.alloc.data(nim)
+}
+\arguments{
+ \item{nim}{the nifti object}
+}
+\details{
+ The function return the number of bytes allocated.
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+\author{
+ Oliver Granert <o.granert <at> neurologie.uni-kiel.de>
+}
+
+\seealso{
+ \code{\link{nifti.image.new}},
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.read}}
+}
+
+\examples{
+nim=nifti.image.new()
+no.of.bytes=nifti.image.alloc.data(nim)
+}
+\keyword{manip}
+\keyword{data}
diff --git a/man/nifti_image_copy_info.Rd b/man/nifti_image_copy_info.Rd
new file mode 100644
index 0000000..6d08cbf
--- /dev/null
+++ b/man/nifti_image_copy_info.Rd
@@ -0,0 +1,36 @@
+\name{nifti.image.copy.info}
+\alias{nifti.image.copy.info}
+\title{Copy NIFTI image (info) without voxel data.}
+\description{
+Copy the nifti.image structure, without data.
+
+Duplicate the structure, including fname, iname and extensions.
+Leave the data pointer as NULL.
+}
+\usage{
+nifti.image.copy.info(nim)
+}
+\arguments{
+ \item{nim}{the nifti object}
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+\author{
+ Oliver Granert <o.granert <at> neurologie.uni-kiel.de>
+}
+
+\seealso{
+ \code{\link{nifti.image.new}},
+ \code{\link{nifti.image.read}},
+ \code{\link{nifti.image.write}}
+}
+
+\examples{
+\dontrun{
+nim <- nifti.image.read(file.choose())
+nim_copy <- nifti.image.copy.info(nim)
+}
+}
+\keyword{manip}
diff --git a/man/nifti_image_free.Rd b/man/nifti_image_free.Rd
new file mode 100644
index 0000000..9636ec3
--- /dev/null
+++ b/man/nifti_image_free.Rd
@@ -0,0 +1,32 @@
+\name{nifti.image.free}
+\alias{nifti.image.free}
+\title{Free NIfTI image data structure}
+\description{
+Free image data (everything!).
+}
+\usage{
+nifti.image.free(nim)
+}
+\arguments{
+ \item{nim}{the nifti object}
+}
+\details{
+Free 'everything' about a nifti struct (including the passed struct):
+(fname and iname, data, extensions, nim)
+}
+\value{
+A \code{\link{nifti}} object
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+
+\seealso{
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.read}}
+ \code{\link{nifti.image.unload}}
+}
+
+\keyword{manip}
+\keyword{data}
\ No newline at end of file
diff --git a/man/nifti_image_new.Rd b/man/nifti_image_new.Rd
new file mode 100644
index 0000000..9b9cd5f
--- /dev/null
+++ b/man/nifti_image_new.Rd
@@ -0,0 +1,36 @@
+\name{nifti.image.new}
+\alias{nifti.image.new}
+\title{Create new NIfTI image}
+\description{
+ Basic initialization of a nifti.image structure (to a 1x1x1 image)
+}
+\usage{
+nifti.image.new()
+}
+\details{
+Creates an image of size 1x1x1.
+}
+\value{
+A \code{\link{nifti}} object
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+\author{
+ Oliver Granert <o.granert <at> neurologie.uni-kiel.de>
+}
+
+\seealso{
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.read}}
+}
+
+\examples{
+# create 1x1x1 nifti volume
+nim=nifti.image.new()
+# resize nifti volume to 15x15x15
+nim$dim<-c(15,15,15)
+}
+\keyword{manip}
+\keyword{data}
diff --git a/man/nifti_image_read.Rd b/man/nifti_image_read.Rd
new file mode 100644
index 0000000..9d0a6f6
--- /dev/null
+++ b/man/nifti_image_read.Rd
@@ -0,0 +1,50 @@
+\name{nifti.image.read}
+\alias{nifti.image.read}
+\title{Read data from NIfTI (Analyze) files}
+\description{
+ This function reads the meta and image data from a nifti file.
+}
+\usage{
+nifti.image.read(file, read_data=1, rm.NaN=TRUE)
+}
+\arguments{
+ \item{file}{name of the nifti file}
+ \item{read_data}{0=do not read image data, 1=read image data}
+ \item{rm.NaN}{logical value indicating whether NA and NaN values should be stripped (default in niftilib C library)}
+}
+\details{
+If \code{read_data=0} only the header info is loaded.
+}
+\value{
+\code{\link{nifti}} object
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+\author{
+ Oliver Granert <o.granert <at> neurologie.uni-kiel.de>
+}
+
+\seealso{
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.new}}
+}
+\examples{
+\dontrun{
+nim <- nifti.image.read(file.choose())
+# access to attributes...
+nim$qto.xyz # voxel to mm transformation matrix (q-form)
+nim$qto.ijk # mm to voxel transformation matrix (q-form)
+nim$sto.xyz # voxel to mm transformation matrix (s-form)
+nim$sto.ijk # mm to voxel transformation matrix (s-form)
+nim$toffset #
+nim$descrip # description
+nim$fname # header filename (store image information)
+nim$iname # image filename (store image data)
+nim$slice.duration
+# access to voxel values...
+nim[10,11,12] # voxel value at x=10, y=11, z=12
+}
+}
+\keyword{IO}
diff --git a/man/nifti_image_setdatatype.Rd b/man/nifti_image_setdatatype.Rd
new file mode 100644
index 0000000..a0035cf
--- /dev/null
+++ b/man/nifti_image_setdatatype.Rd
@@ -0,0 +1,69 @@
+\name{nifti.image.setdatatype}
+\alias{nifti.image.setdatatype}
+\title{Change data type of nifti object.}
+\description{
+Set \code{datatype} and \code{nbyper} fields.
+}
+\usage{
+nifti.image.setdatatype(nim, value)
+}
+\arguments{
+ \item{nim}{ nifti image object }
+ \item{value}{data type as string, e.g. "NIFTI_TYPE_UINT8", or numeric type id, e.g. 2. See details section for a list of possible values.}
+}
+\details{
+\tabular{rcl}{
+\bold{original ANALYZE 7.5 type codes} \tab \bold{numeric type id} \tab \bold{description} \cr
+\code{DT_NONE} \tab 0 \tab unknown/none data format\cr
+\code{DT_UNKNOWN} \tab 0 \tab unknown/none data format \cr
+\code{DT_BINARY} \tab 1 \tab binary (1 bit/voxel) \cr
+\code{DT_UNSIGNED_CHAR}\tab 2 \tab unsigned char (8 bits/voxel) \cr
+\code{DT_SIGNED_SHORT} \tab 4 \tab signed short (16 bits/voxel) \cr
+\code{DT_SIGNED_INT} \tab 8 \tab signed int (32 bits/voxel) \cr
+\code{DT_FLOAT} \tab 16 \tab float (32 bits/voxel) \cr
+\code{DT_COMPLEX} \tab 32 \tab complex (64 bits/voxel) \cr
+\code{DT_DOUBLE} \tab 64 \tab double (64 bits/voxel) \cr
+\code{DT_RGB} \tab 128 \tab RGB triple (24 bits/voxel) \cr
+\code{DT_ALL} \tab 255 \tab not very useful (?) \cr
+ \tab \tab \cr
+\code{DT_UINT8} \tab 2 \tab \cr
+\code{DT_INT16} \tab 4 \tab \cr
+\code{DT_INT32} \tab 8 \tab \cr
+\code{DT_FLOAT32} \tab 16 \tab \cr
+\code{DT_COMPLEX64} \tab 32 \tab \cr
+\code{DT_FLOAT64} \tab 64 \tab \cr
+\code{DT_RGB24} \tab 128 \tab \cr
+ \tab \tab \cr
+\code{DT_INT8} \tab 256 \tab signed char (8 bits) \cr
+\code{DT_UINT16} \tab 512 \tab unsigned short (16 bits) \cr
+\code{DT_UINT32} \tab 768 \tab unsigned int (32 bits) \cr
+\code{DT_INT64} \tab 1024 \tab long long (64 bits) \cr
+\code{DT_UINT64} \tab 1280 \tab unsigned long long (64 bits) \cr
+\code{DT_FLOAT128} \tab 1536 \tab long double (128 bits) \cr
+\code{DT_COMPLEX128} \tab 1792 \tab double pair (128 bits) \cr
+\code{DT_COMPLEX256} \tab 2048 \tab long double pair (256 bits) \cr
+\code{DT_RGBA32} \tab 2304 \tab 4 byte RGBA (32 bits/voxel) \cr
+\bold{new codes for NIFTI} \tab \tab \cr
+\code{NIFTI_TYPE_UINT8} \tab 2 \tab unsigned char \cr
+\code{NIFTI_TYPE_INT16} \tab 4 \tab signed short \cr
+\code{NIFTI_TYPE_INT32} \tab 8 \tab signed int \cr
+\code{NIFTI_TYPE_FLOAT32} \tab 16 \tab 32 bit float \cr
+\code{NIFTI_TYPE_COMPLEX64} \tab 32 \tab 64 bit complex = 2x32 bit floats \cr
+\code{NIFTI_TYPE_FLOAT64} \tab 64 \tab 64 bit float = double \cr
+\code{NIFTI_TYPE_RGB24} \tab 128 \tab 3x8 bit bytes \cr
+\code{NIFTI_TYPE_INT8} \tab 256 \tab signed char \cr
+\code{NIFTI_TYPE_UINT16} \tab 512 \tab unsigned short \cr
+\code{NIFTI_TYPE_UINT32} \tab 768 \tab unsigned int \cr
+\code{NIFTI_TYPE_INT64} \tab 1024 \tab signed long long \cr
+\code{NIFTI_TYPE_UINT64} \tab 1280 \tab unsigned long long. \cr
+\code{NIFTI_TYPE_FLOAT128} \tab 1536 \tab 128 bit float = long double \cr
+\code{NIFTI_TYPE_COMPLEX128} \tab 1792 \tab 128 bit complex = 2 64 bit floats \cr
+\code{NIFTI_TYPE_COMPLEX256} \tab 2048 \tab 256 bit complex = 2 128 bit floats \cr
+\code{NIFTI_TYPE_RGBA32} \tab 2304 \tab 4x8 bit bytes (32bits/voxel) \cr
+}}
+\seealso{
+ \code{\link{nifti.image.unload}},
+ \code{\link{nifti.image.alloc.data}}
+}
+
+\keyword{IO}
diff --git a/man/nifti_image_unload.Rd b/man/nifti_image_unload.Rd
new file mode 100644
index 0000000..5330064
--- /dev/null
+++ b/man/nifti_image_unload.Rd
@@ -0,0 +1,31 @@
+\name{nifti.image.unload}
+\alias{nifti.image.unload}
+\title{Unload NIfTI image data}
+\description{
+Unload the image data in nifti struct, but keep the metadata.
+}
+\usage{
+nifti.image.unload(nim)
+}
+\arguments{
+ \item{nim}{the nifti object}
+}
+\details{
+Unload image data, but keep header information and other metadata.
+}
+\value{
+A \code{\link{nifti}} object
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+
+\seealso{
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.read}}
+ \code{\link{nifti.image.free}}
+}
+
+\keyword{manip}
+\keyword{data}
\ No newline at end of file
diff --git a/man/nifti_image_write.Rd b/man/nifti_image_write.Rd
new file mode 100644
index 0000000..32df131
--- /dev/null
+++ b/man/nifti_image_write.Rd
@@ -0,0 +1,32 @@
+\name{nifti.image.write}
+\alias{nifti.image.write}
+\title{Write data to NIfTI (Analyze) files}
+\description{
+ This function writes volume data to a NIfTI file.
+}
+\usage{
+nifti.image.write(nim)
+}
+\arguments{
+ \item{nim}{the nifti object}
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+\author{
+ Oliver Granert <o.granert <at> neurologie.uni-kiel.de>
+}
+
+\seealso{
+ \code{\link{nifti.image.read}},
+ \code{\link{nifti.image.new}}
+}
+
+\examples{
+\dontrun{
+nim <- nifti.image.read(file.choose())
+nifti.image.write(nim)
+}
+}
+\keyword{IO}
diff --git a/man/nifti_interpolate3D.Rd b/man/nifti_interpolate3D.Rd
new file mode 100644
index 0000000..8ceed9a
--- /dev/null
+++ b/man/nifti_interpolate3D.Rd
@@ -0,0 +1,42 @@
+\name{nifti.interpolate3d}
+\alias{nifti.interpolate3d}
+\title{Interpolation between voxels}
+\description{
+ This function interpolates in 3d between voxels (in volume data).
+}
+\usage{
+nifti.interpolate3d(nim, x, y, z, t=1)
+}
+\arguments{
+ \item{nim}{the nifti object}
+ \item{x}{x coordinate (subpixel/floating point)}
+ \item{y}{y coordinate (subpixel/floating point)}
+ \item{z}{z coordinate (subpixel/floating point)}
+ \item{t}{t coordinate (subpixel/floating point)}
+}
+\references{
+\url{http://nifti.nimh.nih.gov}
+\url{http://niftilib.sourceforge.net}
+}
+\author{
+Oliver Granert <o.granert <at> neurologie.uni-kiel.de>
+}
+
+\seealso{
+ \code{\link{nifti.image.read}},
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.new}}
+}
+
+\examples{
+\dontrun{
+nim <- nifti.image.read(file.choose())
+plot(c(nifti.interpolate3d(nim,100,100,3),
+ nifti.interpolate3d(nim,100.25,100,3),
+ nifti.interpolate3d(nim,100.5,100,3),
+ nifti.interpolate3d(nim,100.75,100,3),
+ nifti.interpolate3d(nim,101,100,3)),
+ xlab="position x", ylab="interpolation")
+}
+}
+\keyword{utilities}
diff --git a/man/nifti_read_subregion_image.Rd b/man/nifti_read_subregion_image.Rd
new file mode 100644
index 0000000..e57e58a
--- /dev/null
+++ b/man/nifti_read_subregion_image.Rd
@@ -0,0 +1,43 @@
+\name{nifti.read.subregion.image}
+\alias{nifti.read.subregion.image}
+\title{Read a subregion from a NIfTI image}
+\description{
+EXPERIMENTAL (unstable interface!): Read a single arbitary subregion of any rectangular size from a NIfTI dataset.
+}
+\usage{
+nifti.read.subregion.image(nim, start_index, region_size)
+}
+\arguments{
+ \item{nim}{the nifti object}
+ \item{start_index}{start_index the index location of the first voxel that will be returned}
+ \item{region_size}{region_size the size of the subregion to be returned}
+}
+\details{
+ This function may be used to read a single arbitary subregion of any
+ rectangular size from a nifti dataset, such as a small 5x5x5 subregion
+ around the center of a 3D image.
+
+ Example: given nim$dim = c(64, 64, 64) (3-D dataset)
+
+ if start_index = c( 29, 29, 29) and
+ region_size = c( 5, 5, 5)
+ -> read 5x5x5 region starting with the first voxel location at (29,29,29)
+}
+\value{
+The subregion data in a vector.
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+\author{
+ Oliver Granert <o.granert <at> neurologie.uni-kiel.de>
+}
+
+\seealso{
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.read}}
+}
+
+\keyword{manip}
+\keyword{data}
diff --git a/man/nifti_set_filenames.Rd b/man/nifti_set_filenames.Rd
new file mode 100644
index 0000000..ffc27ae
--- /dev/null
+++ b/man/nifti_set_filenames.Rd
@@ -0,0 +1,38 @@
+\name{nifti.set.filenames}
+\alias{nifti.set.filenames}
+\title{Set filenames for a NIFTI image}
+\description{
+ Set filenames (image and header filename) for a NIfTI image.
+}
+\usage{
+nifti.set.filenames(nim, prefix, check=1, set_byte_order=1)
+}
+\arguments{
+ \item{nim}{the nifti object}
+ \item{prefix}{(required) prefix for output filenames}
+ \item{check}{check for previous existence of filename (existence is an
+ error condition)}
+ \item{set_byte_order}{flag to set nim->byteorder here (if
+ set\_byte\_order=1 then byteorder is set based on the CPU type)}
+}
+
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+\author{
+ Oliver Granert <o.granert <at> neurologie.uni-kiel.de>
+}
+\seealso{
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.read}},
+ \code{\link{nifti.image.new}}
+}
+\examples{
+nim <- nifti.image.new()
+nifti.set.filenames(nim, "testvolume")
+# show the result
+nim$fname
+nim$iname
+}
+\keyword{manip}
diff --git a/man/nifti_units_string.Rd b/man/nifti_units_string.Rd
new file mode 100644
index 0000000..0307dc4
--- /dev/null
+++ b/man/nifti_units_string.Rd
@@ -0,0 +1,31 @@
+\name{nifti.units.string}
+\alias{nifti.units.string}
+\title{Return string for NIfTI-1 unit code value.}
+\description{
+Return a string holding the name of a NIFTI units type.
+}
+\usage{
+nifti.units.string(value)
+}
+\arguments{
+ \item{value}{NIfTI-1 unit code}
+}
+\details{
+Return a string holding the name of a NIFTI units type.
+}
+\value{
+String for the given unit type value.
+}
+\references{
+ \url{http://nifti.nimh.nih.gov}
+ \url{http://niftilib.sourceforge.net}
+}
+
+\seealso{
+ \code{\link{nifti.datatype.string}},
+ \code{\link{nifti.image.write}},
+ \code{\link{nifti.image.read}}
+}
+
+\keyword{manip}
+\keyword{data}
diff --git a/src/Makevars.in b/src/Makevars.in
new file mode 100644
index 0000000..f5c4f1c
--- /dev/null
+++ b/src/Makevars.in
@@ -0,0 +1,2 @@
+PKG_CPPFLAGS=-I.. @CFLAGS@ @CPPFLAGS@ @INCLUDE@ @DEFS@
+PKG_LIBS=@LDFLAGS@ @LIBS@
diff --git a/src/Rnifti.c b/src/Rnifti.c
new file mode 100644
index 0000000..6ace6f1
--- /dev/null
+++ b/src/Rnifti.c
@@ -0,0 +1,1687 @@
+#include "nifti1_io.h" /* directly include I/O library functions */
+#include "nifti1.h"
+#include <R.h>
+#include <Rdefines.h>
+
+//#include "International.h"
+
+extern char *gni_version;
+
+SEXP NIFTI_type_tag;
+#define SEXP2NIFTI(nim) ((TYPEOF(nim) != EXTPTRSXP || R_ExternalPtrTag(nim) != NIFTI_type_tag)?NULL:(nifti_image *)R_ExternalPtrAddr(nim))
+
+SEXP Rnifti_image_setdatatype(SEXP nim, SEXP value);
+
+/*
+ library(Rniftilib)
+ a=nifti_image_read("C:\\ffmri_L2409-00001-00001-0.img")
+
+ for(s in 1:(dim(a)[2])) image(a[1,s,,],col=gray(1:255/255))
+ for(s in 1:(dim(a)[3])) image(a[1,,s,],col=gray(1:255/255))
+*/
+
+SEXP Rnifti_init(SEXP libpath)
+{
+ NIFTI_type_tag = install("NIFTI_TYPE_TAG");
+ return R_NilValue;
+}
+
+char *Rnifti_attributes[] =
+ {
+ "qto.xyz", /* 0 */
+ "qto.ijk", /* 1 */
+ "sto.xyz", /* 2 */
+ "sto.ijk", /* 3 */
+ "toffset", /* 4 */
+ "descrip", /* 5 */
+ "fname", /* 6 */
+ "iname", /* 7 */
+ "slice.duration", /* 8 */
+ "qform.code", /* 9 */
+ "sform.code", /* 10 */
+ "quatern.b", /* 11 */
+ "quatern.c", /* 12 */
+ "quatern.d", /* 13 */
+ "qoffset.x", /* 14 */
+ "qoffset.y", /* 15 */
+ "qoffset.z", /* 16 */
+ "qfac", /* 17 */
+ "pixdim", /* 18 */
+ "nifti.type", /* 19 */
+ "sizeof.hdr", /* 20 */
+ "datatype", /* 21 */
+ "scl.slope", /* 22 nifti1: Data scaling: slope. analyze 7.5: float funused1; */
+ "scl.inter", /* 23 nifti1: Data scaling: offset. analyze 7.5: float funused2; */
+ "qto_xyz", /* 24 */
+ "qto_ijk", /* 25 */
+ "sto_xyz", /* 26 */
+ "sto_ijk", /* 27 */
+ "dim", /* 28 */
+ "nbyper", /* 29 */
+ "xyz_units", /* 30 */
+ "time_units", /* 31 */
+ NULL
+ };
+
+SEXP Rnifti_mat44_SEXP(mat44 *mat)
+{
+ SEXP ret_val;
+ int c,r;
+ PROTECT(ret_val = NEW_NUMERIC(4*4));
+ for(r=0;r<4;++r)
+ for(c=0;c<4;++c)
+ NUMERIC_POINTER(ret_val)[r+c*4]=(double)(mat->m[r][c]);
+
+ SEXP dim;
+ PROTECT(dim=NEW_INTEGER(2));
+ INTEGER_POINTER(dim)[0]=4;
+ INTEGER_POINTER(dim)[1]=4;
+ SET_DIM(ret_val,dim);
+
+ UNPROTECT(2);
+ return ret_val;
+}
+
+void Rnifti_SEXP_mat44(SEXP val,mat44 *mat)
+{
+ int c,r;
+ PROTECT(val = AS_NUMERIC(val));
+ if(LENGTH(val)==16)
+ {
+ for(r=0;r<4;++r)
+ for(c=0;c<4;++c)
+ (mat->m[r][c])=(float)NUMERIC_POINTER(val)[r+c*4];
+ }
+ else
+ error("matrix must be 4x4\n");
+ UNPROTECT(1);
+}
+
+SEXP Rnifti_mat33_SEXP(mat33 *mat)
+{
+ SEXP ret_val;
+ int c,r;
+ PROTECT(ret_val = NEW_NUMERIC(4*4));
+ for(r=0;r<3;++r)
+ for(c=0;c<3;++c)
+ NUMERIC_POINTER(ret_val)[r+c*4]=(double)mat->m[r][c];
+
+ SEXP dim;
+ PROTECT(dim=NEW_INTEGER(2));
+ INTEGER_POINTER(dim)[0]=3;
+ INTEGER_POINTER(dim)[1]=3;
+ SET_DIM(ret_val,dim);
+
+ UNPROTECT(2);
+ return ret_val;
+}
+
+void Rnifti_SEXP_mat33(SEXP val,mat33 *mat)
+{
+ int c,r;
+ PROTECT(val = AS_NUMERIC(val));
+ if(LENGTH(val)==9)
+ {
+ for(r=0;r<3;++r)
+ for(c=0;c<3;++c)
+ (mat->m[r][c])=(float)NUMERIC_POINTER(val)[r+c*4];
+ }
+ else
+ error("matrix must be 3x3\n");
+ UNPROTECT(1);
+}
+
+SEXP Rnifti_float_SEXP(float val)
+{
+ SEXP ret_val;
+ PROTECT(ret_val=NEW_NUMERIC(1));
+ NUMERIC_POINTER(ret_val)[0]=val;
+ UNPROTECT(1);
+ return ret_val;
+}
+
+void Rnifti_SEXP_float(SEXP val_sexp, float *val)
+{
+ PROTECT(val_sexp=AS_NUMERIC(val_sexp));
+ *val=(float)NUMERIC_POINTER(val_sexp)[0];
+ UNPROTECT(1);
+}
+
+SEXP Rnifti_int_SEXP(int val)
+{
+ SEXP ret_val;
+ PROTECT(ret_val=NEW_INTEGER(1));
+ INTEGER_POINTER(ret_val)[0]=val;
+ UNPROTECT(1);
+ return ret_val;
+}
+
+void Rnifti_SEXP_int(SEXP val_sexp, int *val)
+{
+ PROTECT(val_sexp=AS_INTEGER(val_sexp));
+ *val=(int)INTEGER_POINTER(val_sexp)[0];
+ UNPROTECT(1);
+}
+
+void Rnifti_SEXP_short(SEXP val_sexp, short *val)
+{
+ PROTECT(val_sexp=AS_INTEGER(val_sexp));
+ *val=(short)INTEGER_POINTER(val_sexp)[0];
+ UNPROTECT(1);
+}
+
+SEXP Rnifti_pchar_SEXP(const char* val)
+{
+ SEXP ret_val;
+ PROTECT(ret_val=NEW_CHARACTER(1));
+ if(val!=NULL)
+ SET_STRING_ELT(ret_val, 0, mkChar(val));
+ else
+ SET_STRING_ELT(ret_val, 0, mkChar(""));
+ UNPROTECT(1);
+ return ret_val;
+}
+
+void Rnifti_SEXP_pchar(SEXP val_sexp, char* val, int max_num)
+{
+ PROTECT(val_sexp=AS_CHARACTER(val_sexp));
+ const char *pcstring = CHAR(CHARACTER_POINTER(val_sexp)[0]);
+ if(strlen(pcstring)<max_num)
+ strcpy(val,pcstring);
+ else
+ error("character string to long\n");
+ UNPROTECT(1);
+}
+
+SEXP Rnifti_image_free(SEXP nim)
+{
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(pnim!=NULL)
+ {
+ /*Rprintf("Delete nifti %p\n",pnim);*/
+ nifti_image_free(pnim);
+ R_ClearExternalPtr(nim);
+ }
+ else
+ error("Rnifti_image_free: not a nifti pointer.\n");
+ return R_NilValue;
+}
+
+SEXP Rnifti_image_new()
+{
+ nifti_image *pnim;
+
+ /* create nifti image of size 1x1x1 */
+ pnim = nifti_simple_init_nim();
+
+ /*- if the data pointer is not yet set, get memory space for the image */
+ if( pnim->data == NULL )
+ {
+ int ntot = nifti_get_volsize(pnim);
+ pnim->data = (void *)calloc(1,ntot) ; /* create image memory */
+ if( pnim->data == NULL )
+ {
+ error("** failed to alloc %d bytes for image data\n",(int)ntot);
+ }
+ }
+
+ SEXP nim = R_MakeExternalPtr(pnim,NIFTI_type_tag, R_NilValue);
+ R_RegisterCFinalizer(nim,(R_CFinalizer_t) Rnifti_image_free);
+
+ /* set class attribute to nifti */
+ SEXP classattrib;
+ PROTECT(classattrib = allocVector(STRSXP, 1));
+ SET_STRING_ELT(classattrib, 0, mkChar("nifti"));
+ classgets(nim, classattrib);
+ UNPROTECT(1);
+ return nim;
+}
+
+SEXP Rnifti_image_alloc_data(SEXP nim)
+{
+ int ntot=0;
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(pnim != NULL)
+ {
+ if( pnim->data != NULL )
+ {
+ free(pnim->data);
+ pnim->data = NULL;
+ }
+ /*- if the data pointer is not yet set, get memory space for the image */
+ if( pnim->data == NULL )
+ {
+ ntot = nifti_get_volsize(pnim);
+ pnim->data = (void *)calloc(1,ntot) ; /* create image memory */
+ if( pnim->data == NULL )
+ {
+ error("failed to alloc %d bytes for image data\n",(int)ntot);
+ }
+ }
+ }
+ return Rnifti_int_SEXP(ntot);
+}
+
+SEXP Rnifti_image_unload(SEXP nim)
+{
+ nifti_image *pnim=SEXP2NIFTI(nim);
+ nifti_image_unload( pnim );
+ return nim;
+}
+
+/* EXPERIMENTAL function ...*/
+SEXP Rnifti_read_subregion_image(SEXP nim, SEXP start_index, SEXP region_index)
+{
+ SEXP ret_val=R_NilValue;
+ int i,region_size_in_voxel=0,region_size_in_bytes=0;
+ void *data=NULL;
+ SEXP start_index_sexp,region_index_sexp;
+
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ PROTECT(start_index_sexp=AS_INTEGER(start_index));
+ PROTECT(region_index_sexp=AS_INTEGER(region_index));
+ if(LENGTH(start_index_sexp)<pnim->dim[0] || LENGTH(region_index)<pnim->dim[0])
+ {
+ UNPROTECT(2);
+ error("ERROR: start_index and region_index must have length >= no. of image dimensions!");
+ return ret_val;
+ }
+
+ int *start_index_int=INTEGER_POINTER(start_index_sexp);
+ int *region_index_int=INTEGER_POINTER(region_index_sexp);
+
+ for(i=0;i<pnim->dim[0];++i)
+ region_size_in_voxel=region_index_int[i]*region_size_in_voxel;
+ region_size_in_bytes=region_size_in_voxel*pnim->nbyper;
+
+ switch(pnim->datatype)
+ {
+ case DT_NONE:
+ case DT_BINARY:
+ case DT_UNSIGNED_CHAR: PROTECT(ret_val=NEW_CHARACTER(region_size_in_voxel)); data=(void*)CHARACTER_POINTER(ret_val); break;
+ case DT_SIGNED_INT: PROTECT(ret_val=NEW_INTEGER(region_size_in_voxel)); data=(void*)INTEGER_POINTER(ret_val); break;
+ case DT_DOUBLE: PROTECT(ret_val=NEW_NUMERIC(region_size_in_voxel)); data=(void*)NUMERIC_POINTER(ret_val); break;
+ case DT_INT8:
+ case DT_UINT16:
+ case DT_SIGNED_SHORT:
+ case DT_UINT32:
+ case DT_INT64:
+ case DT_UINT64:
+ case DT_FLOAT:
+ case DT_FLOAT128:
+ case DT_COMPLEX:
+ case DT_COMPLEX128:
+ case DT_COMPLEX256:
+ case DT_RGB:
+ case DT_RGBA32:
+ default: warning("Unsupported or unknown data type!"); break;
+ }
+ if(data!=NULL)
+ {
+ if(region_size_in_bytes != nifti_read_subregion_image(pnim, start_index_int, region_index_int,&data ))
+ error("ERROR: calculated region size different from returned region size!");
+ UNPROTECT(3); // unprotect start_index_sexp and region_index_sexp and ret_val
+ }
+ else
+ UNPROTECT(2); // unprotect start_index_sexp and region_index_sexp
+ return ret_val;
+}
+
+SEXP Rnifti_set_filenames(SEXP nim, SEXP prefix, SEXP check, SEXP set_byte_order)
+{
+ SEXP ret_val=Rnifti_int_SEXP(1);
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(pnim!=NULL)
+ {
+ int icheck;
+ int iset_byte_order;
+ char prefix_buffer[500];
+
+ Rnifti_SEXP_pchar(prefix, prefix_buffer, 500);
+ Rnifti_SEXP_int(check, &icheck);
+ Rnifti_SEXP_int(set_byte_order, &iset_byte_order);
+ ret_val = Rnifti_int_SEXP(nifti_set_filenames( pnim, prefix_buffer, icheck, iset_byte_order));
+ }
+ return ret_val;
+}
+
+
+SEXP Rnifti_image_listattributes(SEXP nim)
+{
+ SEXP Rstring;
+ PROTECT( Rstring= NEW_CHARACTER(9));
+ int iIndex;
+ for(iIndex=0;Rnifti_attributes[iIndex]!=NULL;++iIndex)
+ SET_STRING_ELT(Rstring, iIndex, mkChar(Rnifti_attributes[iIndex]));
+ UNPROTECT(1);
+ return Rstring;
+}
+
+SEXP Rnifti_image_setattribute(SEXP nim, SEXP sym, SEXP value)
+{
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(pnim!=NULL)
+ {
+ SEXP Rstring;
+ PROTECT( Rstring= AS_CHARACTER(sym));
+ int iIndex;
+ for(iIndex=0;Rnifti_attributes[iIndex]!=NULL;++iIndex)
+ if(strcmp(Rnifti_attributes[iIndex],CHAR(STRING_ELT(Rstring,0)))==0)
+ break;
+ UNPROTECT(1);
+ switch(iIndex)
+ {
+ case 0: /*qto.xyz*/
+ //Rnifti_SEXP_mat44(value,&(pnim->qto_xyz));
+ error("set attribute qto.xyz not implemented use qto_xyz!"); break;
+ case 1: /*qto.ijk*/
+ //Rnifti_SEXP_mat44(value,&(pnim->qto_ijk)); break;
+ error("set attribute qto.ijk not implemented use qto_ijk!"); break;
+ case 2: /*sto.xyz*/
+ //Rnifti_SEXP_mat44(value,&(pnim->sto_xyz)); break;
+ error("set attribute sto.xyz not implemented use sto_xyz!"); break;
+ case 3: /*sto.ijk*/
+ //Rnifti_SEXP_mat44(value,&(pnim->sto_ijk)); break;
+ error("set attribute sto.ijk not implemented use sto_ijk!"); break;
+ case 24: /*qto_xyz*/
+ Rnifti_SEXP_mat44(value,&(pnim->qto_xyz)); break;
+ case 25: /*qto_ijk*/
+ Rnifti_SEXP_mat44(value,&(pnim->qto_ijk)); break;
+ case 26: /*sto_xyz*/
+ Rnifti_SEXP_mat44(value,&(pnim->sto_xyz)); break;
+ case 27: /*sto_ijk*/
+ Rnifti_SEXP_mat44(value,&(pnim->sto_ijk)); break;
+ case 4: /*toffset*/
+ Rnifti_SEXP_float(value,&pnim->toffset); break;
+ case 5: /*descrip*/
+ Rnifti_SEXP_pchar(value,pnim->descrip,80); break;
+ case 6: /*fname*/
+ /* Rnifti_SEXP_pchar(value,pnim->fname,0); break; */
+ warning("Can not set this attribute directly! Please use the nifti.set.filenames function.\n"); break;
+ case 7: /*iname*/
+ /* Rnifti_SEXP_pchar(value,pnim->iname,0); break; */
+ warning("Can not set this attribute directly! Please use the nifti.set.filenames function.\n"); break;
+ case 8: /*slice_duration*/
+ Rnifti_SEXP_float(value,&(pnim->slice_duration)); break;
+ case 9: /* qform.code */
+ Rnifti_SEXP_int(value, &(pnim->qform_code)); break;
+ case 10: /* sform.code */
+ Rnifti_SEXP_int(value, &(pnim->sform_code)); break;
+ case 11: /* quatern_b 11 */
+ Rnifti_SEXP_float(value,&(pnim->quatern_b)); break;
+ case 12: /* quatern_c 12 */
+ Rnifti_SEXP_float(value,&(pnim->quatern_c)); break;
+ case 13: /* quatern_d 13 */
+ Rnifti_SEXP_float(value,&(pnim->quatern_d)); break;
+ case 14: /* qoffset_x 14 */
+ Rnifti_SEXP_float(value,&(pnim->qoffset_x)); break;
+ case 15: /* qoffset_y 15 */
+ Rnifti_SEXP_float(value,&(pnim->qoffset_y)); break;
+ case 16: /* qoffset_z 16 */
+ Rnifti_SEXP_float(value,&(pnim->qoffset_z)); break;
+ case 17: /* qfac 17 */
+ Rnifti_SEXP_float(value,&(pnim->qfac)); break;
+ case 18: /* pixdim 18 */
+ if(length(value)<=pnim->dim[0])
+ {
+ int iIndex;
+ PROTECT(value=AS_NUMERIC(value));
+ for(iIndex=0;iIndex<length(value);++iIndex)
+ {
+ pnim->pixdim[iIndex+1]=NUMERIC_POINTER(value)[iIndex];
+ }
+ UNPROTECT(1);
+ }
+ else
+ error("Length of pixdim greater than number of dimensions (dim[0])\n");
+ break;
+ case 19: /* nifti_type 19 */
+ if(IS_NUMERIC(value))
+ {
+ Rnifti_SEXP_int(value,&pnim->nifti_type);
+ }
+ else
+ error("Only nummeric values are allowed to set nifti_type.\n");
+ break;
+ case 21: /* datatype */
+ if(IS_NUMERIC(value))
+ {
+ /*SEXP_to_int(value,&pnim->datatype);*/
+ Rnifti_image_setdatatype(nim, value);
+ }
+ else
+ error("Only nummeric values are allowed to set nifti_datatype.\n");
+ break;
+ case 22: /* scl_slope nifti1: Data scaling: slope. analyze 7.5: float funused1 */
+ if(IS_NUMERIC(value))
+ {
+ Rnifti_SEXP_float(value,&(pnim->scl_slope));
+ }
+ else
+ error("Only nummeric values are allowed to set scl_slope.\n");
+ break;
+ case 23: /* scl_inter nifti1: Data scaling: offset. analyze 7.5: float funused2 */
+ if(IS_NUMERIC(value))
+ {
+ Rnifti_SEXP_float(value,&(pnim->scl_inter));
+ }
+ else
+ error("Only nummeric values are allowed to set scl_inter.\n");
+ break;
+ case 28: /* dim */
+ PROTECT(value = AS_INTEGER(value));
+ if(length(value)>1 && length(value)<=7)
+ {
+ int iIndex;
+ pnim->dim[0]=length(value);
+ for(iIndex=0;iIndex<length(value);++iIndex)
+ {
+ pnim->dim[iIndex+1]=INTEGER_POINTER(value)[iIndex];
+ }
+ // correct dependend structure entries
+ nifti_update_dims_from_array(pnim);
+ // correct size of data array if necessary
+ if( pnim->data != NULL )
+ Rnifti_image_alloc_data(nim);
+ }
+ else
+ error("Length of vector not compatible with the number of dimensions.\n");
+ UNPROTECT(1);
+ break;
+ case 30: /* xyz_units */
+ if((IS_NUMERIC(value) || IS_INTEGER(value)) && length(value)==1)
+ {
+ PROTECT(value = AS_INTEGER(value));
+ pnim->xyz_units=INTEGER_POINTER(value)[0];
+ UNPROTECT(1);
+ }
+ else
+ error("Length of input vector not compatible with xyz_units.\n");
+ break;
+ case 31: /* time_units */
+ if((IS_NUMERIC(value) || IS_INTEGER(value)) && length(value)==1)
+ {
+ PROTECT(value = AS_INTEGER(value));
+ pnim->time_units=INTEGER_POINTER(value)[0];
+ UNPROTECT(1);
+ }
+ else
+ error("Length of input vector not compatible with time_units.\n");
+ break;
+ default:
+ error("Rnifti_image_setattribute: unknown attribute\n");
+ break;
+ }
+ //Rprintf("symbol: %d\n",is_symbol(sym));
+ }
+ else
+ error("Rnifti_image_setattribute: not a pointer to a nifti object.\n");
+ return nim;
+}
+
+SEXP Rnifti_image_getattribute(SEXP nim, SEXP sym)
+{
+ SEXP ret_val=R_NilValue;
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(pnim!=NULL)
+ {
+ SEXP Rstring;
+ PROTECT( Rstring= AS_CHARACTER(sym));
+ int iIndex;
+ for(iIndex=0;Rnifti_attributes[iIndex]!=NULL;++iIndex)
+ if(strcmp(Rnifti_attributes[iIndex],CHAR(STRING_ELT(Rstring,0)))==0)
+ break;
+ UNPROTECT(1);
+ switch(iIndex)
+ {
+ /* R comaptible transformation matrices */
+ case 0: /*qto.xyz*/
+ // old: return Rnifti_mat44_SEXP(&(pnim->qto_xyz)); break;
+ { // generate a matrix compatible with R indexing (voxel start index at 1)
+ mat44 Rqto_xyz;
+ for(int r=0;r<4;++r)
+ {
+ for(int c=0;c<4;++c)
+ {
+ Rqto_xyz.m[r][c]=pnim->qto_xyz.m[r][c];
+ }
+ Rqto_xyz.m[r][3]=Rqto_xyz.m[r][3]-Rqto_xyz.m[r][0]-Rqto_xyz.m[r][1]-Rqto_xyz.m[r][2];
+ }
+ return Rnifti_mat44_SEXP(&Rqto_xyz);
+ }
+ break;
+ case 1: /*qto.ijk*/
+ // old: return Rnifti_mat44_SEXP(&(pnim->qto_ijk)); break;
+ { // generate a matrix compatible with R indexing (voxel start index at 1)
+ mat44 Rqto_ijk;
+ for(int r=0;r<3;++r)
+ {
+ for(int c=0;c<4;++c)
+ {
+ Rqto_ijk.m[r][c]=pnim->qto_ijk.m[r][c]+pnim->qto_ijk.m[3][c];
+ }
+ }
+ for(int c=0;c<4;++c)
+ {
+ Rqto_ijk.m[3][c]=pnim->qto_ijk.m[3][c];
+ }
+ return Rnifti_mat44_SEXP(&Rqto_ijk);
+ }
+ break;
+ case 2: /*sto.xyz*/
+ // old: return Rnifti_mat44_SEXP(&(pnim->sto_xyz)); break;
+ { // generate a matrix compatible with R indexing (voxel start index at 1)
+ mat44 Rsto_xyz;
+ for(int r=0;r<4;++r)
+ {
+ for(int c=0;c<4;++c)
+ {
+ Rsto_xyz.m[r][c]=pnim->sto_xyz.m[r][c];
+ }
+ Rsto_xyz.m[r][3]=Rsto_xyz.m[r][3]-Rsto_xyz.m[r][0]-Rsto_xyz.m[r][1]-Rsto_xyz.m[r][2];
+ }
+ return Rnifti_mat44_SEXP(&Rsto_xyz);
+ }
+ break;
+ case 3: /*sto.ijk*/
+ // old: return Rnifti_mat44_SEXP(&(pnim->sto_ijk)); break;
+ { // generate a matrix compatible with R indexing (voxel index start at 1)
+ mat44 Rsto_ijk;
+ for(int r=0;r<3;++r)
+ {
+ for(int c=0;c<4;++c)
+ {
+ Rsto_ijk.m[r][c]=pnim->sto_ijk.m[r][c]+pnim->sto_ijk.m[3][c];
+ }
+ }
+ for(int c=0;c<4;++c)
+ {
+ Rsto_ijk.m[3][c]=pnim->sto_ijk.m[3][c];
+ }
+ return Rnifti_mat44_SEXP(&Rsto_ijk);
+ }
+ break;
+ /* C comaptible transformation matrices (voxel index start at 0)*/
+ case 24: /*qto_xyz*/
+ return Rnifti_mat44_SEXP(&(pnim->qto_xyz)); break;
+ case 25: /*qto_ijk*/
+ return Rnifti_mat44_SEXP(&(pnim->qto_ijk)); break;
+ case 26: /*sto_xyz*/
+ return Rnifti_mat44_SEXP(&(pnim->sto_xyz)); break;
+ case 27: /*sto_ijk*/
+ return Rnifti_mat44_SEXP(&(pnim->sto_ijk)); break;
+ case 4: /*toffset*/
+ return Rnifti_float_SEXP(pnim->toffset); break;
+ case 5: /*descrip*/
+ return Rnifti_pchar_SEXP(pnim->descrip); break;
+ case 6: /*fname*/
+ return Rnifti_pchar_SEXP(pnim->fname); break;
+ case 7: /*iname*/
+ return Rnifti_pchar_SEXP(pnim->iname); break;
+ case 8: /*slice_duration*/
+ return Rnifti_float_SEXP(pnim->slice_duration); break;
+ case 9: /* qform_code */
+ switch(pnim->qform_code)
+ {
+ case NIFTI_XFORM_UNKNOWN:
+ /*! Arbitrary coordinates (Method 1). */
+ return Rnifti_pchar_SEXP("NIFTI.XFORM.UNKNOWN");
+ break;
+ case NIFTI_XFORM_SCANNER_ANAT:
+ /*! Scanner-based anatomical coordinates */
+ return Rnifti_pchar_SEXP("NIFTI.XFORM.SCANNER_ANAT");
+ break;
+ case NIFTI_XFORM_ALIGNED_ANAT:
+ /*! Coordinates aligned to another file's,
+ or to anatomical "truth". */
+ return Rnifti_pchar_SEXP("NIFTI.XFORM.ALIGNED_ANAT");
+ break;
+ case NIFTI_XFORM_TALAIRACH:
+ /*! Coordinates aligned to Talairach-
+ Tournoux Atlas; (0,0,0)=AC, etc. */
+ return Rnifti_pchar_SEXP("NIFTI.XFORM.TALAIRACH");
+ break;
+ case NIFTI_XFORM_MNI_152:
+ /*! MNI 152 normalized coordinates. */
+ return Rnifti_pchar_SEXP("NIFTI.XFORM.MNI.152");
+ break;
+ default:
+ {
+ char buffer[100];
+ snprintf(buffer,100,"qform code: %d",pnim->qform_code);
+ return Rnifti_pchar_SEXP(buffer);
+ }
+ break;
+ }
+ break;
+ case 10: /* sform_code */
+ switch(pnim->sform_code)
+ {
+ case NIFTI_XFORM_UNKNOWN:
+ /*! Arbitrary coordinates (Method 1). */
+ return Rnifti_pchar_SEXP("NIFTI.XFORM.UNKNOWN");
+ break;
+ case NIFTI_XFORM_SCANNER_ANAT:
+ /*! Scanner-based anatomical coordinates */
+ return Rnifti_pchar_SEXP("NIFTI.XFORM.SCANNER_ANAT");
+ break;
+ case NIFTI_XFORM_ALIGNED_ANAT:
+ /*! Coordinates aligned to another file's,
+ or to anatomical "truth". */
+ return Rnifti_pchar_SEXP("NIFTI.XFORM.ALIGNED.ANAT");
+ break;
+ case NIFTI_XFORM_TALAIRACH:
+ /*! Coordinates aligned to Talairach-
+ Tournoux Atlas; (0,0,0)=AC, etc. */
+ return Rnifti_pchar_SEXP("NIFTI.XFORM.TALAIRACH");
+ break;
+ case NIFTI_XFORM_MNI_152:
+ /*! MNI 152 normalized coordinates. */
+ return Rnifti_pchar_SEXP("NIFTI.XFORM.MNI.152");
+ break;
+ default:
+ {
+ char buffer[100];
+ snprintf(buffer,100,"qform code: %d",pnim->qform_code);
+ return Rnifti_pchar_SEXP(buffer);
+ }
+ break;
+ }
+ break;
+ case 11: /* quatern_b 11 */
+ return Rnifti_float_SEXP(pnim->quatern_b); break;
+ case 12: /* quatern_c 12 */
+ return Rnifti_float_SEXP(pnim->quatern_c); break;
+ case 13: /* quatern_d 13 */
+ return Rnifti_float_SEXP(pnim->quatern_d); break;
+ case 14: /* qoffset_x 14 */
+ return Rnifti_float_SEXP(pnim->qoffset_x); break;
+ case 15: /* qoffset_y 15 */
+ return Rnifti_float_SEXP(pnim->qoffset_y); break;
+ case 16: /* qoffset_z 16 */
+ return Rnifti_float_SEXP(pnim->qoffset_z); break;
+ case 17: /* qfac 17 */
+ return Rnifti_float_SEXP(pnim->qfac); break;
+ case 18: /* pixdim 18 */
+ if(pnim->dim[0]<8)
+ {
+ PROTECT(ret_val=NEW_NUMERIC(pnim->dim[0]));
+ for(iIndex=0;iIndex<pnim->dim[0];++iIndex)
+ {
+ NUMERIC_POINTER(ret_val)[iIndex]=pnim->pixdim[iIndex+1];
+ }
+ UNPROTECT(1);
+ }
+ else
+ error("number of dimensions (dim[0]) > 7!\n");
+ break;
+ case 19: /* nifti_type 19 */
+ switch(pnim->nifti_type)
+ {
+ case NIFTI_FTYPE_ANALYZE:
+ return Rnifti_pchar_SEXP("NIFTI.FTYPE.ANALYZE"); break;
+ case NIFTI_FTYPE_NIFTI1_1:
+ return Rnifti_pchar_SEXP("NIFTI.FTYPE.NIFTI1.1"); break;
+ case NIFTI_FTYPE_NIFTI1_2:
+ return Rnifti_pchar_SEXP("NIFTI.FTYPE.NIFTI1.2"); break;
+ case NIFTI_FTYPE_ASCII:
+ return Rnifti_pchar_SEXP("NIFTI.FTYPE.ASCII"); break;
+ default:
+ return Rnifti_pchar_SEXP("NIFTI.FTYPE.UNKNOWN"); break;
+ }
+ break;
+ case 20: /* sizeof_hdr 20 */
+ {
+ struct nifti_1_header hdr = nifti_convert_nim2nhdr(pnim);
+ return Rnifti_int_SEXP(hdr.sizeof_hdr);
+ }
+ break;
+ case 21: /* datatype */
+ return Rnifti_int_SEXP(pnim->datatype);
+ break;
+ case 22: /* scl_slope nifti1: Data scaling: slope. analyze 7.5: float funused1 */
+ return Rnifti_float_SEXP(pnim->scl_slope);
+ break;
+ case 23: /* scl_inter nifti1: Data scaling: offset. analyze 7.5: float funused2 */
+ return Rnifti_float_SEXP(pnim->scl_inter);
+ break;
+ case 28: /* dim */
+ if(pnim->dim[0]>0 && pnim->dim[0]<8)
+ {
+ PROTECT(ret_val=NEW_INTEGER(pnim->dim[0]));
+ for(iIndex=0;iIndex<pnim->dim[0];++iIndex)
+ {
+ INTEGER_POINTER(ret_val)[iIndex]=pnim->dim[iIndex+1];
+ }
+ UNPROTECT(1);
+ }
+ else
+ error("Rnifti_image_getattribute: incorrect number of dimensions in dim[0]!\n");
+ break;
+ case 29: /* nbyper */
+ return Rnifti_int_SEXP(pnim->nbyper);
+ break;
+ case 30: /* xyz_units */
+ return Rnifti_int_SEXP(pnim->xyz_units);
+ break;
+ case 31: /* time_units */
+ return Rnifti_int_SEXP(pnim->time_units);
+ break;
+ default:
+ error("Rnifti_image_getattribute: unknown symbol\n"); break;
+
+ }
+ //Rprintf("symbol: %d\n",is_symbol(sym));
+ }
+ else
+ error("Rnifti_image_getattribute: not a pointer to a nifti object.\n");
+ return ret_val;
+}
+
+/** @brief Copy the nifti_image structure, without data.
+
+ Duplicate the structure, including fname, iname and extensions.
+ Leave the data pointer as NULL.
+*/
+SEXP Rnifti_image_copy_info(SEXP nim)
+{
+ SEXP ret_val=R_NilValue;
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(pnim!=NULL)
+ {
+ nifti_image *pnew_nim=nifti_copy_nim_info(pnim);
+ ret_val = R_MakeExternalPtr(pnew_nim,NIFTI_type_tag, R_NilValue);
+ R_RegisterCFinalizer(ret_val,(R_CFinalizer_t) Rnifti_image_free);
+
+ // set class attribute to nifti
+ SEXP classattrib;
+ PROTECT(classattrib = allocVector(STRSXP, 1));
+ SET_STRING_ELT(classattrib, 0, mkChar("nifti"));
+ classgets(ret_val, classattrib);
+ UNPROTECT(1);
+ }
+ else
+ error("nifti_image_copy_info: object is not a nifti image");
+ return ret_val;
+}
+
+SEXP Rnifti_image_read(SEXP file, SEXP read_data, SEXP rmNaN)
+{
+ nifti_image *pnim;
+ PROTECT(read_data = AS_INTEGER(read_data));
+ PROTECT(file = AS_CHARACTER(file));
+ PROTECT(rmNaN = AS_LOGICAL(rmNaN));
+ if(!isString(file) || length(file) != 1)
+ { error("Rnifti_image_read: file is not a single string\n"); return R_NilValue; }
+ if(!isLogical(rmNaN) || length(rmNaN) != 1)
+ { error("Rnifti_image_read: rm.NaN is not a single logical\n"); return R_NilValue; }
+ int int_rmNaN = (int)(LOGICAL_POINTER(rmNaN)[0]);
+ if(int_rmNaN<0)
+ { error("Rnifti_image_read: rm.NaN is not a valid logical\n"); return R_NilValue; }
+ if(length(read_data) != 1)
+ { error("Rnifti_image_read: read_data is not a single integer\n"); return R_NilValue; }
+ int *piread_data = INTEGER_POINTER(read_data);
+ const char *pcfilename = CHAR(STRING_ELT(file , 0));
+
+
+
+ pnim = nifti_image_read_NaN( pcfilename , piread_data[0], int_rmNaN ) ;
+ if(pnim==NULL)
+ {
+ error("Rnifti_image_read: Can not open file \"%s\"",pcfilename);
+ UNPROTECT(3);
+ return R_NilValue;
+ }
+
+ SEXP nim = R_MakeExternalPtr(pnim,NIFTI_type_tag, R_NilValue);
+ R_RegisterCFinalizer(nim,(R_CFinalizer_t) Rnifti_image_free);
+
+ // set class attribute to PAC::ImageBase
+ SEXP classattrib;
+ PROTECT(classattrib = allocVector(STRSXP, 1));
+ SET_STRING_ELT(classattrib, 0, mkChar("nifti"));
+ classgets(nim, classattrib);
+ UNPROTECT(4);
+ return nim;
+}
+
+SEXP Rnifti_image_write(SEXP nim)
+{
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(pnim!=NULL)
+ {
+ nifti_image_write(pnim);
+ }
+ return R_NilValue;
+}
+
+/*SEXP Rnifti_image_getdim(SEXP nim)
+{
+ SEXP ret_val=R_NilValue;
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(pnim!=NULL)
+ {
+ int i;
+ PROTECT(ret_val = NEW_INTEGER(pnim->dim[0]));
+ for(i=0;i<pnim->dim[0];++i)
+ INTEGER(ret_val)[i]=pnim->dim[i+1];
+ UNPROTECT(1);
+ }
+ return ret_val;
+}*/
+
+SEXP Rnifti_image_getpixel2(SEXP sexp_args)
+{
+ SEXP ret_val=R_NilValue;
+ // skip function name
+ sexp_args = CDR(sexp_args);
+
+ // check first argument (should be a nifti object)
+ if(sexp_args == R_NilValue)
+ {
+ warning("First argument must be a nifti object.");
+ return ret_val;
+ }
+ // grab nifti object
+ SEXP nim = CAR(sexp_args);
+ nifti_image *pnim=SEXP2NIFTI(nim);
+ if(pnim!=NULL)
+ {
+ int i;
+ for(i = 0; sexp_args != R_NilValue; i++)
+ {
+ Rprintf("arg %04d: ",i);
+ SEXP value = CAR(sexp_args);
+
+ if(value == NULL_USER_OBJECT)
+ Rprintf("NULL");
+ if(IS_LOGICAL(value) && LENGTH(value)>0)
+ Rprintf("%s ",LOGICAL_POINTER(value)[0]?"TRUE":"FALSE");
+ if(IS_NUMERIC(value) && LENGTH(value)>0)
+ Rprintf("%f ",NUMERIC_POINTER(value)[0]);
+ if(IS_INTEGER(value) && LENGTH(value)>0)
+ Rprintf("%d ",INTEGER_POINTER(value)[0]);
+ if(IS_CHARACTER(value) && LENGTH(value)>0)
+ {
+ Rprintf("%s ",CHAR(STRING_ELT(value , 0)));
+ }
+ // the name of the argument
+ {
+ SEXP printname = PRINTNAME(TAG(sexp_args));
+ if(printname != NULL_USER_OBJECT)
+ Rprintf(" (%s) ",CHAR(printname));
+ }
+ Rprintf("\n");
+
+ sexp_args = CDR(sexp_args);
+ }
+ }
+ else
+ warning("First argument must be a nifti object.");
+ return ret_val;
+}
+
+#define REALDIM(iDim) ((iDim<(pnim->dim[0]))?pnim->dim[iDim+1]:1)
+
+SEXP Rnifti_image_getpixel(SEXP nim,
+ SEXP sexp_x, SEXP sexp_y,
+ SEXP sexp_z, SEXP sexp_t,
+ SEXP sexp_dim5, SEXP sexp_dim6, SEXP sexp_dim7)
+{
+ SEXP ret_val=R_NilValue;
+ char buffer[10];
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(IS_LOGICAL(sexp_x) || IS_LOGICAL(sexp_y) || IS_LOGICAL(sexp_z) || IS_LOGICAL(sexp_t) ||
+ IS_LOGICAL(sexp_dim5) || IS_LOGICAL(sexp_dim6) || IS_LOGICAL(sexp_dim7))
+ {
+ error("logical indices are not supported yet!");
+ return nim;
+ }
+
+ if(pnim!=NULL)
+ {
+ SEXP coord[7];
+ PROTECT(coord[0] = AS_INTEGER(sexp_x));
+ PROTECT(coord[1] = AS_INTEGER(sexp_y));
+ PROTECT(coord[2] = AS_INTEGER(sexp_z));
+ PROTECT(coord[3] = AS_INTEGER(sexp_t));
+
+ PROTECT(coord[4] = AS_INTEGER(sexp_dim5));
+ PROTECT(coord[5] = AS_INTEGER(sexp_dim6));
+ PROTECT(coord[6] = AS_INTEGER(sexp_dim7));
+
+ int iDim,outdim=0;
+ int *iCoord[7];
+ // determine number of dimensions in output matrix
+ for(iDim=0;iDim<7;++iDim)
+ {
+ if(LENGTH(coord[iDim])>1) outdim++;
+ iCoord[iDim]=INTEGER(coord[iDim]);
+ }
+ // check if indices are valid (out of bounds?)
+ int iCoordCounter;
+ for(iDim=0;iDim<7;++iDim)
+ for(iCoordCounter=0;iCoordCounter<LENGTH(coord[iDim]);++iCoordCounter)
+ if( iCoord[iDim][iCoordCounter]<0 || iCoord[iDim][iCoordCounter]>=REALDIM(iDim))
+ {
+ error("nifti: index out of range (dimension %d index %d dim: %d) \n",iDim,iCoord[iDim][iCoordCounter],REALDIM(iDim));
+ UNPROTECT(7);
+ return nim;
+ }
+
+ if(pnim->datatype==DT_RGB || pnim->datatype==DT_RGBA32)
+ PROTECT(ret_val = NEW_CHARACTER(LENGTH(sexp_x)*LENGTH(sexp_y)*LENGTH(sexp_z)*LENGTH(sexp_t)));
+ else
+ PROTECT(ret_val = NEW_NUMERIC(LENGTH(sexp_x)*LENGTH(sexp_y)*LENGTH(sexp_z)*LENGTH(sexp_t)));
+ int iIndex[7], iTOffset=0, iSOffset=0;
+ /* do type checking outside the main loop to speedup processing...*/
+ switch(pnim->datatype)
+ {
+ /* uchar (8 bits) */
+ case DT_UNSIGNED_CHAR:
+ for(iIndex[6]=0;iIndex[6]<LENGTH(coord[6]);++iIndex[6])
+ for(iIndex[5]=0;iIndex[5]<LENGTH(coord[5]);++iIndex[5])
+ for(iIndex[4]=0;iIndex[4]<LENGTH(coord[4]);++iIndex[4])
+ for(iIndex[3]=0;iIndex[3]<LENGTH(coord[3]);++iIndex[3])
+ for(iIndex[2]=0;iIndex[2]<LENGTH(coord[2]);++iIndex[2])
+ for(iIndex[1]=0;iIndex[1]<LENGTH(coord[1]);++iIndex[1])
+ for(iIndex[0]=0;iIndex[0]<LENGTH(coord[0]);++iIndex[0])
+ {
+ iSOffset= iCoord[0][iIndex[0]]
+ + iCoord[1][iIndex[1]]*pnim->dim[1]
+ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2]
+ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]
+ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]
+ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]
+ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6];
+ NUMERIC_POINTER(ret_val)[iTOffset] = (double)((unsigned char*)pnim->data)[iSOffset];
+ ++iTOffset;
+ }
+ break;
+ /* signed char (8 bits) */
+ case DT_INT8:
+ for(iIndex[6]=0;iIndex[6]<LENGTH(coord[6]);++iIndex[6])
+ for(iIndex[5]=0;iIndex[5]<LENGTH(coord[5]);++iIndex[5])
+ for(iIndex[4]=0;iIndex[4]<LENGTH(coord[4]);++iIndex[4])
+ for(iIndex[3]=0;iIndex[3]<LENGTH(coord[3]);++iIndex[3])
+ for(iIndex[2]=0;iIndex[2]<LENGTH(coord[2]);++iIndex[2])
+ for(iIndex[1]=0;iIndex[1]<LENGTH(coord[1]);++iIndex[1])
+ for(iIndex[0]=0;iIndex[0]<LENGTH(coord[0]);++iIndex[0])
+ {
+ iSOffset= iCoord[0][iIndex[0]]
+ + iCoord[1][iIndex[1]]*pnim->dim[1]
+ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2]
+ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]
+ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]
+ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]
+ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6];
+ NUMERIC_POINTER(ret_val)[iTOffset] = (double)((signed char*)pnim->data)[iSOffset];
+ ++iTOffset;
+ }
+ break;
+ /* unsigned short (16 bits) */
+ case DT_UINT16:
+ for(iIndex[6]=0;iIndex[6]<LENGTH(coord[6]);++iIndex[6])
+ for(iIndex[5]=0;iIndex[5]<LENGTH(coord[5]);++iIndex[5])
+ for(iIndex[4]=0;iIndex[4]<LENGTH(coord[4]);++iIndex[4])
+ for(iIndex[3]=0;iIndex[3]<LENGTH(coord[3]);++iIndex[3])
+ for(iIndex[2]=0;iIndex[2]<LENGTH(coord[2]);++iIndex[2])
+ for(iIndex[1]=0;iIndex[1]<LENGTH(coord[1]);++iIndex[1])
+ for(iIndex[0]=0;iIndex[0]<LENGTH(coord[0]);++iIndex[0])
+ {
+ iSOffset= iCoord[0][iIndex[0]]
+ + iCoord[1][iIndex[1]]*pnim->dim[1]
+ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2]
+ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]
+ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]
+ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]
+ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6];
+ NUMERIC_POINTER(ret_val)[iTOffset] = (double)((unsigned short*)pnim->data)[iSOffset];
+ ++iTOffset;
+ }
+ break;
+ /* signed short (16 bits) */
+ case DT_SIGNED_SHORT:
+ for(iIndex[6]=0;iIndex[6]<LENGTH(coord[6]);++iIndex[6])
+ for(iIndex[5]=0;iIndex[5]<LENGTH(coord[5]);++iIndex[5])
+ for(iIndex[4]=0;iIndex[4]<LENGTH(coord[4]);++iIndex[4])
+ for(iIndex[3]=0;iIndex[3]<LENGTH(coord[3]);++iIndex[3])
+ for(iIndex[2]=0;iIndex[2]<LENGTH(coord[2]);++iIndex[2])
+ for(iIndex[1]=0;iIndex[1]<LENGTH(coord[1]);++iIndex[1])
+ for(iIndex[0]=0;iIndex[0]<LENGTH(coord[0]);++iIndex[0])
+ {
+ iSOffset= iCoord[0][iIndex[0]]
+ + iCoord[1][iIndex[1]]*pnim->dim[1]
+ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2]
+ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]
+ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]
+ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]
+ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6];
+ NUMERIC_POINTER(ret_val)[iTOffset] = (double)((short*)pnim->data)[iSOffset];
+ ++iTOffset;
+ }
+ break;
+ /* unsigned int (32 bits) */
+ case DT_UINT32:
+ for(iIndex[6]=0;iIndex[6]<LENGTH(coord[6]);++iIndex[6])
+ for(iIndex[5]=0;iIndex[5]<LENGTH(coord[5]);++iIndex[5])
+ for(iIndex[4]=0;iIndex[4]<LENGTH(coord[4]);++iIndex[4])
+ for(iIndex[3]=0;iIndex[3]<LENGTH(coord[3]);++iIndex[3])
+ for(iIndex[2]=0;iIndex[2]<LENGTH(coord[2]);++iIndex[2])
+ for(iIndex[1]=0;iIndex[1]<LENGTH(coord[1]);++iIndex[1])
+ for(iIndex[0]=0;iIndex[0]<LENGTH(coord[0]);++iIndex[0])
+ {
+ iSOffset= iCoord[0][iIndex[0]]
+ + iCoord[1][iIndex[1]]*pnim->dim[1]
+ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2]
+ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]
+ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]
+ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]
+ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6];
+ NUMERIC_POINTER(ret_val)[iTOffset] = (double)((unsigned int*)pnim->data)[iSOffset];
+ ++iTOffset;
+ }
+ break;
+ /* signed int (32 bits) */
+ case DT_SIGNED_INT:
+ for(iIndex[6]=0;iIndex[6]<LENGTH(coord[6]);++iIndex[6])
+ for(iIndex[5]=0;iIndex[5]<LENGTH(coord[5]);++iIndex[5])
+ for(iIndex[4]=0;iIndex[4]<LENGTH(coord[4]);++iIndex[4])
+ for(iIndex[3]=0;iIndex[3]<LENGTH(coord[3]);++iIndex[3])
+ for(iIndex[2]=0;iIndex[2]<LENGTH(coord[2]);++iIndex[2])
+ for(iIndex[1]=0;iIndex[1]<LENGTH(coord[1]);++iIndex[1])
+ for(iIndex[0]=0;iIndex[0]<LENGTH(coord[0]);++iIndex[0])
+ {
+ iSOffset= iCoord[0][iIndex[0]]
+ + iCoord[1][iIndex[1]]*pnim->dim[1]
+ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2]
+ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]
+ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]
+ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]
+ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6];
+ NUMERIC_POINTER(ret_val)[iTOffset] = (double)((int*)pnim->data)[iSOffset];
+ ++iTOffset;
+ }
+ break;
+ /* float (32 bits) */
+ case DT_FLOAT:
+ for(iIndex[6]=0;iIndex[6]<LENGTH(coord[6]);++iIndex[6])
+ for(iIndex[5]=0;iIndex[5]<LENGTH(coord[5]);++iIndex[5])
+ for(iIndex[4]=0;iIndex[4]<LENGTH(coord[4]);++iIndex[4])
+ for(iIndex[3]=0;iIndex[3]<LENGTH(coord[3]);++iIndex[3])
+ for(iIndex[2]=0;iIndex[2]<LENGTH(coord[2]);++iIndex[2])
+ for(iIndex[1]=0;iIndex[1]<LENGTH(coord[1]);++iIndex[1])
+ for(iIndex[0]=0;iIndex[0]<LENGTH(coord[0]);++iIndex[0])
+ {
+ iSOffset= iCoord[0][iIndex[0]]
+ + iCoord[1][iIndex[1]]*pnim->dim[1]
+ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2]
+ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]
+ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]
+ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]
+ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6];
+ NUMERIC_POINTER(ret_val)[iTOffset] = (double)((float*)pnim->data)[iSOffset];
+ ++iTOffset;
+ }
+ break;
+ /* double (64 bits) */
+ case DT_DOUBLE:
+ for(iIndex[6]=0;iIndex[6]<LENGTH(coord[6]);++iIndex[6])
+ for(iIndex[5]=0;iIndex[5]<LENGTH(coord[5]);++iIndex[5])
+ for(iIndex[4]=0;iIndex[4]<LENGTH(coord[4]);++iIndex[4])
+ for(iIndex[3]=0;iIndex[3]<LENGTH(coord[3]);++iIndex[3])
+ for(iIndex[2]=0;iIndex[2]<LENGTH(coord[2]);++iIndex[2])
+ for(iIndex[1]=0;iIndex[1]<LENGTH(coord[1]);++iIndex[1])
+ for(iIndex[0]=0;iIndex[0]<LENGTH(coord[0]);++iIndex[0])
+ {
+ iSOffset= iCoord[0][iIndex[0]]
+ + iCoord[1][iIndex[1]]*pnim->dim[1]
+ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2]
+ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]
+ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]
+ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]
+ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6];
+ NUMERIC_POINTER(ret_val)[iTOffset] = (double)((double*)pnim->data)[iSOffset];
+ ++iTOffset;
+ }
+ break;
+ /* rgb (24 bits) */
+ case DT_RGB:
+ for(iIndex[6]=0;iIndex[6]<LENGTH(coord[6]);++iIndex[6])
+ for(iIndex[5]=0;iIndex[5]<LENGTH(coord[5]);++iIndex[5])
+ for(iIndex[4]=0;iIndex[4]<LENGTH(coord[4]);++iIndex[4])
+ for(iIndex[3]=0;iIndex[3]<LENGTH(coord[3]);++iIndex[3])
+ for(iIndex[2]=0;iIndex[2]<LENGTH(coord[2]);++iIndex[2])
+ for(iIndex[1]=0;iIndex[1]<LENGTH(coord[1]);++iIndex[1])
+ for(iIndex[0]=0;iIndex[0]<LENGTH(coord[0]);++iIndex[0])
+ {
+ iSOffset= iCoord[0][iIndex[0]]
+ + iCoord[1][iIndex[1]]*pnim->dim[1]
+ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2]
+ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]
+ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]
+ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]
+ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6];
+ sprintf(buffer,"#%02X%02X%02X",((unsigned char*)pnim->data)[iSOffset*3],((unsigned char*)pnim->data)[iSOffset*3+1],((unsigned char*)pnim->data)[iSOffset*3+2]);
+ SET_STRING_ELT(ret_val, iTOffset, mkChar(buffer));
+ ++iTOffset;
+ }
+ break;
+ /* rgba (32 bits) */
+ case DT_RGBA32:
+ for(iIndex[6]=0;iIndex[6]<LENGTH(coord[6]);++iIndex[6])
+ for(iIndex[5]=0;iIndex[5]<LENGTH(coord[5]);++iIndex[5])
+ for(iIndex[4]=0;iIndex[4]<LENGTH(coord[4]);++iIndex[4])
+ for(iIndex[3]=0;iIndex[3]<LENGTH(coord[3]);++iIndex[3])
+ for(iIndex[2]=0;iIndex[2]<LENGTH(coord[2]);++iIndex[2])
+ for(iIndex[1]=0;iIndex[1]<LENGTH(coord[1]);++iIndex[1])
+ for(iIndex[0]=0;iIndex[0]<LENGTH(coord[0]);++iIndex[0])
+ {
+ iSOffset= iCoord[0][iIndex[0]]
+ + iCoord[1][iIndex[1]]*pnim->dim[1]
+ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2]
+ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]
+ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]
+ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]
+ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6];
+ sprintf(buffer,"#%02X%02X%02X%02X",((unsigned char*)pnim->data)[iSOffset*4],((unsigned char*)pnim->data)[iSOffset*4+1],((unsigned char*)pnim->data)[iSOffset*4+2],((unsigned char*)pnim->data)[iSOffset*4+3]);
+ SET_STRING_ELT(ret_val, iTOffset, mkChar(buffer));
+ ++iTOffset;
+ }
+ break;
+ default:
+ warning("unsupported data format (identifier %d)",pnim->datatype);
+ }
+ /*Rprintf("outdim=%d\n",outdim);*/
+ /* set the dimension attribute */
+ if(outdim>1)
+ {
+ SEXP dim;
+ PROTECT(dim=NEW_INTEGER(outdim));
+ int iDimCount=0;
+ for(iDim=0;iDim<7;++iDim)
+ {
+ /*Rprintf("length[%d]=%d\n",iDim,LENGTH(coord[iDim]));*/
+ if(LENGTH(coord[iDim])>1)
+ {
+ INTEGER_POINTER(dim)[iDimCount++]=LENGTH(coord[iDim]);
+ }
+ }
+ SET_DIM(ret_val,dim);
+ UNPROTECT(1);
+ }
+ UNPROTECT(8);
+ }
+ return ret_val;
+}
+
+SEXP Rnifti_image_printinfo(SEXP nim)
+{
+ int iIndex;
+ SEXP ret_val=R_NilValue;
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(pnim!=NULL)
+ {
+ Rprintf("dimension: ");
+ for(iIndex=0;iIndex<pnim->dim[0];++iIndex)
+ Rprintf("%d ",pnim->dim[iIndex+1]);
+ Rprintf("\n");
+
+ Rprintf("dimensions: freq = %d, phase = %d, slice = %d\n",
+ pnim->freq_dim, pnim->phase_dim, pnim->slice_dim);
+ if(pnim->qform_code!=NIFTI_XFORM_UNKNOWN)
+ {
+ int icod, jcod, kcod;
+ nifti_mat44_to_orientation( pnim->qto_xyz , &icod, &jcod, &kcod );
+ Rprintf("i orientation (voxel x-axis): %s\n",nifti_orientation_string(icod));
+ Rprintf("j orientation (voxel y-axis): %s\n",nifti_orientation_string(jcod));
+ Rprintf("k orientation (voxel z-axis): %s\n",nifti_orientation_string(kcod));
+ }
+ int c;
+ Rprintf("number of nifti ext. : %d\n",pnim->num_ext);
+ for (c = 0; c < pnim->num_ext; c++ )
+ {
+ Rprintf("%d] size: %d code: %d",c,pnim->ext_list[c].esize,pnim->ext_list[c].ecode);
+ switch(pnim->ext_list[c].ecode)
+ {
+ case NIFTI_ECODE_IGNORE:
+ Rprintf("(ignore /unknown)\n");
+ break;
+ case NIFTI_ECODE_DICOM:
+ Rprintf("(raw DICOM attributes)\n");
+ break;
+ case NIFTI_ECODE_AFNI:
+ Rprintf("(Robert W Cox: http://afni.nimh.nih.gov/afni)\n");
+ break;
+ case NIFTI_ECODE_COMMENT:
+ Rprintf("(plain ASCII text)\n");
+ break;
+ case NIFTI_ECODE_XCEDE:
+ Rprintf("(David B Keator: http://www.nbirn.net/Resources/Users/Applications/xcede/index.htm)\n");
+ break;
+ case NIFTI_ECODE_JIMDIMINFO:
+ Rprintf("(Mark A Horsfield: http://someplace/something)\n");
+ break;
+ case NIFTI_ECODE_WORKFLOW_FWDS:
+ Rprintf("(Kate Fissell: http://kraepelin.wpic.pitt.edu)\n");
+ break;
+ default:
+ Rprintf("(unknown NIFTI_ECODE)\n");
+ break;
+ }
+ }
+ Rprintf("data type: %s (%d)\n",nifti_datatype_to_string(pnim->datatype),pnim->datatype);
+ /*switch(pnim->datatype)
+ {
+ //--- the original ANALYZE 7.5 type codes ---
+ case DT_BINARY: // 1 binary (1 bit/voxel)
+ Rprintf(" data type: 1 binary (1 bit/voxel)\n");
+ break;
+ case DT_UNSIGNED_CHAR: // 2 unsigned char (8 bits/voxel)
+ Rprintf(" data type: 2 unsigned char (8 bits/voxel)\n");
+ break;
+ case DT_SIGNED_SHORT: // 4 signed short (16 bits/voxel)
+ Rprintf(" data type: 4 signed short (16 bits/voxel)\n");
+ break;
+ case DT_SIGNED_INT: // 8 signed int (32 bits/voxel)
+ Rprintf(" data type: 8 signed int (32 bits/voxel)\n");
+ break;
+ case DT_FLOAT: // 16 float (32 bits/voxel)
+ Rprintf(" data type: 16 float (32 bits/voxel)\n");
+ break;
+ case DT_COMPLEX: // 32 complex (64 bits/voxel)
+ Rprintf(" data type: 32 complex (64 bits/voxel)\n");
+ break;
+ case DT_DOUBLE: // 64 double (64 bits/voxel)
+ Rprintf(" data type: 64 double (64 bits/voxel) \n");
+ break;
+ case DT_RGB: //128 RGB triple (24 bits/voxel)
+ Rprintf(" data type: 128 RGB triple (24 bits/voxel)\n");
+ break;
+ //------------------- new codes for NIFTI ---
+ case DT_INT8: // 256 signed char (8 bits)
+ Rprintf(" data type: 256 signed char (8 bits)\n");
+ break;
+ case DT_UINT16: // 512 unsigned short (16 bits)
+ Rprintf(" data type: 512 unsigned short (16 bits)\n");
+ break;
+ case DT_UINT32: // 768 unsigned int (32 bits)
+ Rprintf(" data type: 768 unsigned int (32 bits)\n");
+ break;
+ case DT_INT64: //1024 long long (64 bits)
+ Rprintf(" data type: 1024 long long (64 bits)\n");
+ break;
+ case DT_UINT64: //1280 unsigned long long (64 bits)
+ Rprintf(" data type: 1280 unsigned long long (64 bits)\n");
+ break;
+ case DT_FLOAT128: //1536 long double (128 bits)
+ Rprintf(" data type: 1536 long double (128 bits)\n");
+ break;
+ case DT_COMPLEX128: //1792 double pair (128 bits)
+ Rprintf(" data type: 1792 double pair (128 bits)\n");
+ break;
+ case DT_COMPLEX256: //2048 long double pair (256 bits)
+ Rprintf(" data type: 2048 long double pair (256 bits)\n");
+ break;
+ case DT_RGBA32: //2304 RGBA (32 bits/voxel)
+ Rprintf(" data type: 2304 RGBA32 (32 bits/voxel)\n");
+ break;
+ default: // what it says, dude
+ Rprintf(" data type: %u what it says, dude\n",pnim->datatype);
+ break;
+ }*/
+ }
+ Rprintf("intent: %s\n",nifti_intent_string(pnim->intent_code));
+ Rprintf("attributes: (accessible via $ operator)\n");
+ for(iIndex=0;Rnifti_attributes[iIndex]!=NULL;++iIndex)
+ {
+ if(iIndex!=0)
+ {
+ if(iIndex%5==0)
+ Rprintf("\n");
+ else
+ Rprintf("; ");
+ }
+ Rprintf("\"%s\"",Rnifti_attributes[iIndex]);
+ }
+ Rprintf("\n");
+ return ret_val;
+}
+
+SEXP Rnifti_image_setpixel(
+ SEXP nim,
+ SEXP sexp_x, SEXP sexp_y,
+ SEXP sexp_z, SEXP sexp_t,
+ SEXP sexp_dim5, SEXP sexp_dim6, SEXP sexp_dim7,
+ SEXP value)
+{
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(IS_LOGICAL(sexp_x) || IS_LOGICAL(sexp_y) || IS_LOGICAL(sexp_z) || IS_LOGICAL(sexp_t) ||
+ IS_LOGICAL(sexp_dim5) || IS_LOGICAL(sexp_dim6) || IS_LOGICAL(sexp_dim7))
+ {
+ error("logical indices are not supported");
+ return nim;
+ }
+
+ /*PROTECT(value = AS_NUMERIC(value));*/
+ if(pnim!=NULL)
+ {
+ SEXP coord[7];
+ PROTECT(coord[0] = AS_INTEGER(sexp_x));
+ PROTECT(coord[1] = AS_INTEGER(sexp_y));
+ PROTECT(coord[2] = AS_INTEGER(sexp_z));
+ PROTECT(coord[3] = AS_INTEGER(sexp_t));
+
+ PROTECT(coord[4] = AS_INTEGER(sexp_dim5));
+ PROTECT(coord[5] = AS_INTEGER(sexp_dim6));
+ PROTECT(coord[6] = AS_INTEGER(sexp_dim7));
+
+ int iDim,outdim=0;
+ int *iCoord[7];
+
+ // determine number of dimensions in output matrix
+ for(iDim=0;iDim<7;++iDim)
+ {
+ if(LENGTH(coord[iDim])>1) outdim++;
+ iCoord[iDim]=INTEGER(coord[iDim]);
+ }
+ // check if indices are valid (out of bounds?)
+ int iCoordCounter;
+ for(iDim=0;iDim<7;++iDim)
+ for(iCoordCounter=0;iCoordCounter<LENGTH(coord[iDim]);++iCoordCounter)
+ if( iCoord[iDim][iCoordCounter]<0 || iCoord[iDim][iCoordCounter]>=REALDIM(iDim))
+ {
+ error("nifti: index out of range (dimension %d index %d)",iDim+1,iCoord[iDim][iCoordCounter]+1);
+ UNPROTECT(8);
+ return nim;
+ }
+
+ int iIndex[7], iTOffset=0, iSOffset=0;
+
+ int total=LENGTH(coord[0]);
+ for(iDim=1;iDim<7;++iDim)
+ total*=LENGTH(coord[iDim]);
+
+ if(LENGTH(value)>total || total%LENGTH(value)!=0)
+ {
+ UNPROTECT(7);
+ error("Number of items to replace is not a multiple of replacement length!");
+ return nim;
+ }
+
+#define LOOP_START for(iIndex[6]=0;iIndex[6]<LENGTH(coord[6]);++iIndex[6]) \
+ for(iIndex[5]=0;iIndex[5]<LENGTH(coord[5]);++iIndex[5]) \
+ for(iIndex[4]=0;iIndex[4]<LENGTH(coord[4]);++iIndex[4]) \
+ for(iIndex[3]=0;iIndex[3]<LENGTH(coord[3]);++iIndex[3]) \
+ for(iIndex[2]=0;iIndex[2]<LENGTH(coord[2]);++iIndex[2]) \
+ for(iIndex[1]=0;iIndex[1]<LENGTH(coord[1]);++iIndex[1]) \
+ for(iIndex[0]=0;iIndex[0]<LENGTH(coord[0]);++iIndex[0]) \
+ { \
+ iTOffset = iCoord[0][iIndex[0]] \
+ + iCoord[1][iIndex[1]]*pnim->dim[1] \
+ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] \
+ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] \
+ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] \
+ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] \
+ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6];
+
+#define LOOP_END ++iSOffset; if(iSOffset==LENGTH(value)) iSOffset=0; } break;
+
+ if(IS_NUMERIC(value))
+ {
+ switch(pnim->datatype)
+ {
+ /* uchar (8 bits) */
+ case DT_UNSIGNED_CHAR:
+ LOOP_START
+ ((unsigned char*)pnim->data)[iTOffset]=(unsigned char)(NUMERIC_POINTER(value)[iSOffset]);
+ LOOP_END
+ /* signed char (8 bits) */
+ case DT_INT8:
+ LOOP_START
+ ((signed char*)pnim->data)[iTOffset]=(signed char)(NUMERIC_POINTER(value)[iSOffset]);
+ LOOP_END
+ /* unsigned short (16 bits) */
+ case DT_UINT16:
+ LOOP_START
+ ((unsigned short*)pnim->data)[iTOffset]=(unsigned short)(NUMERIC_POINTER(value)[iSOffset]);
+ LOOP_END
+ // signed short (16 bits)
+ case DT_SIGNED_SHORT:
+ LOOP_START
+ ((short*)pnim->data)[iTOffset]=(short)(NUMERIC_POINTER(value)[iSOffset]);
+ LOOP_END
+ // signed int (32 bits)
+ case DT_SIGNED_INT:
+ LOOP_START
+ ((int*)pnim->data)[iTOffset]=(int)(NUMERIC_POINTER(value)[iSOffset]);
+ LOOP_END
+ /* unsigned int (32 bits) */
+ case DT_UINT32:
+ LOOP_START
+ ((unsigned int*)pnim->data)[iTOffset]=(unsigned int)(NUMERIC_POINTER(value)[iSOffset]);
+ LOOP_END
+ /* float (32 bits) */
+ case DT_FLOAT:
+ LOOP_START
+ ((float*)pnim->data)[iTOffset]=(float)(NUMERIC_POINTER(value)[iSOffset]);
+ LOOP_END
+ /* double (64 bits) */
+ case DT_DOUBLE:
+ LOOP_START
+ ((double*)pnim->data)[iTOffset]=(double)(NUMERIC_POINTER(value)[iSOffset]);
+ LOOP_END
+ /* rgb (24 bits)
+ case DT_RGB:
+ LOOP_START
+ unsigned r,g,b;
+ Rprintf("%s\n",CHAR(CHARACTER_POINTER(value)[iSOffset]));
+ sscanf(CHAR(CHARACTER_POINTER(value)[iSOffset]),"#%2X%2X%2X",&r,&g,&b);
+ Rprintf("%d %d %d\n",r,g,b);
+ ((unsigned char *)pnim->data)[iTOffset*3+0]=(unsigned char)r;
+ ((unsigned char *)pnim->data)[iTOffset*3+1]=(unsigned char)g;
+ ((unsigned char *)pnim->data)[iTOffset*3+2]=(unsigned char)b;
+ LOOP_END*/
+ /* rgba (32 bits)
+ case DT_RGBA32:
+ LOOP_START
+ unsigned r,g,b,a;
+ sscanf(CHAR(CHARACTER_POINTER(value)[iSOffset]),"#%2X%2X%2X%2X",&r,&g,&b,&a);
+ ((unsigned char *)pnim->data)[iTOffset*4+0]=(unsigned char)r;
+ ((unsigned char *)pnim->data)[iTOffset*4+1]=(unsigned char)g;
+ ((unsigned char *)pnim->data)[iTOffset*4+2]=(unsigned char)b;
+ ((unsigned char *)pnim->data)[iTOffset*4+3]=(unsigned char)a;
+ LOOP_END */
+ default:
+ warning("Unsupported data format for input type NUMERIC (nifti image datatype is %d)!",pnim->datatype);
+ }
+ }
+ else if(IS_INTEGER(value))
+ {
+ switch(pnim->datatype)
+ {
+ /* uchar (8 bits) */
+ case DT_UNSIGNED_CHAR:
+ LOOP_START
+ ((unsigned char*)pnim->data)[iTOffset]=(unsigned char)(INTEGER_POINTER(value)[iSOffset]);
+ LOOP_END
+ /* signed char (8 bits) */
+ case DT_INT8:
+ LOOP_START
+ ((signed char*)pnim->data)[iTOffset]=(signed char)(INTEGER_POINTER(value)[iSOffset]);
+ LOOP_END
+ /* unsigned short (16 bits) */
+ case DT_UINT16:
+ LOOP_START
+ ((unsigned short*)pnim->data)[iTOffset]=(unsigned short)(INTEGER_POINTER(value)[iSOffset]);
+ LOOP_END
+ // signed short (16 bits)
+ case DT_SIGNED_SHORT:
+ LOOP_START
+ ((short*)pnim->data)[iTOffset]=(short)(INTEGER_POINTER(value)[iSOffset]);
+ LOOP_END
+ // signed int (32 bits)
+ case DT_SIGNED_INT:
+ LOOP_START
+ ((int*)pnim->data)[iTOffset]=(int)(INTEGER_POINTER(value)[iSOffset]);
+ LOOP_END
+ /* unsigned int (32 bits) */
+ case DT_UINT32:
+ LOOP_START
+ ((unsigned int*)pnim->data)[iTOffset]=(unsigned int)(INTEGER_POINTER(value)[iSOffset]);
+ LOOP_END
+ /* float (32 bits) */
+ case DT_FLOAT:
+ LOOP_START
+ ((float*)pnim->data)[iTOffset]=(float)(INTEGER_POINTER(value)[iSOffset]);
+ LOOP_END
+ /* double (64 bits) */
+ case DT_DOUBLE:
+ LOOP_START
+ ((double*)pnim->data)[iTOffset]=(double)(INTEGER_POINTER(value)[iSOffset]);
+ LOOP_END
+ default:
+ warning("Unsupported data format for input of type INTEGER (nifti image datatype is %d)!",pnim->datatype);
+ }
+ }
+ else if(IS_CHARACTER(value))
+ {
+ switch(pnim->datatype)
+ {
+ /* rgb (24 bits) */
+ case DT_RGB:
+ LOOP_START
+ unsigned r,g,b;
+ /*Rprintf("%s\n",CHAR(CHARACTER_POINTER(value)[iSOffset]));*/
+ sscanf(CHAR(CHARACTER_POINTER(value)[iSOffset]),"#%2X%2X%2X",&r,&g,&b);
+ /*Rprintf("%d %d %d\n",r,g,b);*/
+ ((unsigned char *)pnim->data)[iTOffset*3+0]=(unsigned char)r;
+ ((unsigned char *)pnim->data)[iTOffset*3+1]=(unsigned char)g;
+ ((unsigned char *)pnim->data)[iTOffset*3+2]=(unsigned char)b;
+ LOOP_END
+ /* rgba (32 bits) */
+ case DT_RGBA32:
+ LOOP_START
+ unsigned r,g,b,a;
+ sscanf(CHAR(CHARACTER_POINTER(value)[iSOffset]),"#%2X%2X%2X%2X",&r,&g,&b,&a);
+ ((unsigned char *)pnim->data)[iTOffset*4+0]=(unsigned char)r;
+ ((unsigned char *)pnim->data)[iTOffset*4+1]=(unsigned char)g;
+ ((unsigned char *)pnim->data)[iTOffset*4+2]=(unsigned char)b;
+ ((unsigned char *)pnim->data)[iTOffset*4+3]=(unsigned char)a;
+ LOOP_END
+ default:
+ warning("Unsupported data format for input type CHARACTER (nifti image datatype is %d)",pnim->datatype);
+ }
+ }
+ else
+ error("Unsupported input data format (need NUMERIC, INTEGER or CHARACTER vectors)!");
+ UNPROTECT(7);
+ }
+ return nim;
+}
+
+SEXP Rnifti_image_setdatatype(SEXP nim, SEXP value)
+{
+ nifti_image *pnim=SEXP2NIFTI(nim);
+
+ if(pnim!=NULL)
+ {
+ int itype=DT_UNKNOWN;
+ if(IS_NUMERIC(value) || IS_INTEGER(value))
+ {
+ PROTECT(value = AS_INTEGER(value));
+ itype=INTEGER(value)[0];
+ UNPROTECT(1);
+ }
+ else if(isString(value) || length(value) != 1)
+ {
+ const char *pctype = CHAR(STRING_ELT(value , 0));
+ itype=nifti_datatype_from_string(pctype);
+ }
+ else
+ warning("Unsupported or unknown second argument (type set to DT_UNKNOWN)!");
+ switch(itype)
+ {
+ case DT_NONE: pnim->nbyper=0; break;
+ case DT_BINARY: pnim->nbyper=0; break;
+ case DT_UNSIGNED_CHAR: pnim->nbyper=1; break;
+ case DT_INT8: pnim->nbyper=1; break;
+ case DT_UINT16: pnim->nbyper=2; break;
+ case DT_SIGNED_SHORT: pnim->nbyper=2; break;
+ case DT_SIGNED_INT: pnim->nbyper=4; break;
+ case DT_UINT32: pnim->nbyper=4; break;
+ case DT_INT64: pnim->nbyper=8; break;
+ case DT_UINT64: pnim->nbyper=8; break;
+ case DT_FLOAT: pnim->nbyper=4; break;
+ case DT_FLOAT128: pnim->nbyper=16; break;
+ case DT_DOUBLE: pnim->nbyper=8; break;
+ case DT_COMPLEX: pnim->nbyper=8; break;
+ case DT_COMPLEX128: pnim->nbyper=16; break;
+ case DT_COMPLEX256: pnim->nbyper=32; break;
+ case DT_RGB: pnim->nbyper=3; break;
+ case DT_RGBA32: pnim->nbyper=4; break;
+ default: warning("Unsupported or unknown data type!"); break;
+ }
+ pnim->datatype=itype;
+ }
+ return nim;
+}
+
+
+SEXP Rnifti_compiled_with_zlib(void)
+{
+ SEXP ret_val=R_NilValue;
+
+ PROTECT(ret_val=NEW_LOGICAL(1));
+ LOGICAL_POINTER(ret_val)[0]=nifti_compiled_with_zlib();
+ UNPROTECT(1);
+
+ return ret_val;
+}
+
+SEXP Rnifti_disp_lib_version(void)
+{
+ SEXP ret_val=R_NilValue;
+ char buffer[200];
+
+ snprintf(buffer, 200, "%s, compiled %s", nifti_lib_version(), __DATE__);
+
+ PROTECT(ret_val = NEW_CHARACTER(1));
+ SET_STRING_ELT(ret_val, 0, mkChar(buffer));
+ UNPROTECT(1);
+
+ return ret_val;
+}
+
+SEXP Rnifti_units_string(SEXP value)
+{
+ SEXP ret_val=R_NilValue;
+ PROTECT(value=AS_INTEGER(value));
+ if(IS_INTEGER(value) && LENGTH(value)==1)
+ ret_val = Rnifti_pchar_SEXP(nifti_units_string(INTEGER_POINTER(value)[0]));
+ UNPROTECT(1);
+ return ret_val;
+}
+
+SEXP Rnifti_datatype_string(SEXP value)
+{
+ SEXP ret_val=R_NilValue;
+ PROTECT(value=AS_INTEGER(value));
+ if(IS_INTEGER(value) && LENGTH(value)==1)
+ ret_val = Rnifti_pchar_SEXP(nifti_datatype_string(INTEGER_POINTER(value)[0]));
+ UNPROTECT(1);
+ return ret_val;
+}
+
diff --git a/src/nifti1.h b/src/nifti1.h
new file mode 100644
index 0000000..06d3665
--- /dev/null
+++ b/src/nifti1.h
@@ -0,0 +1,1490 @@
+/** \file nifti1.h
+ \brief Official definition of the nifti1 header. Written by Bob Cox, SSCC, NIMH.
+
+ HISTORY:
+
+ 29 Nov 2007 [rickr]
+ - added DT_RGBA32 and NIFTI_TYPE_RGBA32
+ - added NIFTI_INTENT codes:
+ TIME_SERIES, NODE_INDEX, RGB_VECTOR, RGBA_VECTOR, SHAPE
+ */
+
+#ifndef _NIFTI_HEADER_
+#define _NIFTI_HEADER_
+
+/*****************************************************************************
+ ** This file defines the "NIFTI-1" header format. **
+ ** It is derived from 2 meetings at the NIH (31 Mar 2003 and **
+ ** 02 Sep 2003) of the Data Format Working Group (DFWG), **
+ ** chartered by the NIfTI (Neuroimaging Informatics Technology **
+ ** Initiative) at the National Institutes of Health (NIH). **
+ **--------------------------------------------------------------**
+ ** Neither the National Institutes of Health (NIH), the DFWG, **
+ ** nor any of the members or employees of these institutions **
+ ** imply any warranty of usefulness of this material for any **
+ ** purpose, and do not assume any liability for damages, **
+ ** incidental or otherwise, caused by any use of this document. **
+ ** If these conditions are not acceptable, do not use this! **
+ **--------------------------------------------------------------**
+ ** Author: Robert W Cox (NIMH, Bethesda) **
+ ** Advisors: John Ashburner (FIL, London), **
+ ** Stephen Smith (FMRIB, Oxford), **
+ ** Mark Jenkinson (FMRIB, Oxford) **
+******************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* Note that the ANALYZE 7.5 file header (dbh.h) is
+ (c) Copyright 1986-1995
+ Biomedical Imaging Resource
+ Mayo Foundation
+ Incorporation of components of dbh.h are by permission of the
+ Mayo Foundation.
+
+ Changes from the ANALYZE 7.5 file header in this file are released to the
+ public domain, including the functional comments and any amusing asides.
+-----------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/*! INTRODUCTION TO NIFTI-1:
+ ------------------------
+ The twin (and somewhat conflicting) goals of this modified ANALYZE 7.5
+ format are:
+ (a) To add information to the header that will be useful for functional
+ neuroimaging data analysis and display. These additions include:
+ - More basic data types.
+ - Two affine transformations to specify voxel coordinates.
+ - "Intent" codes and parameters to describe the meaning of the data.
+ - Affine scaling of the stored data values to their "true" values.
+ - Optional storage of the header and image data in one file (.nii).
+ (b) To maintain compatibility with non-NIFTI-aware ANALYZE 7.5 compatible
+ software (i.e., such a program should be able to do something useful
+ with a NIFTI-1 dataset -- at least, with one stored in a traditional
+ .img/.hdr file pair).
+
+ Most of the unused fields in the ANALYZE 7.5 header have been taken,
+ and some of the lesser-used fields have been co-opted for other purposes.
+ Notably, most of the data_history substructure has been co-opted for
+ other purposes, since the ANALYZE 7.5 format describes this substructure
+ as "not required".
+
+ NIFTI-1 FLAG (MAGIC STRINGS):
+ ----------------------------
+ To flag such a struct as being conformant to the NIFTI-1 spec, the last 4
+ bytes of the header must be either the C String "ni1" or "n+1";
+ in hexadecimal, the 4 bytes
+ 6E 69 31 00 or 6E 2B 31 00
+ (in any future version of this format, the '1' will be upgraded to '2',
+ etc.). Normally, such a "magic number" or flag goes at the start of the
+ file, but trying to avoid clobbering widely-used ANALYZE 7.5 fields led to
+ putting this marker last. However, recall that "the last shall be first"
+ (Matthew 20:16).
+
+ If a NIFTI-aware program reads a header file that is NOT marked with a
+ NIFTI magic string, then it should treat the header as an ANALYZE 7.5
+ structure.
+
+ NIFTI-1 FILE STORAGE:
+ --------------------
+ "ni1" means that the image data is stored in the ".img" file corresponding
+ to the header file (starting at file offset 0).
+
+ "n+1" means that the image data is stored in the same file as the header
+ information. We recommend that the combined header+data filename suffix
+ be ".nii". When the dataset is stored in one file, the first byte of image
+ data is stored at byte location (int)vox_offset in this combined file.
+ The minimum allowed value of vox_offset is 352; for compatibility with
+ some software, vox_offset should be an integral multiple of 16.
+
+ GRACE UNDER FIRE:
+ ----------------
+ Most NIFTI-aware programs will only be able to handle a subset of the full
+ range of datasets possible with this format. All NIFTI-aware programs
+ should take care to check if an input dataset conforms to the program's
+ needs and expectations (e.g., check datatype, intent_code, etc.). If the
+ input dataset can't be handled by the program, the program should fail
+ gracefully (e.g., print a useful warning; not crash).
+
+ SAMPLE CODES:
+ ------------
+ The associated files nifti1_io.h and nifti1_io.c provide a sample
+ implementation in C of a set of functions to read, write, and manipulate
+ NIFTI-1 files. The file nifti1_test.c is a sample program that uses
+ the nifti1_io.c functions.
+-----------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* HEADER STRUCT DECLARATION:
+ -------------------------
+ In the comments below for each field, only NIFTI-1 specific requirements
+ or changes from the ANALYZE 7.5 format are described. For convenience,
+ the 348 byte header is described as a single struct, rather than as the
+ ANALYZE 7.5 group of 3 substructs.
+
+ Further comments about the interpretation of various elements of this
+ header are after the data type definition itself. Fields that are
+ marked as ++UNUSED++ have no particular interpretation in this standard.
+ (Also see the UNUSED FIELDS comment section, far below.)
+
+ The presumption below is that the various C types have particular sizes:
+ sizeof(int) = sizeof(float) = 4 ; sizeof(short) = 2
+-----------------------------------------------------------------------------*/
+
+/*=================*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*=================*/
+
+/*! \struct nifti_1_header
+ \brief Data structure defining the fields in the nifti1 header.
+ This binary header should be found at the beginning of a valid
+ NIFTI-1 header file.
+ */
+ /*************************/ /************************/
+struct nifti_1_header { /* NIFTI-1 usage */ /* ANALYZE 7.5 field(s) */
+ /*************************/ /************************/
+
+ /*--- was header_key substruct ---*/
+ int sizeof_hdr; /*!< MUST be 348 */ /* int sizeof_hdr; */
+ char data_type[10]; /*!< ++UNUSED++ */ /* char data_type[10]; */
+ char db_name[18]; /*!< ++UNUSED++ */ /* char db_name[18]; */
+ int extents; /*!< ++UNUSED++ */ /* int extents; */
+ short session_error; /*!< ++UNUSED++ */ /* short session_error; */
+ char regular; /*!< ++UNUSED++ */ /* char regular; */
+ char dim_info; /*!< MRI slice ordering. */ /* char hkey_un0; */
+
+ /*--- was image_dimension substruct ---*/
+ short dim[8]; /*!< Data array dimensions.*/ /* short dim[8]; */
+ float intent_p1 ; /*!< 1st intent parameter. */ /* short unused8; */
+ /* short unused9; */
+ float intent_p2 ; /*!< 2nd intent parameter. */ /* short unused10; */
+ /* short unused11; */
+ float intent_p3 ; /*!< 3rd intent parameter. */ /* short unused12; */
+ /* short unused13; */
+ short intent_code ; /*!< NIFTI_INTENT_* code. */ /* short unused14; */
+ short datatype; /*!< Defines data type! */ /* short datatype; */
+ short bitpix; /*!< Number bits/voxel. */ /* short bitpix; */
+ short slice_start; /*!< First slice index. */ /* short dim_un0; */
+ float pixdim[8]; /*!< Grid spacings. */ /* float pixdim[8]; */
+ float vox_offset; /*!< Offset into .nii file */ /* float vox_offset; */
+ float scl_slope ; /*!< Data scaling: slope. */ /* float funused1; */
+ float scl_inter ; /*!< Data scaling: offset. */ /* float funused2; */
+ short slice_end; /*!< Last slice index. */ /* float funused3; */
+ char slice_code ; /*!< Slice timing order. */
+ char xyzt_units ; /*!< Units of pixdim[1..4] */
+ float cal_max; /*!< Max display intensity */ /* float cal_max; */
+ float cal_min; /*!< Min display intensity */ /* float cal_min; */
+ float slice_duration;/*!< Time for 1 slice. */ /* float compressed; */
+ float toffset; /*!< Time axis shift. */ /* float verified; */
+ int glmax; /*!< ++UNUSED++ */ /* int glmax; */
+ int glmin; /*!< ++UNUSED++ */ /* int glmin; */
+
+ /*--- was data_history substruct ---*/
+ char descrip[80]; /*!< any text you like. */ /* char descrip[80]; */
+ char aux_file[24]; /*!< auxiliary filename. */ /* char aux_file[24]; */
+
+ short qform_code ; /*!< NIFTI_XFORM_* code. */ /*-- all ANALYZE 7.5 ---*/
+ short sform_code ; /*!< NIFTI_XFORM_* code. */ /* fields below here */
+ /* are replaced */
+ float quatern_b ; /*!< Quaternion b param. */
+ float quatern_c ; /*!< Quaternion c param. */
+ float quatern_d ; /*!< Quaternion d param. */
+ float qoffset_x ; /*!< Quaternion x shift. */
+ float qoffset_y ; /*!< Quaternion y shift. */
+ float qoffset_z ; /*!< Quaternion z shift. */
+
+ float srow_x[4] ; /*!< 1st row affine transform. */
+ float srow_y[4] ; /*!< 2nd row affine transform. */
+ float srow_z[4] ; /*!< 3rd row affine transform. */
+
+ char intent_name[16];/*!< 'name' or meaning of data. */
+
+ char magic[4] ; /*!< MUST be "ni1\0" or "n+1\0". */
+
+} ; /**** 348 bytes total ****/
+
+typedef struct nifti_1_header nifti_1_header ;
+
+/*---------------------------------------------------------------------------*/
+/* HEADER EXTENSIONS:
+ -----------------
+ After the end of the 348 byte header (e.g., after the magic field),
+ the next 4 bytes are a char array field named "extension". By default,
+ all 4 bytes of this array should be set to zero. In a .nii file, these
+ 4 bytes will always be present, since the earliest start point for
+ the image data is byte #352. In a separate .hdr file, these bytes may
+ or may not be present. If not present (i.e., if the length of the .hdr
+ file is 348 bytes), then a NIfTI-1 compliant program should use the
+ default value of extension={0,0,0,0}. The first byte (extension[0])
+ is the only value of this array that is specified at present. The other
+ 3 bytes are reserved for future use.
+
+ If extension[0] is nonzero, it indicates that extended header information
+ is present in the bytes following the extension array. In a .nii file,
+ this extended header data is before the image data (and vox_offset
+ must be set correctly to allow for this). In a .hdr file, this extended
+ data follows extension and proceeds (potentially) to the end of the file.
+
+ The format of extended header data is weakly specified. Each extension
+ must be an integer multiple of 16 bytes long. The first 8 bytes of each
+ extension comprise 2 integers:
+ int esize , ecode ;
+ These values may need to be byte-swapped, as indicated by dim[0] for
+ the rest of the header.
+ * esize is the number of bytes that form the extended header data
+ + esize must be a positive integral multiple of 16
+ + this length includes the 8 bytes of esize and ecode themselves
+ * ecode is a non-negative integer that indicates the format of the
+ extended header data that follows
+ + different ecode values are assigned to different developer groups
+ + at present, the "registered" values for code are
+ = 0 = unknown private format (not recommended!)
+ = 2 = DICOM format (i.e., attribute tags and values)
+ = 4 = AFNI group (i.e., ASCII XML-ish elements)
+ In the interests of interoperability (a primary rationale for NIfTI),
+ groups developing software that uses this extension mechanism are
+ encouraged to document and publicize the format of their extensions.
+ To this end, the NIfTI DFWG will assign even numbered codes upon request
+ to groups submitting at least rudimentary documentation for the format
+ of their extension; at present, the contact is mailto:rwcox at nih.gov.
+ The assigned codes and documentation will be posted on the NIfTI
+ website. All odd values of ecode (and 0) will remain unassigned;
+ at least, until the even ones are used up, when we get to 2,147,483,646.
+
+ Note that the other contents of the extended header data section are
+ totally unspecified by the NIfTI-1 standard. In particular, if binary
+ data is stored in such a section, its byte order is not necessarily
+ the same as that given by examining dim[0]; it is incumbent on the
+ programs dealing with such data to determine the byte order of binary
+ extended header data.
+
+ Multiple extended header sections are allowed, each starting with an
+ esize,ecode value pair. The first esize value, as described above,
+ is at bytes #352-355 in the .hdr or .nii file (files start at byte #0).
+ If this value is positive, then the second (esize2) will be found
+ starting at byte #352+esize1 , the third (esize3) at byte #352+esize1+esize2,
+ et cetera. Of course, in a .nii file, the value of vox_offset must
+ be compatible with these extensions. If a malformed file indicates
+ that an extended header data section would run past vox_offset, then
+ the entire extended header section should be ignored. In a .hdr file,
+ if an extended header data section would run past the end-of-file,
+ that extended header data should also be ignored.
+
+ With the above scheme, a program can successively examine the esize
+ and ecode values, and skip over each extended header section if the
+ program doesn't know how to interpret the data within. Of course, any
+ program can simply ignore all extended header sections simply by jumping
+ straight to the image data using vox_offset.
+-----------------------------------------------------------------------------*/
+
+/*! \struct nifti1_extender
+ \brief This structure represents a 4-byte string that should follow the
+ binary nifti_1_header data in a NIFTI-1 header file. If the char
+ values are {1,0,0,0}, the file is expected to contain extensions,
+ values of {0,0,0,0} imply the file does not contain extensions.
+ Other sequences of values are not currently defined.
+ */
+struct nifti1_extender { char extension[4] ; } ;
+typedef struct nifti1_extender nifti1_extender ;
+
+/*! \struct nifti1_extension
+ \brief Data structure defining the fields of a header extension.
+ */
+struct nifti1_extension {
+ int esize ; /*!< size of extension, in bytes (must be multiple of 16) */
+ int ecode ; /*!< extension code, one of the NIFTI_ECODE_ values */
+ char * edata ; /*!< raw data, with no byte swapping (length is esize-8) */
+} ;
+typedef struct nifti1_extension nifti1_extension ;
+
+/*---------------------------------------------------------------------------*/
+/* DATA DIMENSIONALITY (as in ANALYZE 7.5):
+ ---------------------------------------
+ dim[0] = number of dimensions;
+ - if dim[0] is outside range 1..7, then the header information
+ needs to be byte swapped appropriately
+ - ANALYZE supports dim[0] up to 7, but NIFTI-1 reserves
+ dimensions 1,2,3 for space (x,y,z), 4 for time (t), and
+ 5,6,7 for anything else needed.
+
+ dim[i] = length of dimension #i, for i=1..dim[0] (must be positive)
+ - also see the discussion of intent_code, far below
+
+ pixdim[i] = voxel width along dimension #i, i=1..dim[0] (positive)
+ - cf. ORIENTATION section below for use of pixdim[0]
+ - the units of pixdim can be specified with the xyzt_units
+ field (also described far below).
+
+ Number of bits per voxel value is in bitpix, which MUST correspond with
+ the datatype field. The total number of bytes in the image data is
+ dim[1] * ... * dim[dim[0]] * bitpix / 8
+
+ In NIFTI-1 files, dimensions 1,2,3 are for space, dimension 4 is for time,
+ and dimension 5 is for storing multiple values at each spatiotemporal
+ voxel. Some examples:
+ - A typical whole-brain FMRI experiment's time series:
+ - dim[0] = 4
+ - dim[1] = 64 pixdim[1] = 3.75 xyzt_units = NIFTI_UNITS_MM
+ - dim[2] = 64 pixdim[2] = 3.75 | NIFTI_UNITS_SEC
+ - dim[3] = 20 pixdim[3] = 5.0
+ - dim[4] = 120 pixdim[4] = 2.0
+ - A typical T1-weighted anatomical volume:
+ - dim[0] = 3
+ - dim[1] = 256 pixdim[1] = 1.0 xyzt_units = NIFTI_UNITS_MM
+ - dim[2] = 256 pixdim[2] = 1.0
+ - dim[3] = 128 pixdim[3] = 1.1
+ - A single slice EPI time series:
+ - dim[0] = 4
+ - dim[1] = 64 pixdim[1] = 3.75 xyzt_units = NIFTI_UNITS_MM
+ - dim[2] = 64 pixdim[2] = 3.75 | NIFTI_UNITS_SEC
+ - dim[3] = 1 pixdim[3] = 5.0
+ - dim[4] = 1200 pixdim[4] = 0.2
+ - A 3-vector stored at each point in a 3D volume:
+ - dim[0] = 5
+ - dim[1] = 256 pixdim[1] = 1.0 xyzt_units = NIFTI_UNITS_MM
+ - dim[2] = 256 pixdim[2] = 1.0
+ - dim[3] = 128 pixdim[3] = 1.1
+ - dim[4] = 1 pixdim[4] = 0.0
+ - dim[5] = 3 intent_code = NIFTI_INTENT_VECTOR
+ - A single time series with a 3x3 matrix at each point:
+ - dim[0] = 5
+ - dim[1] = 1 xyzt_units = NIFTI_UNITS_SEC
+ - dim[2] = 1
+ - dim[3] = 1
+ - dim[4] = 1200 pixdim[4] = 0.2
+ - dim[5] = 9 intent_code = NIFTI_INTENT_GENMATRIX
+ - intent_p1 = intent_p2 = 3.0 (indicates matrix dimensions)
+-----------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* DATA STORAGE:
+ ------------
+ If the magic field is "n+1", then the voxel data is stored in the
+ same file as the header. In this case, the voxel data starts at offset
+ (int)vox_offset into the header file. Thus, vox_offset=352.0 means that
+ the data starts immediately after the NIFTI-1 header. If vox_offset is
+ greater than 352, the NIFTI-1 format does not say much about the
+ contents of the dataset file between the end of the header and the
+ start of the data.
+
+ FILES:
+ -----
+ If the magic field is "ni1", then the voxel data is stored in the
+ associated ".img" file, starting at offset 0 (i.e., vox_offset is not
+ used in this case, and should be set to 0.0).
+
+ When storing NIFTI-1 datasets in pairs of files, it is customary to name
+ the files in the pattern "name.hdr" and "name.img", as in ANALYZE 7.5.
+ When storing in a single file ("n+1"), the file name should be in
+ the form "name.nii" (the ".nft" and ".nif" suffixes are already taken;
+ cf. http://www.icdatamaster.com/n.html ).
+
+ BYTE ORDERING:
+ -------------
+ The byte order of the data arrays is presumed to be the same as the byte
+ order of the header (which is determined by examining dim[0]).
+
+ Floating point types are presumed to be stored in IEEE-754 format.
+-----------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* DETAILS ABOUT vox_offset:
+ ------------------------
+ In a .nii file, the vox_offset field value is interpreted as the start
+ location of the image data bytes in that file. In a .hdr/.img file pair,
+ the vox_offset field value is the start location of the image data
+ bytes in the .img file.
+ * If vox_offset is less than 352 in a .nii file, it is equivalent
+ to 352 (i.e., image data never starts before byte #352 in a .nii file).
+ * The default value for vox_offset in a .nii file is 352.
+ * In a .hdr file, the default value for vox_offset is 0.
+ * vox_offset should be an integer multiple of 16; otherwise, some
+ programs may not work properly (e.g., SPM). This is to allow
+ memory-mapped input to be properly byte-aligned.
+ Note that since vox_offset is an IEEE-754 32 bit float (for compatibility
+ with the ANALYZE-7.5 format), it effectively has a 24 bit mantissa. All
+ integers from 0 to 2^24 can be represented exactly in this format, but not
+ all larger integers are exactly storable as IEEE-754 32 bit floats. However,
+ unless you plan to have vox_offset be potentially larger than 16 MB, this
+ should not be an issue. (Actually, any integral multiple of 16 up to 2^27
+ can be represented exactly in this format, which allows for up to 128 MB
+ of random information before the image data. If that isn't enough, then
+ perhaps this format isn't right for you.)
+
+ In a .img file (i.e., image data stored separately from the NIfTI-1
+ header), data bytes between #0 and #vox_offset-1 (inclusive) are completely
+ undefined and unregulated by the NIfTI-1 standard. One potential use of
+ having vox_offset > 0 in the .hdr/.img file pair storage method is to make
+ the .img file be a copy of (or link to) a pre-existing image file in some
+ other format, such as DICOM; then vox_offset would be set to the offset of
+ the image data in this file. (It may not be possible to follow the
+ "multiple-of-16 rule" with an arbitrary external file; using the NIfTI-1
+ format in such a case may lead to a file that is incompatible with software
+ that relies on vox_offset being a multiple of 16.)
+
+ In a .nii file, data bytes between #348 and #vox_offset-1 (inclusive) may
+ be used to store user-defined extra information; similarly, in a .hdr file,
+ any data bytes after byte #347 are available for user-defined extra
+ information. The (very weak) regulation of this extra header data is
+ described elsewhere.
+-----------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* DATA SCALING:
+ ------------
+ If the scl_slope field is nonzero, then each voxel value in the dataset
+ should be scaled as
+ y = scl_slope * x + scl_inter
+ where x = voxel value stored
+ y = "true" voxel value
+ Normally, we would expect this scaling to be used to store "true" floating
+ values in a smaller integer datatype, but that is not required. That is,
+ it is legal to use scaling even if the datatype is a float type (crazy,
+ perhaps, but legal).
+ - However, the scaling is to be ignored if datatype is DT_RGB24.
+ - If datatype is a complex type, then the scaling is to be
+ applied to both the real and imaginary parts.
+
+ The cal_min and cal_max fields (if nonzero) are used for mapping (possibly
+ scaled) dataset values to display colors:
+ - Minimum display intensity (black) corresponds to dataset value cal_min.
+ - Maximum display intensity (white) corresponds to dataset value cal_max.
+ - Dataset values below cal_min should display as black also, and values
+ above cal_max as white.
+ - Colors "black" and "white", of course, may refer to any scalar display
+ scheme (e.g., a color lookup table specified via aux_file).
+ - cal_min and cal_max only make sense when applied to scalar-valued
+ datasets (i.e., dim[0] < 5 or dim[5] = 1).
+-----------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* TYPE OF DATA (acceptable values for datatype field):
+ ---------------------------------------------------
+ Values of datatype smaller than 256 are ANALYZE 7.5 compatible.
+ Larger values are NIFTI-1 additions. These are all multiples of 256, so
+ that no bits below position 8 are set in datatype. But there is no need
+ to use only powers-of-2, as the original ANALYZE 7.5 datatype codes do.
+
+ The additional codes are intended to include a complete list of basic
+ scalar types, including signed and unsigned integers from 8 to 64 bits,
+ floats from 32 to 128 bits, and complex (float pairs) from 64 to 256 bits.
+
+ Note that most programs will support only a few of these datatypes!
+ A NIFTI-1 program should fail gracefully (e.g., print a warning message)
+ when it encounters a dataset with a type it doesn't like.
+-----------------------------------------------------------------------------*/
+
+#undef DT_UNKNOWN /* defined in dirent.h on some Unix systems */
+
+/*! \defgroup NIFTI1_DATATYPES
+ \brief nifti1 datatype codes
+ @{
+ */
+ /*--- the original ANALYZE 7.5 type codes ---*/
+#define DT_NONE 0
+#define DT_UNKNOWN 0 /* what it says, dude */
+#define DT_BINARY 1 /* binary (1 bit/voxel) */
+#define DT_UNSIGNED_CHAR 2 /* unsigned char (8 bits/voxel) */
+#define DT_SIGNED_SHORT 4 /* signed short (16 bits/voxel) */
+#define DT_SIGNED_INT 8 /* signed int (32 bits/voxel) */
+#define DT_FLOAT 16 /* float (32 bits/voxel) */
+#define DT_COMPLEX 32 /* complex (64 bits/voxel) */
+#define DT_DOUBLE 64 /* double (64 bits/voxel) */
+#define DT_RGB 128 /* RGB triple (24 bits/voxel) */
+#define DT_ALL 255 /* not very useful (?) */
+
+ /*----- another set of names for the same ---*/
+#define DT_UINT8 2
+#define DT_INT16 4
+#define DT_INT32 8
+#define DT_FLOAT32 16
+#define DT_COMPLEX64 32
+#define DT_FLOAT64 64
+#define DT_RGB24 128
+
+ /*------------------- new codes for NIFTI ---*/
+#define DT_INT8 256 /* signed char (8 bits) */
+#define DT_UINT16 512 /* unsigned short (16 bits) */
+#define DT_UINT32 768 /* unsigned int (32 bits) */
+#define DT_INT64 1024 /* long long (64 bits) */
+#define DT_UINT64 1280 /* unsigned long long (64 bits) */
+#define DT_FLOAT128 1536 /* long double (128 bits) */
+#define DT_COMPLEX128 1792 /* double pair (128 bits) */
+#define DT_COMPLEX256 2048 /* long double pair (256 bits) */
+#define DT_RGBA32 2304 /* 4 byte RGBA (32 bits/voxel) */
+/* @} */
+
+
+ /*------- aliases for all the above codes ---*/
+
+/*! \defgroup NIFTI1_DATATYPE_ALIASES
+ \brief aliases for the nifti1 datatype codes
+ @{
+ */
+ /*! unsigned char. */
+#define NIFTI_TYPE_UINT8 2
+ /*! signed short. */
+#define NIFTI_TYPE_INT16 4
+ /*! signed int. */
+#define NIFTI_TYPE_INT32 8
+ /*! 32 bit float. */
+#define NIFTI_TYPE_FLOAT32 16
+ /*! 64 bit complex = 2 32 bit floats. */
+#define NIFTI_TYPE_COMPLEX64 32
+ /*! 64 bit float = double. */
+#define NIFTI_TYPE_FLOAT64 64
+ /*! 3 8 bit bytes. */
+#define NIFTI_TYPE_RGB24 128
+ /*! signed char. */
+#define NIFTI_TYPE_INT8 256
+ /*! unsigned short. */
+#define NIFTI_TYPE_UINT16 512
+ /*! unsigned int. */
+#define NIFTI_TYPE_UINT32 768
+ /*! signed long long. */
+#define NIFTI_TYPE_INT64 1024
+ /*! unsigned long long. */
+#define NIFTI_TYPE_UINT64 1280
+ /*! 128 bit float = long double. */
+#define NIFTI_TYPE_FLOAT128 1536
+ /*! 128 bit complex = 2 64 bit floats. */
+#define NIFTI_TYPE_COMPLEX128 1792
+ /*! 256 bit complex = 2 128 bit floats */
+#define NIFTI_TYPE_COMPLEX256 2048
+ /*! 4 8 bit bytes. */
+#define NIFTI_TYPE_RGBA32 2304
+/* @} */
+
+ /*-------- sample typedefs for complicated types ---*/
+#if 0
+typedef struct { float r,i; } complex_float ;
+typedef struct { double r,i; } complex_double ;
+typedef struct { long double r,i; } complex_longdouble ;
+typedef struct { unsigned char r,g,b; } rgb_byte ;
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* INTERPRETATION OF VOXEL DATA:
+ ----------------------------
+ The intent_code field can be used to indicate that the voxel data has
+ some particular meaning. In particular, a large number of codes is
+ given to indicate that the the voxel data should be interpreted as
+ being drawn from a given probability distribution.
+
+ VECTOR-VALUED DATASETS:
+ ----------------------
+ The 5th dimension of the dataset, if present (i.e., dim[0]=5 and
+ dim[5] > 1), contains multiple values (e.g., a vector) to be stored
+ at each spatiotemporal location. For example, the header values
+ - dim[0] = 5
+ - dim[1] = 64
+ - dim[2] = 64
+ - dim[3] = 20
+ - dim[4] = 1 (indicates no time axis)
+ - dim[5] = 3
+ - datatype = DT_FLOAT
+ - intent_code = NIFTI_INTENT_VECTOR
+ mean that this dataset should be interpreted as a 3D volume (64x64x20),
+ with a 3-vector of floats defined at each point in the 3D grid.
+
+ A program reading a dataset with a 5th dimension may want to reformat
+ the image data to store each voxels' set of values together in a struct
+ or array. This programming detail, however, is beyond the scope of the
+ NIFTI-1 file specification! Uses of dimensions 6 and 7 are also not
+ specified here.
+
+ STATISTICAL PARAMETRIC DATASETS (i.e., SPMs):
+ --------------------------------------------
+ Values of intent_code from NIFTI_FIRST_STATCODE to NIFTI_LAST_STATCODE
+ (inclusive) indicate that the numbers in the dataset should be interpreted
+ as being drawn from a given distribution. Most such distributions have
+ auxiliary parameters (e.g., NIFTI_INTENT_TTEST has 1 DOF parameter).
+
+ If the dataset DOES NOT have a 5th dimension, then the auxiliary parameters
+ are the same for each voxel, and are given in header fields intent_p1,
+ intent_p2, and intent_p3.
+
+ If the dataset DOES have a 5th dimension, then the auxiliary parameters
+ are different for each voxel. For example, the header values
+ - dim[0] = 5
+ - dim[1] = 128
+ - dim[2] = 128
+ - dim[3] = 1 (indicates a single slice)
+ - dim[4] = 1 (indicates no time axis)
+ - dim[5] = 2
+ - datatype = DT_FLOAT
+ - intent_code = NIFTI_INTENT_TTEST
+ mean that this is a 2D dataset (128x128) of t-statistics, with the
+ t-statistic being in the first "plane" of data and the degrees-of-freedom
+ parameter being in the second "plane" of data.
+
+ If the dataset 5th dimension is used to store the voxel-wise statistical
+ parameters, then dim[5] must be 1 plus the number of parameters required
+ by that distribution (e.g., intent_code=NIFTI_INTENT_TTEST implies dim[5]
+ must be 2, as in the example just above).
+
+ Note: intent_code values 2..10 are compatible with AFNI 1.5x (which is
+ why there is no code with value=1, which is obsolescent in AFNI).
+
+ OTHER INTENTIONS:
+ ----------------
+ The purpose of the intent_* fields is to help interpret the values
+ stored in the dataset. Some non-statistical values for intent_code
+ and conventions are provided for storing other complex data types.
+
+ The intent_name field provides space for a 15 character (plus 0 byte)
+ 'name' string for the type of data stored. Examples:
+ - intent_code = NIFTI_INTENT_ESTIMATE; intent_name = "T1";
+ could be used to signify that the voxel values are estimates of the
+ NMR parameter T1.
+ - intent_code = NIFTI_INTENT_TTEST; intent_name = "House";
+ could be used to signify that the voxel values are t-statistics
+ for the significance of 'activation' response to a House stimulus.
+ - intent_code = NIFTI_INTENT_DISPVECT; intent_name = "ToMNI152";
+ could be used to signify that the voxel values are a displacement
+ vector that transforms each voxel (x,y,z) location to the
+ corresponding location in the MNI152 standard brain.
+ - intent_code = NIFTI_INTENT_SYMMATRIX; intent_name = "DTI";
+ could be used to signify that the voxel values comprise a diffusion
+ tensor image.
+
+ If no data name is implied or needed, intent_name[0] should be set to 0.
+-----------------------------------------------------------------------------*/
+
+ /*! default: no intention is indicated in the header. */
+
+#define NIFTI_INTENT_NONE 0
+
+ /*-------- These codes are for probability distributions ---------------*/
+ /* Most distributions have a number of parameters,
+ below denoted by p1, p2, and p3, and stored in
+ - intent_p1, intent_p2, intent_p3 if dataset doesn't have 5th dimension
+ - image data array if dataset does have 5th dimension
+
+ Functions to compute with many of the distributions below can be found
+ in the CDF library from U Texas.
+
+ Formulas for and discussions of these distributions can be found in the
+ following books:
+
+ [U] Univariate Discrete Distributions,
+ NL Johnson, S Kotz, AW Kemp.
+
+ [C1] Continuous Univariate Distributions, vol. 1,
+ NL Johnson, S Kotz, N Balakrishnan.
+
+ [C2] Continuous Univariate Distributions, vol. 2,
+ NL Johnson, S Kotz, N Balakrishnan. */
+ /*----------------------------------------------------------------------*/
+
+ /*! [C2, chap 32] Correlation coefficient R (1 param):
+ p1 = degrees of freedom
+ R/sqrt(1-R*R) is t-distributed with p1 DOF. */
+
+/*! \defgroup NIFTI1_INTENT_CODES
+ \brief nifti1 intent codes, to describe intended meaning of dataset contents
+ @{
+ */
+#define NIFTI_INTENT_CORREL 2
+
+ /*! [C2, chap 28] Student t statistic (1 param): p1 = DOF. */
+
+#define NIFTI_INTENT_TTEST 3
+
+ /*! [C2, chap 27] Fisher F statistic (2 params):
+ p1 = numerator DOF, p2 = denominator DOF. */
+
+#define NIFTI_INTENT_FTEST 4
+
+ /*! [C1, chap 13] Standard normal (0 params): Density = N(0,1). */
+
+#define NIFTI_INTENT_ZSCORE 5
+
+ /*! [C1, chap 18] Chi-squared (1 param): p1 = DOF.
+ Density(x) proportional to exp(-x/2) * x^(p1/2-1). */
+
+#define NIFTI_INTENT_CHISQ 6
+
+ /*! [C2, chap 25] Beta distribution (2 params): p1=a, p2=b.
+ Density(x) proportional to x^(a-1) * (1-x)^(b-1). */
+
+#define NIFTI_INTENT_BETA 7
+
+ /*! [U, chap 3] Binomial distribution (2 params):
+ p1 = number of trials, p2 = probability per trial.
+ Prob(x) = (p1 choose x) * p2^x * (1-p2)^(p1-x), for x=0,1,...,p1. */
+
+#define NIFTI_INTENT_BINOM 8
+
+ /*! [C1, chap 17] Gamma distribution (2 params):
+ p1 = shape, p2 = scale.
+ Density(x) proportional to x^(p1-1) * exp(-p2*x). */
+
+#define NIFTI_INTENT_GAMMA 9
+
+ /*! [U, chap 4] Poisson distribution (1 param): p1 = mean.
+ Prob(x) = exp(-p1) * p1^x / x! , for x=0,1,2,.... */
+
+#define NIFTI_INTENT_POISSON 10
+
+ /*! [C1, chap 13] Normal distribution (2 params):
+ p1 = mean, p2 = standard deviation. */
+
+#define NIFTI_INTENT_NORMAL 11
+
+ /*! [C2, chap 30] Noncentral F statistic (3 params):
+ p1 = numerator DOF, p2 = denominator DOF,
+ p3 = numerator noncentrality parameter. */
+
+#define NIFTI_INTENT_FTEST_NONC 12
+
+ /*! [C2, chap 29] Noncentral chi-squared statistic (2 params):
+ p1 = DOF, p2 = noncentrality parameter. */
+
+#define NIFTI_INTENT_CHISQ_NONC 13
+
+ /*! [C2, chap 23] Logistic distribution (2 params):
+ p1 = location, p2 = scale.
+ Density(x) proportional to sech^2((x-p1)/(2*p2)). */
+
+#define NIFTI_INTENT_LOGISTIC 14
+
+ /*! [C2, chap 24] Laplace distribution (2 params):
+ p1 = location, p2 = scale.
+ Density(x) proportional to exp(-abs(x-p1)/p2). */
+
+#define NIFTI_INTENT_LAPLACE 15
+
+ /*! [C2, chap 26] Uniform distribution: p1 = lower end, p2 = upper end. */
+
+#define NIFTI_INTENT_UNIFORM 16
+
+ /*! [C2, chap 31] Noncentral t statistic (2 params):
+ p1 = DOF, p2 = noncentrality parameter. */
+
+#define NIFTI_INTENT_TTEST_NONC 17
+
+ /*! [C1, chap 21] Weibull distribution (3 params):
+ p1 = location, p2 = scale, p3 = power.
+ Density(x) proportional to
+ ((x-p1)/p2)^(p3-1) * exp(-((x-p1)/p2)^p3) for x > p1. */
+
+#define NIFTI_INTENT_WEIBULL 18
+
+ /*! [C1, chap 18] Chi distribution (1 param): p1 = DOF.
+ Density(x) proportional to x^(p1-1) * exp(-x^2/2) for x > 0.
+ p1 = 1 = 'half normal' distribution
+ p1 = 2 = Rayleigh distribution
+ p1 = 3 = Maxwell-Boltzmann distribution. */
+
+#define NIFTI_INTENT_CHI 19
+
+ /*! [C1, chap 15] Inverse Gaussian (2 params):
+ p1 = mu, p2 = lambda
+ Density(x) proportional to
+ exp(-p2*(x-p1)^2/(2*p1^2*x)) / x^3 for x > 0. */
+
+#define NIFTI_INTENT_INVGAUSS 20
+
+ /*! [C2, chap 22] Extreme value type I (2 params):
+ p1 = location, p2 = scale
+ cdf(x) = exp(-exp(-(x-p1)/p2)). */
+
+#define NIFTI_INTENT_EXTVAL 21
+
+ /*! Data is a 'p-value' (no params). */
+
+#define NIFTI_INTENT_PVAL 22
+
+ /*! Data is ln(p-value) (no params).
+ To be safe, a program should compute p = exp(-abs(this_value)).
+ The nifti_stats.c library returns this_value
+ as positive, so that this_value = -log(p). */
+
+
+#define NIFTI_INTENT_LOGPVAL 23
+
+ /*! Data is log10(p-value) (no params).
+ To be safe, a program should compute p = pow(10.,-abs(this_value)).
+ The nifti_stats.c library returns this_value
+ as positive, so that this_value = -log10(p). */
+
+#define NIFTI_INTENT_LOG10PVAL 24
+
+ /*! Smallest intent_code that indicates a statistic. */
+
+#define NIFTI_FIRST_STATCODE 2
+
+ /*! Largest intent_code that indicates a statistic. */
+
+#define NIFTI_LAST_STATCODE 24
+
+ /*---------- these values for intent_code aren't for statistics ----------*/
+
+ /*! To signify that the value at each voxel is an estimate
+ of some parameter, set intent_code = NIFTI_INTENT_ESTIMATE.
+ The name of the parameter may be stored in intent_name. */
+
+#define NIFTI_INTENT_ESTIMATE 1001
+
+ /*! To signify that the value at each voxel is an index into
+ some set of labels, set intent_code = NIFTI_INTENT_LABEL.
+ The filename with the labels may stored in aux_file. */
+
+#define NIFTI_INTENT_LABEL 1002
+
+ /*! To signify that the value at each voxel is an index into the
+ NeuroNames labels set, set intent_code = NIFTI_INTENT_NEURONAME. */
+
+#define NIFTI_INTENT_NEURONAME 1003
+
+ /*! To store an M x N matrix at each voxel:
+ - dataset must have a 5th dimension (dim[0]=5 and dim[5]>1)
+ - intent_code must be NIFTI_INTENT_GENMATRIX
+ - dim[5] must be M*N
+ - intent_p1 must be M (in float format)
+ - intent_p2 must be N (ditto)
+ - the matrix values A[i][[j] are stored in row-order:
+ - A[0][0] A[0][1] ... A[0][N-1]
+ - A[1][0] A[1][1] ... A[1][N-1]
+ - etc., until
+ - A[M-1][0] A[M-1][1] ... A[M-1][N-1] */
+
+#define NIFTI_INTENT_GENMATRIX 1004
+
+ /*! To store an NxN symmetric matrix at each voxel:
+ - dataset must have a 5th dimension
+ - intent_code must be NIFTI_INTENT_SYMMATRIX
+ - dim[5] must be N*(N+1)/2
+ - intent_p1 must be N (in float format)
+ - the matrix values A[i][[j] are stored in row-order:
+ - A[0][0]
+ - A[1][0] A[1][1]
+ - A[2][0] A[2][1] A[2][2]
+ - etc.: row-by-row */
+
+#define NIFTI_INTENT_SYMMATRIX 1005
+
+ /*! To signify that the vector value at each voxel is to be taken
+ as a displacement field or vector:
+ - dataset must have a 5th dimension
+ - intent_code must be NIFTI_INTENT_DISPVECT
+ - dim[5] must be the dimensionality of the displacment
+ vector (e.g., 3 for spatial displacement, 2 for in-plane) */
+
+#define NIFTI_INTENT_DISPVECT 1006 /* specifically for displacements */
+#define NIFTI_INTENT_VECTOR 1007 /* for any other type of vector */
+
+ /*! To signify that the vector value at each voxel is really a
+ spatial coordinate (e.g., the vertices or nodes of a surface mesh):
+ - dataset must have a 5th dimension
+ - intent_code must be NIFTI_INTENT_POINTSET
+ - dim[0] = 5
+ - dim[1] = number of points
+ - dim[2] = dim[3] = dim[4] = 1
+ - dim[5] must be the dimensionality of space (e.g., 3 => 3D space).
+ - intent_name may describe the object these points come from
+ (e.g., "pial", "gray/white" , "EEG", "MEG"). */
+
+#define NIFTI_INTENT_POINTSET 1008
+
+ /*! To signify that the vector value at each voxel is really a triple
+ of indexes (e.g., forming a triangle) from a pointset dataset:
+ - dataset must have a 5th dimension
+ - intent_code must be NIFTI_INTENT_TRIANGLE
+ - dim[0] = 5
+ - dim[1] = number of triangles
+ - dim[2] = dim[3] = dim[4] = 1
+ - dim[5] = 3
+ - datatype should be an integer type (preferably DT_INT32)
+ - the data values are indexes (0,1,...) into a pointset dataset. */
+
+#define NIFTI_INTENT_TRIANGLE 1009
+
+ /*! To signify that the vector value at each voxel is a quaternion:
+ - dataset must have a 5th dimension
+ - intent_code must be NIFTI_INTENT_QUATERNION
+ - dim[0] = 5
+ - dim[5] = 4
+ - datatype should be a floating point type */
+
+#define NIFTI_INTENT_QUATERNION 1010
+
+ /*! Dimensionless value - no params - although, as in _ESTIMATE
+ the name of the parameter may be stored in intent_name. */
+
+#define NIFTI_INTENT_DIMLESS 1011
+
+ /*---------- these values apply to GIFTI datasets ----------*/
+
+ /*! To signify that the value at each location is from a time series. */
+
+#define NIFTI_INTENT_TIME_SERIES 2001
+
+ /*! To signify that the value at each location is a node index, from
+ a complete surface dataset. */
+
+#define NIFTI_INTENT_NODE_INDEX 2002
+
+ /*! To signify that the vector value at each location is an RGB triplet,
+ of whatever type.
+ - dataset must have a 5th dimension
+ - dim[0] = 5
+ - dim[1] = number of nodes
+ - dim[2] = dim[3] = dim[4] = 1
+ - dim[5] = 3
+ */
+
+#define NIFTI_INTENT_RGB_VECTOR 2003
+
+ /*! To signify that the vector value at each location is a 4 valued RGBA
+ vector, of whatever type.
+ - dataset must have a 5th dimension
+ - dim[0] = 5
+ - dim[1] = number of nodes
+ - dim[2] = dim[3] = dim[4] = 1
+ - dim[5] = 4
+ */
+
+#define NIFTI_INTENT_RGBA_VECTOR 2004
+
+ /*! To signify that the value at each location is a shape value, such
+ as the curvature. */
+
+#define NIFTI_INTENT_SHAPE 2005
+
+/* @} */
+
+/*---------------------------------------------------------------------------*/
+/* 3D IMAGE (VOLUME) ORIENTATION AND LOCATION IN SPACE:
+ ---------------------------------------------------
+ There are 3 different methods by which continuous coordinates can
+ attached to voxels. The discussion below emphasizes 3D volumes, and
+ the continuous coordinates are referred to as (x,y,z). The voxel
+ index coordinates (i.e., the array indexes) are referred to as (i,j,k),
+ with valid ranges:
+ i = 0 .. dim[1]-1
+ j = 0 .. dim[2]-1 (if dim[0] >= 2)
+ k = 0 .. dim[3]-1 (if dim[0] >= 3)
+ The (x,y,z) coordinates refer to the CENTER of a voxel. In methods
+ 2 and 3, the (x,y,z) axes refer to a subject-based coordinate system,
+ with
+ +x = Right +y = Anterior +z = Superior.
+ This is a right-handed coordinate system. However, the exact direction
+ these axes point with respect to the subject depends on qform_code
+ (Method 2) and sform_code (Method 3).
+
+ N.B.: The i index varies most rapidly, j index next, k index slowest.
+ Thus, voxel (i,j,k) is stored starting at location
+ (i + j*dim[1] + k*dim[1]*dim[2]) * (bitpix/8)
+ into the dataset array.
+
+ N.B.: The ANALYZE 7.5 coordinate system is
+ +x = Left +y = Anterior +z = Superior
+ which is a left-handed coordinate system. This backwardness is
+ too difficult to tolerate, so this NIFTI-1 standard specifies the
+ coordinate order which is most common in functional neuroimaging.
+
+ N.B.: The 3 methods below all give the locations of the voxel centers
+ in the (x,y,z) coordinate system. In many cases, programs will wish
+ to display image data on some other grid. In such a case, the program
+ will need to convert its desired (x,y,z) values into (i,j,k) values
+ in order to extract (or interpolate) the image data. This operation
+ would be done with the inverse transformation to those described below.
+
+ N.B.: Method 2 uses a factor 'qfac' which is either -1 or 1; qfac is
+ stored in the otherwise unused pixdim[0]. If pixdim[0]=0.0 (which
+ should not occur), we take qfac=1. Of course, pixdim[0] is only used
+ when reading a NIFTI-1 header, not when reading an ANALYZE 7.5 header.
+
+ N.B.: The units of (x,y,z) can be specified using the xyzt_units field.
+
+ METHOD 1 (the "old" way, used only when qform_code = 0):
+ -------------------------------------------------------
+ The coordinate mapping from (i,j,k) to (x,y,z) is the ANALYZE
+ 7.5 way. This is a simple scaling relationship:
+
+ x = pixdim[1] * i
+ y = pixdim[2] * j
+ z = pixdim[3] * k
+
+ No particular spatial orientation is attached to these (x,y,z)
+ coordinates. (NIFTI-1 does not have the ANALYZE 7.5 orient field,
+ which is not general and is often not set properly.) This method
+ is not recommended, and is present mainly for compatibility with
+ ANALYZE 7.5 files.
+
+ METHOD 2 (used when qform_code > 0, which should be the "normal" case):
+ ---------------------------------------------------------------------
+ The (x,y,z) coordinates are given by the pixdim[] scales, a rotation
+ matrix, and a shift. This method is intended to represent
+ "scanner-anatomical" coordinates, which are often embedded in the
+ image header (e.g., DICOM fields (0020,0032), (0020,0037), (0028,0030),
+ and (0018,0050)), and represent the nominal orientation and location of
+ the data. This method can also be used to represent "aligned"
+ coordinates, which would typically result from some post-acquisition
+ alignment of the volume to a standard orientation (e.g., the same
+ subject on another day, or a rigid rotation to true anatomical
+ orientation from the tilted position of the subject in the scanner).
+ The formula for (x,y,z) in terms of header parameters and (i,j,k) is:
+
+ [ x ] [ R11 R12 R13 ] [ pixdim[1] * i ] [ qoffset_x ]
+ [ y ] = [ R21 R22 R23 ] [ pixdim[2] * j ] + [ qoffset_y ]
+ [ z ] [ R31 R32 R33 ] [ qfac * pixdim[3] * k ] [ qoffset_z ]
+
+ The qoffset_* shifts are in the NIFTI-1 header. Note that the center
+ of the (i,j,k)=(0,0,0) voxel (first value in the dataset array) is
+ just (x,y,z)=(qoffset_x,qoffset_y,qoffset_z).
+
+ The rotation matrix R is calculated from the quatern_* parameters.
+ This calculation is described below.
+
+ The scaling factor qfac is either 1 or -1. The rotation matrix R
+ defined by the quaternion parameters is "proper" (has determinant 1).
+ This may not fit the needs of the data; for example, if the image
+ grid is
+ i increases from Left-to-Right
+ j increases from Anterior-to-Posterior
+ k increases from Inferior-to-Superior
+ Then (i,j,k) is a left-handed triple. In this example, if qfac=1,
+ the R matrix would have to be
+
+ [ 1 0 0 ]
+ [ 0 -1 0 ] which is "improper" (determinant = -1).
+ [ 0 0 1 ]
+
+ If we set qfac=-1, then the R matrix would be
+
+ [ 1 0 0 ]
+ [ 0 -1 0 ] which is proper.
+ [ 0 0 -1 ]
+
+ This R matrix is represented by quaternion [a,b,c,d] = [0,1,0,0]
+ (which encodes a 180 degree rotation about the x-axis).
+
+ METHOD 3 (used when sform_code > 0):
+ -----------------------------------
+ The (x,y,z) coordinates are given by a general affine transformation
+ of the (i,j,k) indexes:
+
+ x = srow_x[0] * i + srow_x[1] * j + srow_x[2] * k + srow_x[3]
+ y = srow_y[0] * i + srow_y[1] * j + srow_y[2] * k + srow_y[3]
+ z = srow_z[0] * i + srow_z[1] * j + srow_z[2] * k + srow_z[3]
+
+ The srow_* vectors are in the NIFTI_1 header. Note that no use is
+ made of pixdim[] in this method.
+
+ WHY 3 METHODS?
+ --------------
+ Method 1 is provided only for backwards compatibility. The intention
+ is that Method 2 (qform_code > 0) represents the nominal voxel locations
+ as reported by the scanner, or as rotated to some fiducial orientation and
+ location. Method 3, if present (sform_code > 0), is to be used to give
+ the location of the voxels in some standard space. The sform_code
+ indicates which standard space is present. Both methods 2 and 3 can be
+ present, and be useful in different contexts (method 2 for displaying the
+ data on its original grid; method 3 for displaying it on a standard grid).
+
+ In this scheme, a dataset would originally be set up so that the
+ Method 2 coordinates represent what the scanner reported. Later,
+ a registration to some standard space can be computed and inserted
+ in the header. Image display software can use either transform,
+ depending on its purposes and needs.
+
+ In Method 2, the origin of coordinates would generally be whatever
+ the scanner origin is; for example, in MRI, (0,0,0) is the center
+ of the gradient coil.
+
+ In Method 3, the origin of coordinates would depend on the value
+ of sform_code; for example, for the Talairach coordinate system,
+ (0,0,0) corresponds to the Anterior Commissure.
+
+ QUATERNION REPRESENTATION OF ROTATION MATRIX (METHOD 2)
+ -------------------------------------------------------
+ The orientation of the (x,y,z) axes relative to the (i,j,k) axes
+ in 3D space is specified using a unit quaternion [a,b,c,d], where
+ a*a+b*b+c*c+d*d=1. The (b,c,d) values are all that is needed, since
+ we require that a = sqrt(1.0-(b*b+c*c+d*d)) be nonnegative. The (b,c,d)
+ values are stored in the (quatern_b,quatern_c,quatern_d) fields.
+
+ The quaternion representation is chosen for its compactness in
+ representing rotations. The (proper) 3x3 rotation matrix that
+ corresponds to [a,b,c,d] is
+
+ [ a*a+b*b-c*c-d*d 2*b*c-2*a*d 2*b*d+2*a*c ]
+ R = [ 2*b*c+2*a*d a*a+c*c-b*b-d*d 2*c*d-2*a*b ]
+ [ 2*b*d-2*a*c 2*c*d+2*a*b a*a+d*d-c*c-b*b ]
+
+ [ R11 R12 R13 ]
+ = [ R21 R22 R23 ]
+ [ R31 R32 R33 ]
+
+ If (p,q,r) is a unit 3-vector, then rotation of angle h about that
+ direction is represented by the quaternion
+
+ [a,b,c,d] = [cos(h/2), p*sin(h/2), q*sin(h/2), r*sin(h/2)].
+
+ Requiring a >= 0 is equivalent to requiring -Pi <= h <= Pi. (Note that
+ [-a,-b,-c,-d] represents the same rotation as [a,b,c,d]; there are 2
+ quaternions that can be used to represent a given rotation matrix R.)
+ To rotate a 3-vector (x,y,z) using quaternions, we compute the
+ quaternion product
+
+ [0,x',y',z'] = [a,b,c,d] * [0,x,y,z] * [a,-b,-c,-d]
+
+ which is equivalent to the matrix-vector multiply
+
+ [ x' ] [ x ]
+ [ y' ] = R [ y ] (equivalence depends on a*a+b*b+c*c+d*d=1)
+ [ z' ] [ z ]
+
+ Multiplication of 2 quaternions is defined by the following:
+
+ [a,b,c,d] = a*1 + b*I + c*J + d*K
+ where
+ I*I = J*J = K*K = -1 (I,J,K are square roots of -1)
+ I*J = K J*K = I K*I = J
+ J*I = -K K*J = -I I*K = -J (not commutative!)
+ For example
+ [a,b,0,0] * [0,0,0,1] = [0,0,-b,a]
+ since this expands to
+ (a+b*I)*(K) = (a*K+b*I*K) = (a*K-b*J).
+
+ The above formula shows how to go from quaternion (b,c,d) to
+ rotation matrix and direction cosines. Conversely, given R,
+ we can compute the fields for the NIFTI-1 header by
+
+ a = 0.5 * sqrt(1+R11+R22+R33) (not stored)
+ b = 0.25 * (R32-R23) / a => quatern_b
+ c = 0.25 * (R13-R31) / a => quatern_c
+ d = 0.25 * (R21-R12) / a => quatern_d
+
+ If a=0 (a 180 degree rotation), alternative formulas are needed.
+ See the nifti1_io.c function mat44_to_quatern() for an implementation
+ of the various cases in converting R to [a,b,c,d].
+
+ Note that R-transpose (= R-inverse) would lead to the quaternion
+ [a,-b,-c,-d].
+
+ The choice to specify the qoffset_x (etc.) values in the final
+ coordinate system is partly to make it easy to convert DICOM images to
+ this format. The DICOM attribute "Image Position (Patient)" (0020,0032)
+ stores the (Xd,Yd,Zd) coordinates of the center of the first voxel.
+ Here, (Xd,Yd,Zd) refer to DICOM coordinates, and Xd=-x, Yd=-y, Zd=z,
+ where (x,y,z) refers to the NIFTI coordinate system discussed above.
+ (i.e., DICOM +Xd is Left, +Yd is Posterior, +Zd is Superior,
+ whereas +x is Right, +y is Anterior , +z is Superior. )
+ Thus, if the (0020,0032) DICOM attribute is extracted into (px,py,pz), then
+ qoffset_x = -px qoffset_y = -py qoffset_z = pz
+ is a reasonable setting when qform_code=NIFTI_XFORM_SCANNER_ANAT.
+
+ That is, DICOM's coordinate system is 180 degrees rotated about the z-axis
+ from the neuroscience/NIFTI coordinate system. To transform between DICOM
+ and NIFTI, you just have to negate the x- and y-coordinates.
+
+ The DICOM attribute (0020,0037) "Image Orientation (Patient)" gives the
+ orientation of the x- and y-axes of the image data in terms of 2 3-vectors.
+ The first vector is a unit vector along the x-axis, and the second is
+ along the y-axis. If the (0020,0037) attribute is extracted into the
+ value (xa,xb,xc,ya,yb,yc), then the first two columns of the R matrix
+ would be
+ [ -xa -ya ]
+ [ -xb -yb ]
+ [ xc yc ]
+ The negations are because DICOM's x- and y-axes are reversed relative
+ to NIFTI's. The third column of the R matrix gives the direction of
+ displacement (relative to the subject) along the slice-wise direction.
+ This orientation is not encoded in the DICOM standard in a simple way;
+ DICOM is mostly concerned with 2D images. The third column of R will be
+ either the cross-product of the first 2 columns or its negative. It is
+ possible to infer the sign of the 3rd column by examining the coordinates
+ in DICOM attribute (0020,0032) "Image Position (Patient)" for successive
+ slices. However, this method occasionally fails for reasons that I
+ (RW Cox) do not understand.
+-----------------------------------------------------------------------------*/
+
+ /* [qs]form_code value: */ /* x,y,z coordinate system refers to: */
+ /*-----------------------*/ /*---------------------------------------*/
+
+/*! \defgroup NIFTI1_XFORM_CODES
+ \brief nifti1 xform codes to describe the "standard" coordinate system
+ @{
+ */
+ /*! Arbitrary coordinates (Method 1). */
+
+#define NIFTI_XFORM_UNKNOWN 0
+
+ /*! Scanner-based anatomical coordinates */
+
+#define NIFTI_XFORM_SCANNER_ANAT 1
+
+ /*! Coordinates aligned to another file's,
+ or to anatomical "truth". */
+
+#define NIFTI_XFORM_ALIGNED_ANAT 2
+
+ /*! Coordinates aligned to Talairach-
+ Tournoux Atlas; (0,0,0)=AC, etc. */
+
+#define NIFTI_XFORM_TALAIRACH 3
+
+ /*! MNI 152 normalized coordinates. */
+
+#define NIFTI_XFORM_MNI_152 4
+/* @} */
+
+/*---------------------------------------------------------------------------*/
+/* UNITS OF SPATIAL AND TEMPORAL DIMENSIONS:
+ ----------------------------------------
+ The codes below can be used in xyzt_units to indicate the units of pixdim.
+ As noted earlier, dimensions 1,2,3 are for x,y,z; dimension 4 is for
+ time (t).
+ - If dim[4]=1 or dim[0] < 4, there is no time axis.
+ - A single time series (no space) would be specified with
+ - dim[0] = 4 (for scalar data) or dim[0] = 5 (for vector data)
+ - dim[1] = dim[2] = dim[3] = 1
+ - dim[4] = number of time points
+ - pixdim[4] = time step
+ - xyzt_units indicates units of pixdim[4]
+ - dim[5] = number of values stored at each time point
+
+ Bits 0..2 of xyzt_units specify the units of pixdim[1..3]
+ (e.g., spatial units are values 1..7).
+ Bits 3..5 of xyzt_units specify the units of pixdim[4]
+ (e.g., temporal units are multiples of 8).
+
+ This compression of 2 distinct concepts into 1 byte is due to the
+ limited space available in the 348 byte ANALYZE 7.5 header. The
+ macros XYZT_TO_SPACE and XYZT_TO_TIME can be used to mask off the
+ undesired bits from the xyzt_units fields, leaving "pure" space
+ and time codes. Inversely, the macro SPACE_TIME_TO_XYZT can be
+ used to assemble a space code (0,1,2,...,7) with a time code
+ (0,8,16,32,...,56) into the combined value for xyzt_units.
+
+ Note that codes are provided to indicate the "time" axis units are
+ actually frequency in Hertz (_HZ), in part-per-million (_PPM)
+ or in radians-per-second (_RADS).
+
+ The toffset field can be used to indicate a nonzero start point for
+ the time axis. That is, time point #m is at t=toffset+m*pixdim[4]
+ for m=0..dim[4]-1.
+-----------------------------------------------------------------------------*/
+
+/*! \defgroup NIFTI1_UNITS
+ \brief nifti1 units codes to describe the unit of measurement for
+ each dimension of the dataset
+ @{
+ */
+ /*! NIFTI code for unspecified units. */
+#define NIFTI_UNITS_UNKNOWN 0
+
+ /** Space codes are multiples of 1. **/
+ /*! NIFTI code for meters. */
+#define NIFTI_UNITS_METER 1
+ /*! NIFTI code for millimeters. */
+#define NIFTI_UNITS_MM 2
+ /*! NIFTI code for micrometers. */
+#define NIFTI_UNITS_MICRON 3
+
+ /** Time codes are multiples of 8. **/
+ /*! NIFTI code for seconds. */
+#define NIFTI_UNITS_SEC 8
+ /*! NIFTI code for milliseconds. */
+#define NIFTI_UNITS_MSEC 16
+ /*! NIFTI code for microseconds. */
+#define NIFTI_UNITS_USEC 24
+
+ /*** These units are for spectral data: ***/
+ /*! NIFTI code for Hertz. */
+#define NIFTI_UNITS_HZ 32
+ /*! NIFTI code for ppm. */
+#define NIFTI_UNITS_PPM 40
+ /*! NIFTI code for radians per second. */
+#define NIFTI_UNITS_RADS 48
+/* @} */
+
+#undef XYZT_TO_SPACE
+#undef XYZT_TO_TIME
+#define XYZT_TO_SPACE(xyzt) ( (xyzt) & 0x07 )
+#define XYZT_TO_TIME(xyzt) ( (xyzt) & 0x38 )
+
+#undef SPACE_TIME_TO_XYZT
+#define SPACE_TIME_TO_XYZT(ss,tt) ( (((char)(ss)) & 0x07) \
+ | (((char)(tt)) & 0x38) )
+
+/*---------------------------------------------------------------------------*/
+/* MRI-SPECIFIC SPATIAL AND TEMPORAL INFORMATION:
+ ---------------------------------------------
+ A few fields are provided to store some extra information
+ that is sometimes important when storing the image data
+ from an FMRI time series experiment. (After processing such
+ data into statistical images, these fields are not likely
+ to be useful.)
+
+ { freq_dim } = These fields encode which spatial dimension (1,2, or 3)
+ { phase_dim } = corresponds to which acquisition dimension for MRI data.
+ { slice_dim } =
+ Examples:
+ Rectangular scan multi-slice EPI:
+ freq_dim = 1 phase_dim = 2 slice_dim = 3 (or some permutation)
+ Spiral scan multi-slice EPI:
+ freq_dim = phase_dim = 0 slice_dim = 3
+ since the concepts of frequency- and phase-encoding directions
+ don't apply to spiral scan
+
+ slice_duration = If this is positive, AND if slice_dim is nonzero,
+ indicates the amount of time used to acquire 1 slice.
+ slice_duration*dim[slice_dim] can be less than pixdim[4]
+ with a clustered acquisition method, for example.
+
+ slice_code = If this is nonzero, AND if slice_dim is nonzero, AND
+ if slice_duration is positive, indicates the timing
+ pattern of the slice acquisition. The following codes
+ are defined:
+ NIFTI_SLICE_SEQ_INC == sequential increasing
+ NIFTI_SLICE_SEQ_DEC == sequential decreasing
+ NIFTI_SLICE_ALT_INC == alternating increasing
+ NIFTI_SLICE_ALT_DEC == alternating decreasing
+ NIFTI_SLICE_ALT_INC2 == alternating increasing #2
+ NIFTI_SLICE_ALT_DEC2 == alternating decreasing #2
+ { slice_start } = Indicates the start and end of the slice acquisition
+ { slice_end } = pattern, when slice_code is nonzero. These values
+ are present to allow for the possible addition of
+ "padded" slices at either end of the volume, which
+ don't fit into the slice timing pattern. If there
+ are no padding slices, then slice_start=0 and
+ slice_end=dim[slice_dim]-1 are the correct values.
+ For these values to be meaningful, slice_start must
+ be non-negative and slice_end must be greater than
+ slice_start. Otherwise, they should be ignored.
+
+ The following table indicates the slice timing pattern, relative to
+ time=0 for the first slice acquired, for some sample cases. Here,
+ dim[slice_dim]=7 (there are 7 slices, labeled 0..6), slice_duration=0.1,
+ and slice_start=1, slice_end=5 (1 padded slice on each end).
+
+ slice
+ index SEQ_INC SEQ_DEC ALT_INC ALT_DEC ALT_INC2 ALT_DEC2
+ 6 : n/a n/a n/a n/a n/a n/a n/a = not applicable
+ 5 : 0.4 0.0 0.2 0.0 0.4 0.2 (slice time offset
+ 4 : 0.3 0.1 0.4 0.3 0.1 0.0 doesn't apply to
+ 3 : 0.2 0.2 0.1 0.1 0.3 0.3 slices outside
+ 2 : 0.1 0.3 0.3 0.4 0.0 0.1 the range
+ 1 : 0.0 0.4 0.0 0.2 0.2 0.4 slice_start ..
+ 0 : n/a n/a n/a n/a n/a n/a slice_end)
+
+ The SEQ slice_codes are sequential ordering (uncommon but not unknown),
+ either increasing in slice number or decreasing (INC or DEC), as
+ illustrated above.
+
+ The ALT slice codes are alternating ordering. The 'standard' way for
+ these to operate (without the '2' on the end) is for the slice timing
+ to start at the edge of the slice_start .. slice_end group (at slice_start
+ for INC and at slice_end for DEC). For the 'ALT_*2' slice_codes, the
+ slice timing instead starts at the first slice in from the edge (at
+ slice_start+1 for INC2 and at slice_end-1 for DEC2). This latter
+ acquisition scheme is found on some Siemens scanners.
+
+ The fields freq_dim, phase_dim, slice_dim are all squished into the single
+ byte field dim_info (2 bits each, since the values for each field are
+ limited to the range 0..3). This unpleasantness is due to lack of space
+ in the 348 byte allowance.
+
+ The macros DIM_INFO_TO_FREQ_DIM, DIM_INFO_TO_PHASE_DIM, and
+ DIM_INFO_TO_SLICE_DIM can be used to extract these values from the
+ dim_info byte.
+
+ The macro FPS_INTO_DIM_INFO can be used to put these 3 values
+ into the dim_info byte.
+-----------------------------------------------------------------------------*/
+
+#undef DIM_INFO_TO_FREQ_DIM
+#undef DIM_INFO_TO_PHASE_DIM
+#undef DIM_INFO_TO_SLICE_DIM
+
+#define DIM_INFO_TO_FREQ_DIM(di) ( ((di) ) & 0x03 )
+#define DIM_INFO_TO_PHASE_DIM(di) ( ((di) >> 2) & 0x03 )
+#define DIM_INFO_TO_SLICE_DIM(di) ( ((di) >> 4) & 0x03 )
+
+#undef FPS_INTO_DIM_INFO
+#define FPS_INTO_DIM_INFO(fd,pd,sd) ( ( ( ((char)(fd)) & 0x03) ) | \
+ ( ( ((char)(pd)) & 0x03) << 2 ) | \
+ ( ( ((char)(sd)) & 0x03) << 4 ) )
+
+/*! \defgroup NIFTI1_SLICE_ORDER
+ \brief nifti1 slice order codes, describing the acquisition order
+ of the slices
+ @{
+ */
+#define NIFTI_SLICE_UNKNOWN 0
+#define NIFTI_SLICE_SEQ_INC 1
+#define NIFTI_SLICE_SEQ_DEC 2
+#define NIFTI_SLICE_ALT_INC 3
+#define NIFTI_SLICE_ALT_DEC 4
+#define NIFTI_SLICE_ALT_INC2 5 /* 05 May 2005: RWCox */
+#define NIFTI_SLICE_ALT_DEC2 6 /* 05 May 2005: RWCox */
+/* @} */
+
+/*---------------------------------------------------------------------------*/
+/* UNUSED FIELDS:
+ -------------
+ Some of the ANALYZE 7.5 fields marked as ++UNUSED++ may need to be set
+ to particular values for compatibility with other programs. The issue
+ of interoperability of ANALYZE 7.5 files is a murky one -- not all
+ programs require exactly the same set of fields. (Unobscuring this
+ murkiness is a principal motivation behind NIFTI-1.)
+
+ Some of the fields that may need to be set for other (non-NIFTI aware)
+ software to be happy are:
+
+ extents dbh.h says this should be 16384
+ regular dbh.h says this should be the character 'r'
+ glmin, } dbh.h says these values should be the min and max voxel
+ glmax } values for the entire dataset
+
+ It is best to initialize ALL fields in the NIFTI-1 header to 0
+ (e.g., with calloc()), then fill in what is needed.
+-----------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+/* MISCELLANEOUS C MACROS
+-----------------------------------------------------------------------------*/
+
+/*.................*/
+/*! Given a nifti_1_header struct, check if it has a good magic number.
+ Returns NIFTI version number (1..9) if magic is good, 0 if it is not. */
+
+#define NIFTI_VERSION(h) \
+ ( ( (h).magic[0]=='n' && (h).magic[3]=='\0' && \
+ ( (h).magic[1]=='i' || (h).magic[1]=='+' ) && \
+ ( (h).magic[2]>='1' && (h).magic[2]<='9' ) ) \
+ ? (h).magic[2]-'0' : 0 )
+
+/*.................*/
+/*! Check if a nifti_1_header struct says if the data is stored in the
+ same file or in a separate file. Returns 1 if the data is in the same
+ file as the header, 0 if it is not. */
+
+#define NIFTI_ONEFILE(h) ( (h).magic[1] == '+' )
+
+/*.................*/
+/*! Check if a nifti_1_header struct needs to be byte swapped.
+ Returns 1 if it needs to be swapped, 0 if it does not. */
+
+#define NIFTI_NEEDS_SWAP(h) ( (h).dim[0] < 0 || (h).dim[0] > 7 )
+
+/*.................*/
+/*! Check if a nifti_1_header struct contains a 5th (vector) dimension.
+ Returns size of 5th dimension if > 1, returns 0 otherwise. */
+
+#define NIFTI_5TH_DIM(h) ( ((h).dim[0]>4 && (h).dim[5]>1) ? (h).dim[5] : 0 )
+
+/*****************************************************************************/
+
+/*=================*/
+#ifdef __cplusplus
+}
+#endif
+/*=================*/
+
+#endif /* _NIFTI_HEADER_ */
diff --git a/src/nifti1_io.c b/src/nifti1_io.c
new file mode 100644
index 0000000..17a3eb6
--- /dev/null
+++ b/src/nifti1_io.c
@@ -0,0 +1,7569 @@
+#define _NIFTI1_IO_C_
+
+#include "nifti1_io.h" /* typedefs, prototypes, macros, etc. */
+#include <R.h>
+/*****===================================================================*****/
+/***** Sample functions to deal with NIFTI-1 and ANALYZE files *****/
+/*****...................................................................*****/
+/***** This code is released to the public domain. *****/
+/*****...................................................................*****/
+/***** Author: Robert W Cox, SSCC/DIRP/NIMH/NIH/DHHS/USA/EARTH *****/
+/***** Date: August 2003 *****/
+/*****...................................................................*****/
+/***** Neither the National Institutes of Health (NIH), nor any of its *****/
+/***** employees imply any warranty of usefulness of this software for *****/
+/***** any purpose, and do not assume any liability for damages, *****/
+/***** incidental or otherwise, caused by any use of this document. *****/
+/*****===================================================================*****/
+
+/** \file nifti1_io.c
+ \brief main collection of nifti1 i/o routines
+ - written by Bob Cox, SSCC NIMH
+ - revised by Mark Jenkinson, FMRIB
+ - revised by Rick Reynolds, SSCC, NIMH
+ - revised by Kate Fissell, University of Pittsburgh
+
+ The library history can be viewed via "nifti_tool -nifti_hist".
+ <br>The library version can be viewed via "nifti_tool -nifti_ver".
+ */
+
+/* changes by Oliver Granert:
+- change HAVE_ZLIB to HAVE_LIBZ to fit autoconf tests
+*/
+
+/*! global history and version strings, for printing */
+static char * gni_history[] =
+{
+ "----------------------------------------------------------------------\n"
+ "history (of nifti library changes):\n"
+ "\n",
+ "0.0 August, 2003 [rwcox]\n"
+ " (Robert W Cox of the National Institutes of Health, SSCC/DIRP/NIMH)\n"
+ " - initial version\n"
+ "\n",
+ "0.1 July/August, 2004 [Mark Jenkinson]\n"
+ " (FMRIB Centre, University of Oxford, UK)\n"
+ " - Mainly adding low-level IO and changing things to allow gzipped\n"
+ " files to be read and written\n"
+ " - Full backwards compatability should have been maintained\n"
+ "\n",
+ "0.2 16 Nov 2004 [rickr]\n"
+ " (Rick Reynolds of the National Institutes of Health, SSCC/DIRP/NIMH)\n"
+ " - included Mark's changes in the AFNI distribution (including znzlib/)\n"
+ " (HAVE_LIBZ is commented out for the standard distribution)\n"
+ " - modified nifti_validfilename() and nifti_makebasename()\n"
+ " - added nifti_find_file_extension()\n"
+ "\n",
+ "0.3 3 Dec 2004 [rickr]\n"
+ " - note: header extensions are not yet checked for\n"
+ " - added formatted history as global string, for printing\n"
+ " - added nifti_disp_lib_hist(), to display the nifti library history\n"
+ " - added nifti_disp_lib_version(), to display the nifti library history\n",
+ " - re-wrote nifti_findhdrname()\n"
+ " o used nifti_find_file_extension()\n"
+ " o changed order of file tests (default is .nii, depends on input)\n"
+ " o free hdrname on failure\n"
+ " - made similar changes to nifti_findimgname()\n"
+ " - check for NULL return from nifti_findhdrname() calls\n",
+ " - removed most of ERREX() macros\n"
+ " - modified nifti_image_read()\n"
+ " o added debug info and error checking (on gni_debug > 0, only)\n"
+ " o fail if workingname is NULL\n"
+ " o check for failure to open header file\n"
+ " o free workingname on failure\n"
+ " o check for failure of nifti_image_load()\n"
+ " o check for failure of nifti_convert_nhdr2nim()\n",
+ " - changed nifti_image_load() to int, and check nifti_read_buffer return\n"
+ " - changed nifti_read_buffer() to fail on short read, and to count float\n"
+ " fixes (to print on debug)\n"
+ " - changed nifti_image_infodump to print to stderr\n"
+ " - updated function header comments, or moved comments above header\n"
+ " - removed const keyword\n"
+ " - added LNI_FERR() macro for error reporting on input files\n"
+ "\n",
+ "0.4 10 Dec 2004 [rickr] - added header extensions\n"
+ " - in nifti1_io.h:\n"
+ " o added num_ext and ext_list to the definition of nifti_image\n"
+ " o made many functions static (more to follow)\n"
+ " o added LNI_MAX_NIA_EXT_LEN, for max nifti_type 3 extension length\n",
+ " - added __DATE__ to version output in nifti_disp_lib_version()\n"
+ " - added nifti_disp_matrix_orient() to print orientation information\n"
+ " - added '.nia' as a valid file extension in nifti_find_file_extension()\n"
+ " - added much more debug output\n"
+ " - in nifti_image_read(), in the case of an ASCII header, check for\n"
+ " extensions after the end of the header\n",
+ " - added nifti_read_extensions() function\n"
+ " - added nifti_read_next_extension() function\n"
+ " - added nifti_add_exten_to_list() function\n"
+ " - added nifti_check_extension() function\n"
+ " - added nifti_write_extensions() function\n"
+ " - added nifti_extension_size() function\n"
+ " - in nifti_set_iname_offest():\n"
+ " o adjust offset by the extension size and the extender size\n",
+ " o fixed the 'ceiling modulo 16' computation\n"
+ " - in nifti_image_write_hdr_img2(): \n"
+ " o added extension writing\n"
+ " o check for NULL return from nifti_findimgname()\n"
+ " - include number of extensions in nifti_image_to_ascii() output\n"
+ " - in nifti_image_from_ascii():\n"
+ " o return bytes_read as a parameter, computed from the final spos\n"
+ " o extract num_ext from ASCII header\n"
+ "\n",
+ "0.5 14 Dec 2004 [rickr] - added sub-brick reading functions\n"
+ " - added nifti_brick_list type to nifti1_io.h, along with new prototypes\n"
+ " - added main nifti_image_read_bricks() function, with description\n"
+ " - added nifti_image_load_bricks() - library function (requires nim)\n"
+ " - added valid_nifti_brick_list() - library function\n"
+ " - added free_NBL() - library function\n",
+ " - added update_nifti_image_for_brick_list() for dimension update\n"
+ " - added nifti_load_NBL_bricks(), nifti_alloc_NBL_mem(),\n"
+ " nifti_copynsort() and force_positive() (static functions)\n"
+ " - in nifti_image_read(), check for failed load only if read_data is set\n"
+ " - broke most of nifti_image_load() into nifti_image_load_prep()\n"
+ "\n",
+ "0.6 15 Dec 2004 [rickr] - added sub-brick writing functionality\n"
+ " - in nifti1_io.h, removed znzlib directory from include - all nifti\n"
+ " library files are now under the nifti directory\n"
+ " - nifti_read_extensions(): print no offset warning for nifti_type 3\n"
+ " - nifti_write_all_data():\n"
+ " o pass nifti_brick_list * NBL, for optional writing\n"
+ " o if NBL, write each sub-brick, sequentially\n",
+ " - nifti_set_iname_offset(): case 1 must have sizeof() cast to int\n"
+ " - pass NBL to nifti_image_write_hdr_img2(), and allow NBL or data\n"
+ " - added nifti_image_write_bricks() wrapper for ...write_hdr_img2()\n"
+ " - included compression abilities\n"
+ "\n",
+ "0.7 16 Dec 2004 [rickr] - minor changes to extension reading\n"
+ "\n",
+ "0.8 21 Dec 2004 [rickr] - restrict extension reading, and minor changes\n"
+ " - in nifti_image_read(), compute bytes for extensions (see remaining)\n"
+ " - in nifti_read_extensions(), pass 'remain' as space for extensions,\n"
+ " pass it to nifti_read_next_ext(), and update for each one read \n"
+ " - in nifti_check_extension(), require (size <= remain)\n",
+ " - in update_nifti_image_brick_list(), update nvox\n"
+ " - in nifti_image_load_bricks(), make explicit check for nbricks <= 0\n"
+ " - in int_force_positive(), check for (!list)\n"
+ " - in swap_nifti_header(), swap sizeof_hdr, and reorder to struct order\n"
+ " - change get_filesize functions to signed ( < 0 is no file or error )\n",
+ " - in nifti_validfilename(), lose redundant (len < 0) check\n"
+ " - make print_hex_vals() static\n"
+ " - in disp_nifti_1_header, restrict string field widths\n"
+ "\n",
+ "0.9 23 Dec 2004 [rickr] - minor changes\n"
+ " - broke ASCII header reading out of nifti_image_read(), into new\n"
+ " functions has_ascii_header() and read_ascii_image()\n",
+ " - check image_read failure and znzseek failure\n"
+ " - altered some debug output\n"
+ " - nifti_write_all_data() now returns an int\n"
+ "\n",
+ "0.10 29 Dec 2004 [rickr]\n"
+ " - renamed nifti_valid_extension() to nifti_check_extension()\n"
+ " - added functions nifti_makehdrname() and nifti_makeimgname()\n"
+ " - added function valid_nifti_extensions()\n"
+ " - in nifti_write_extensions(), check for validity before writing\n",
+ " - rewrote nifti_image_write_hdr_img2():\n"
+ " o set write_data and leave_open flags from write_opts\n"
+ " o add debug print statements\n"
+ " o use nifti_write_ascii_image() for the ascii case\n"
+ " o rewrote the logic of all cases to be easier to follow\n",
+ " - broke out code as nifti_write_ascii_image() function\n"
+ " - added debug to top-level write functions, and free the znzFile\n"
+ " - removed unused internal function nifti_image_open()\n"
+ "\n",
+ "0.11 30 Dec 2004 [rickr] - small mods\n"
+ " - moved static function prototypes from header to C file\n"
+ " - free extensions in nifti_image_free()\n"
+ "\n",
+ "1.0 07 Jan 2005 [rickr] - INITIAL RELEASE VERSION\n"
+ " - added function nifti_set_filenames()\n"
+ " - added function nifti_read_header()\n"
+ " - added static function nhdr_looks_good()\n"
+ " - added static function need_nhdr_swap()\n"
+ " - exported nifti_add_exten_to_list symbol\n",
+ " - fixed #bytes written in nifti_write_extensions()\n"
+ " - only modify offset if it is too small (nifti_set_iname_offset)\n"
+ " - added nifti_type 3 to nifti_makehdrname and nifti_makeimgname\n"
+ " - added function nifti_set_filenames()\n"
+ "\n",
+ "1.1 07 Jan 2005 [rickr]\n"
+ " - in nifti_read_header(), swap if needed\n"
+ "\n",
+ "1.2 07 Feb 2005 [kate fissell c/o rickr] \n"
+ " - nifti1.h: added doxygen comments for main struct and #define groups\n"
+ " - nifti1_io.h: added doxygen comments for file and nifti_image struct\n"
+ " - nifti1_io.h: added doxygen comments for file and some functions\n"
+ " - nifti1_io.c: changed nifti_copy_nim_info to use memcpy\n"
+ "\n",
+ "1.3 09 Feb 2005 [rickr]\n"
+ " - nifti1.h: added doxygen comments for extension structs\n"
+ " - nifti1_io.h: put most #defines in #ifdef _NIFTI1_IO_C_ block\n"
+ " - added a doxygen-style description to every exported function\n"
+ " - added doxygen-style comments within some functions\n"
+ " - re-exported many znzFile functions that I had made static\n"
+ " - re-added nifti_image_open (sorry, Mark)\n"
+ " - every exported function now has 'nifti' in the name (19 functions)\n",
+ " - made sure every alloc() has a failure test\n"
+ " - added nifti_copy_extensions function, for use in nifti_copy_nim_info\n"
+ " - nifti_is_gzfile: added initial strlen test\n"
+ " - nifti_set_filenames: added set_byte_order parameter option\n"
+ " (it seems appropriate to set the BO when new files are associated)\n"
+ " - disp_nifti_1_header: prints to stdout (a.o.t. stderr), with fflush\n"
+ "\n",
+ "1.4 23 Feb 2005 [rickr] - sourceforge merge\n"
+ " - merged into the nifti_io CVS directory structure at sourceforge.net\n"
+ " - merged in 4 changes by Mark, and re-added his const keywords\n"
+ " - cast some pointers to (void *) for -pedantic compile option\n"
+ " - added nifti_free_extensions()\n"
+ "\n",
+ "1.5 02 Mar 2005 [rickr] - started nifti global options\n"
+ " - gni_debug is now g_opts.debug\n"
+ " - added validity check parameter to nifti_read_header\n"
+ " - need_nhdr_swap no longer does test swaps on the stack\n"
+ "\n",
+ "1.6 05 April 2005 [rickr] - validation and collapsed_image_read\n"
+ " - added nifti_read_collapsed_image(), an interface for reading partial\n"
+ " datasets, specifying a subset of array indices\n"
+ " - for read_collapsed_image, added static functions: rci_read_data(),\n"
+ " rci_alloc_mem(), and make_pivot_list()\n",
+ " - added nifti_nim_is_valid() to check for consistency (more to do)\n"
+ " - added nifti_nim_has_valid_dims() to do many dimensions tests\n"
+ "\n",
+ "1.7 08 April 2005 [rickr]\n"
+ " - added nifti_update_dims_from_array() - to update dimensions\n"
+ " - modified nifti_makehdrname() and nifti_makeimgname():\n"
+ " if prefix has a valid extension, use it (else make one up)\n"
+ " - added nifti_get_intlist - for making an array of ints\n"
+ " - fixed init of NBL->bsize in nifti_alloc_NBL_mem() {thanks, Bob}\n"
+ "\n",
+ "1.8 14 April 2005 [rickr]\n"
+ " - added nifti_set_type_from_names(), for nifti_set_filenames()\n"
+ " (only updates type if number of files does not match it)\n"
+ " - added is_valid_nifti_type(), just to be sure\n"
+ " - updated description of nifti_read_collapsed_image() for *data change\n"
+ " (if *data is already set, assume memory exists for results)\n"
+ " - modified rci_alloc_mem() to allocate only if *data is NULL\n"
+ "\n",
+ "1.9 19 April 2005 [rickr]\n"
+ " - added extension codes NIFTI_ECODE_COMMENT and NIFTI_ECODE_XCEDE\n"
+ " - added nifti_type codes NIFTI_MAX_ECODE and NIFTI_MAX_FTYPE\n"
+ " - added nifti_add_extension() {exported}\n"
+ " - added nifti_fill_extension() as a static function\n"
+ " - added nifti_is_valid_ecode() {exported}\n",
+ " - nifti_type values are now NIFTI_FTYPE_* file codes\n"
+ " - in nifti_read_extensions(), decrement 'remain' by extender size, 4\n"
+ " - in nifti_set_iname_offset(), case 1, update if offset differs\n"
+ " - only output '-d writing nifti file' if debug > 1\n"
+ "\n",
+ "1.10 10 May 2005 [rickr]\n"
+ " - files are read using ZLIB only if they end in '.gz'\n"
+ "\n",
+ "1.11 12 August 2005 [kate fissell]\n"
+ " - Kate's 0.2 release packaging, for sourceforge\n"
+ "\n",
+ "1.12 17 August 2005 [rickr] - comment (doxygen) updates\n"
+ " - updated comments for most functions (2 updates from Cinly Ooi)\n"
+ " - added nifti_type_and_names_match()\n"
+ "\n",
+ "1.12a 24 August 2005 [rickr] - remove all tabs from Clibs/*/*.[ch]\n",
+ "1.12b 25 August 2005 [rickr] - changes by Hans Johnson\n",
+ "1.13 25 August 2005 [rickr]\n",
+ " - finished changes by Hans for Insight\n"
+ " - added const in all appropraite parameter locations (30-40)\n"
+ " (any pointer referencing data that will not change)\n"
+ " - shortened all string constants below 509 character limit\n"
+ "1.14 28 October 2005 [HJohnson]\n",
+ " - use nifti_set_filenames() in nifti_convert_nhdr2nim()\n"
+ "1.15 02 November 2005 [rickr]\n",
+ " - added skip_blank_ext to nifti_global_options\n"
+ " - added nifti_set_skip_blank_ext(), to set option\n"
+ " - if skip_blank_ext and no extensions, do not read/write extender\n"
+ "1.16 18 November 2005 [rickr]\n",
+ " - removed any test or access of dim[i], i>dim[0]\n"
+ " - do not set pixdim for collapsed dims to 1.0, leave them as they are\n"
+ " - added magic and dim[i] tests in nifti_hdr_looks_good()\n"
+ " - added 2 size_t casts\n"
+ "1.17 22 November 2005 [rickr]\n",
+ " - in hdr->nim, for i > dim[0], pass 0 or 1, else set to 1\n"
+ "1.18 02 March 2006 [rickr]\n",
+ " - in nifti_alloc_NBL_mem(), fixed nt=0 case from 1.17 change\n"
+ "1.19 23 May 2006 [HJohnson,rickr]\n",
+ " - nifti_write_ascii_image(): free(hstr)\n"
+ " - nifti_copy_extensions(): clear num_ext and ext_list\n"
+ "1.20 27 Jun 2006 [rickr]\n",
+ " - nifti_findhdrname(): fixed assign of efirst to match stated logic\n"
+ " (problem found by Atle Bjørnerud)\n"
+ "1.21 05 Sep 2006 [rickr] update for nifticlib-0.4 release\n",
+ " - was reminded to actually add nifti_set_skip_blank_ext()\n"
+ " - init g_opts.skip_blank_ext to 0\n"
+ "1.22 01 Jun 2007 nifticlib-0.5 release\n",
+ "1.23 05 Jun 2007 nifti_add_exten_to_list: revert on failure, free old list\n"
+ "1.24 07 Jun 2007 nifti_copy_extensions: use esize-8 for data size\n"
+ "1.25 12 Jun 2007 [rickr] EMPTY_IMAGE creation\n",
+ " - added nifti_make_new_header() - to create from dims/dtype\n"
+ " - added nifti_make_new_nim() - to create from dims/dtype/fill\n"
+ " - added nifti_is_valid_datatype(), and more debug info\n",
+ "1.26 27 Jul 2007 [rickr] handle single volumes > 2^31 bytes (but < 2^32)\n",
+ "1.27 28 Jul 2007 [rickr] nim->nvox, NBL-bsize are now type size_t\n"
+ "1.28 30 Jul 2007 [rickr] size_t updates\n",
+ "1.29 08 Aug 2007 [rickr] for list, valid_nifti_brick_list requires 3 dims\n"
+ "1.30 08 Nov 2007 [Yaroslav/rickr]\n"
+ " - fix ARM struct alignment problem in byte-swapping routines\n",
+ "1.31 29 Nov 2007 [rickr] for nifticlib-1.0.0\n"
+ " - added nifti_datatype_to/from_string routines\n"
+ " - added DT_RGBA32/NIFTI_TYPE_RGBA32 datatype macros (2304)\n"
+ " - added NIFTI_ECODE_FREESURFER (14)\n",
+ "1.32 08 Dec 2007 [rickr]\n"
+ " - nifti_hdr_looks_good() allows ANALYZE headers (req. by V. Luccio)\n"
+ " - added nifti_datatype_is_valid()\n",
+ "1.33 05 Feb 2008 [hansj,rickr] - block nia.gz use\n"
+ "1.34 13 Jun 2008 [rickr] - added nifti_compiled_with_zlib()\n"
+ "1.35 03 Aug 2008 [rickr]\n",
+ " - deal with swapping, so that CPU type does not affect output\n"
+ " (motivated by C Burns)\n"
+ " - added nifti_analyze75 structure and nifti_swap_as_analyze()\n"
+ " - previous swap_nifti_header is saved as old_swap_nifti_header\n"
+ " - also swap UNUSED fields in nifti_1_header struct\n",
+ "1.36 07 Oct 2008 [rickr]\n",
+ " - added nifti_NBL_matches_nim() check for write_bricks()\n"
+ "1.37 10 Mar 2009 [rickr]\n",
+ " - H Johnson cast updates (06 Feb)\n"
+ " - added NIFTI_ECODE_PYPICKLE for PyNIfTI (06 Feb)\n"
+ " - added NIFTI_ECODEs 18-28 for the LONI MiND group\n"
+ "1.38 28 Apr 2009 [rickr]\n",
+ " - uppercase extensions are now valid (requested by M. Coursolle)\n"
+ " - nifti_set_allow_upper_fext controls this option (req by C. Ooi)\n"
+ "1.39 23 Jun 2009 [rickr]: added 4 checks of alloc() returns\n",
+ "1.40 16 Mar 2010 [rickr]: added NIFTI_ECODE_VOXBO for D. Kimberg\n",
+ "1.41 28 Apr 2010 [rickr]: added NIFTI_ECODE_CARET for J. Harwell\n",
+ "1.42 06 Jul 2010 [rickr]: trouble with large (gz) files\n",
+ " - noted/investigated by M Hanke and Y Halchenko\n"
+ " - fixed znzread/write, noting example by M Adler\n"
+ " - changed nifti_swap_* routines/calls to take size_t (6)\n"
+ "1.43 07 Jul 2010 [rickr]: fixed znzR/W to again return nmembers\n",
+ "1.43r 09 Jan 2013 [oliverg]: replace outputs to stdout and stderr by \n",
+ " Rprintf and REprintf\n",
+ "----------------------------------------------------------------------\n"
+};
+static char gni_version[] = "nifti library version 1.43r (9 Jan, 2013)";
+
+/*! global nifti options structure - init with defaults */
+static nifti_global_options g_opts = {
+ 1, /* debug level */
+ 0, /* skip_blank_ext - skip extender if no extensions */
+ 1 /* allow_upper_fext - allow uppercase file extensions */
+};
+
+/*! global nifti types structure list (per type, ordered oldest to newest) */
+static nifti_type_ele nifti_type_list[] = {
+ /* type nbyper swapsize name */
+ { 0, 0, 0, "DT_UNKNOWN" },
+ { 0, 0, 0, "DT_NONE" },
+ { 1, 0, 0, "DT_BINARY" }, /* not usable */
+ { 2, 1, 0, "DT_UNSIGNED_CHAR" },
+ { 2, 1, 0, "DT_UINT8" },
+ { 2, 1, 0, "NIFTI_TYPE_UINT8" },
+ { 4, 2, 2, "DT_SIGNED_SHORT" },
+ { 4, 2, 2, "DT_INT16" },
+ { 4, 2, 2, "NIFTI_TYPE_INT16" },
+ { 8, 4, 4, "DT_SIGNED_INT" },
+ { 8, 4, 4, "DT_INT32" },
+ { 8, 4, 4, "NIFTI_TYPE_INT32" },
+ { 16, 4, 4, "DT_FLOAT" },
+ { 16, 4, 4, "DT_FLOAT32" },
+ { 16, 4, 4, "NIFTI_TYPE_FLOAT32" },
+ { 32, 8, 4, "DT_COMPLEX" },
+ { 32, 8, 4, "DT_COMPLEX64" },
+ { 32, 8, 4, "NIFTI_TYPE_COMPLEX64" },
+ { 64, 8, 8, "DT_DOUBLE" },
+ { 64, 8, 8, "DT_FLOAT64" },
+ { 64, 8, 8, "NIFTI_TYPE_FLOAT64" },
+ { 128, 3, 0, "DT_RGB" },
+ { 128, 3, 0, "DT_RGB24" },
+ { 128, 3, 0, "NIFTI_TYPE_RGB24" },
+ { 255, 0, 0, "DT_ALL" },
+ { 256, 1, 0, "DT_INT8" },
+ { 256, 1, 0, "NIFTI_TYPE_INT8" },
+ { 512, 2, 2, "DT_UINT16" },
+ { 512, 2, 2, "NIFTI_TYPE_UINT16" },
+ { 768, 4, 4, "DT_UINT32" },
+ { 768, 4, 4, "NIFTI_TYPE_UINT32" },
+ { 1024, 8, 8, "DT_INT64" },
+ { 1024, 8, 8, "NIFTI_TYPE_INT64" },
+ { 1280, 8, 8, "DT_UINT64" },
+ { 1280, 8, 8, "NIFTI_TYPE_UINT64" },
+ { 1536, 16, 16, "DT_FLOAT128" },
+ { 1536, 16, 16, "NIFTI_TYPE_FLOAT128" },
+ { 1792, 16, 8, "DT_COMPLEX128" },
+ { 1792, 16, 8, "NIFTI_TYPE_COMPLEX128" },
+ { 2048, 32, 16, "DT_COMPLEX256" },
+ { 2048, 32, 16, "NIFTI_TYPE_COMPLEX256" },
+ { 2304, 4, 0, "DT_RGBA32" },
+ { 2304, 4, 0, "NIFTI_TYPE_RGBA32" },
+};
+
+/*---------------------------------------------------------------------------*/
+/* prototypes for internal functions - not part of exported library */
+
+/* extension routines */
+static int nifti_read_extensions( nifti_image *nim, znzFile fp, int remain );
+static int nifti_read_next_extension( nifti1_extension * nex, nifti_image *nim, int remain, znzFile fp );
+static int nifti_check_extension(nifti_image *nim, int size,int code, int rem);
+static void update_nifti_image_for_brick_list(nifti_image * nim , int nbricks);
+static int nifti_add_exten_to_list(nifti1_extension * new_ext,
+ nifti1_extension ** list, int new_length);
+static int nifti_fill_extension(nifti1_extension * ext, const char * data,
+ int len, int ecode);
+
+/* NBL routines */
+static int nifti_load_NBL_bricks(nifti_image * nim , int * slist, int * sindex, nifti_brick_list * NBL, znzFile fp );
+static int nifti_alloc_NBL_mem( nifti_image * nim, int nbricks,
+ nifti_brick_list * nbl);
+static int nifti_copynsort(int nbricks, const int *blist, int **slist,
+ int **sindex);
+static int nifti_NBL_matches_nim(const nifti_image *nim,
+ const nifti_brick_list *NBL);
+
+/* for nifti_read_collapsed_image: */
+static int rci_read_data(nifti_image *nim, int *pivots, int *prods, int nprods,
+ const int dims[], char *data, znzFile fp, size_t base_offset);
+static int rci_alloc_mem(void ** data, int prods[8], int nprods, int nbyper );
+static int make_pivot_list(nifti_image * nim, const int dims[], int pivots[],
+ int prods[], int * nprods );
+
+/* misc */
+static int compare_strlist (const char * str, char ** strlist, int len);
+static int fileext_compare (const char * test_ext, const char * known_ext);
+static int fileext_n_compare (const char * test_ext,
+ const char * known_ext, int maxlen);
+static int is_mixedcase (const char * str);
+static int is_uppercase (const char * str);
+static int make_lowercase (char * str);
+static int make_uppercase (char * str);
+static int need_nhdr_swap (short dim0, int hdrsize);
+static int print_hex_vals (const char * data, int nbytes/*, FILE * fp*/);
+static int unescape_string (char *str); /* string utility functions */
+static char *escapize_string (const char *str);
+
+/* internal I/O routines */
+static znzFile nifti_image_load_prep( nifti_image *nim );
+static int has_ascii_header(znzFile fp);
+/*---------------------------------------------------------------------------*/
+
+
+/* for calling from some main program */
+
+/*----------------------------------------------------------------------*/
+/*! display the nifti library module history (via stdout)
+*//*--------------------------------------------------------------------*/
+void nifti_disp_lib_hist( void )
+{
+ int c, len = sizeof(gni_history)/sizeof(char *);
+ for( c = 0; c < len; c++ )
+ Rprintf(gni_history[c]);
+}
+
+/*----------------------------------------------------------------------*/
+/*! display the nifti library version (via stdout)
+*//*--------------------------------------------------------------------*/
+/* replaced for use in R by function "const char *nifti_lib_version( void )"
+void nifti_disp_lib_version( void )
+{
+ printf("%s, compiled %s\n", gni_version, __DATE__);
+}*/
+
+/*----------------------------------------------------------------------*/
+/*! return the nifti library version (via constant string)
+*//*--------------------------------------------------------------------*/
+const char *nifti_lib_version( void )
+{
+ return gni_version;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! nifti_image_read_bricks - read nifti data as array of bricks
+ *
+ * 13 Dec 2004 [rickr]
+ *
+ * \param hname - filename of dataset to read (must be valid)
+ * \param nbricks - number of sub-bricks to read
+ * (if blist is valid, nbricks must be > 0)
+ * \param blist - list of sub-bricks to read
+ * (can be NULL; if NULL, read complete dataset)
+ * \param NBL - pointer to empty nifti_brick_list struct
+ * (must be a valid pointer)
+ *
+ * \return
+ * <br> nim - same as nifti_image_read, but
+ * nim->nt = NBL->nbricks (or nt*nu*nv*nw)
+ * nim->nu,nv,nw = 1
+ * nim->data = NULL
+ * <br> NBL - filled with data volumes
+ *
+ * By default, this function will read the nifti dataset and break the data
+ * into a list of nt*nu*nv*nw sub-bricks, each having size nx*ny*nz elements.
+ * That is to say, instead of reading the entire dataset as a single array,
+ * break it up into sub-bricks (volumes), each of size nx*ny*nz elements.
+ *
+ * Note: in the returned nifti_image, nu, nv and nw will always be 1. The
+ * intention of this function is to collapse the dataset into a single
+ * array of volumes (of length nbricks or nt*nu*nv*nw).
+ *
+ * If 'blist' is valid, it is taken to be a list of sub-bricks, of length
+ * 'nbricks'. The data will still be separated into sub-bricks of size
+ * nx*ny*nz elements, but now 'nbricks' sub-bricks will be returned, of the
+ * caller's choosing via 'blist'.
+ *
+ * E.g. consider a dataset with 12 sub-bricks (numbered 0..11), and the
+ * following code:
+ *
+ * <pre>
+ * { nifti_brick_list NB_orig, NB_select;
+ * nifti_image * nim_orig, * nim_select;
+ * int blist[5] = { 7, 0, 5, 5, 9 };
+ *
+ * nim_orig = nifti_image_read_bricks("myfile.nii", 0, NULL, &NB_orig);
+ * nim_select = nifti_image_read_bricks("myfile.nii", 5, blist, &NB_select);
+ * }
+ * </pre>
+ *
+ * Here, nim_orig gets the entire dataset, where NB_orig.nbricks = 12. But
+ * nim_select has NB_select.nbricks = 5.
+ *
+ * Note that the first case is not quite the same as just calling the
+ * nifti_image_read function, as here the data is separated into sub-bricks.
+ *
+ * Note that valid blist elements are in [0..nt*nu*nv*nw-1],
+ * or written [ 0 .. (dim[4]*dim[5]*dim[6]*dim[7] - 1) ].
+ *
+ * Note that, as is the case with all of the reading functions, the
+ * data will be allocated, read in, and properly byte-swapped, if
+ * necessary.
+ *
+ * \sa nifti_image_load_bricks, nifti_free_NBL, valid_nifti_brick_list,
+ nifti_image_read
+*//*----------------------------------------------------------------------*/
+nifti_image *nifti_image_read_bricks(const char * hname, int nbricks,
+ const int * blist, nifti_brick_list * NBL)
+{
+ nifti_image * nim;
+
+ if( !hname || !NBL ){
+ REprintf("** nifti_image_read_bricks: bad params (%p,%p)\n",
+ hname, (void *)NBL);
+ return NULL;
+ }
+
+ if( blist && nbricks <= 0 ){
+ REprintf("** nifti_image_read_bricks: bad nbricks, %d\n", nbricks);
+ return NULL;
+ }
+
+ nim = nifti_image_read(hname, 0); /* read header, but not data */
+
+ if( !nim ) return NULL; /* errors were already printed */
+
+ /* if we fail, free image and return */
+ if( nifti_image_load_bricks(nim, nbricks, blist, NBL) <= 0 ){
+ nifti_image_free(nim);
+ return NULL;
+ }
+
+ if( blist ) update_nifti_image_for_brick_list(nim, nbricks);
+
+ return nim;
+}
+
+
+/*----------------------------------------------------------------------
+ * update_nifti_image_for_brick_list - update nifti_image
+ *
+ * When loading a specific brick list, the distinction between
+ * nt, nu, nv and nw is lost. So put everything in t, and set
+ * dim[0] = 4.
+ *----------------------------------------------------------------------*/
+static void update_nifti_image_for_brick_list( nifti_image * nim , int nbricks )
+{
+ int ndim;
+
+ if( g_opts.debug > 2 ){
+ REprintf("+d updating image dimensions for %d bricks in list\n",
+ nbricks);
+ REprintf(" ndim = %d\n",nim->ndim);
+ REprintf(" nx,ny,nz,nt,nu,nv,nw: (%d,%d,%d,%d,%d,%d,%d)\n",
+ nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw);
+ }
+
+ nim->nt = nbricks;
+ nim->nu = nim->nv = nim->nw = 1;
+ nim->dim[4] = nbricks;
+ nim->dim[5] = nim->dim[6] = nim->dim[7] = 1;
+
+ /* compute nvox */
+ /* do not rely on dimensions above dim[0] 16 Nov 2005 [rickr] */
+ for( nim->nvox = 1, ndim = 1; ndim <= nim->dim[0]; ndim++ )
+ nim->nvox *= nim->dim[ndim];
+
+ /* update the dimensions to 4 or lower */
+ for( ndim = 4; (ndim > 1) && (nim->dim[ndim] <= 1); ndim-- )
+ ;
+
+ if( g_opts.debug > 2 ){
+ REprintf("+d ndim = %d -> %d\n",nim->ndim, ndim);
+ REprintf(" --> (%d,%d,%d,%d,%d,%d,%d)\n",
+ nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw);
+ }
+
+ nim->dim[0] = nim->ndim = ndim;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! nifti_update_dims_from_array - update nx, ny, ... from nim->dim[]
+
+ Fix all the dimension information, based on a new nim->dim[].
+
+ Note: we assume that dim[0] will not increase.
+
+ Check for updates to pixdim[], dx,..., nx,..., nvox, ndim, dim[0].
+*//*--------------------------------------------------------------------*/
+int nifti_update_dims_from_array( nifti_image * nim )
+{
+ int c, ndim;
+
+ if( !nim ){
+ REprintf("** update_dims: missing nim\n");
+ return 1;
+ }
+
+ if( g_opts.debug > 2 ){
+ REprintf("+d updating image dimensions given nim->dim:");
+ for( c = 0; c < 8; c++ ) REprintf(" %d", nim->dim[c]);
+ REprintf("\n");/*fputc('\n',stderr);*/
+ }
+
+ /* verify dim[0] first */
+ if(nim->dim[0] < 1 || nim->dim[0] > 7){
+ REprintf("** invalid dim[0], dim[] = ");
+ for( c = 0; c < 8; c++ ) REprintf(" %d", nim->dim[c]);
+ REprintf("\n");/*fputc('\n',stderr);*/
+ return 1;
+ }
+
+ /* set nx, ny ..., dx, dy, ..., one by one */
+
+ /* less than 1, set to 1, else copy */
+ if(nim->dim[1] < 1) nim->nx = nim->dim[1] = 1;
+ else nim->nx = nim->dim[1];
+ nim->dx = nim->pixdim[1];
+
+ /* if undefined, or less than 1, set to 1 */
+ if(nim->dim[0] < 2 || (nim->dim[0] >= 2 && nim->dim[2] < 1))
+ nim->ny = nim->dim[2] = 1;
+ else
+ nim->ny = nim->dim[2];
+ /* copy delta values, in any case */
+ nim->dy = nim->pixdim[2];
+
+ if(nim->dim[0] < 3 || (nim->dim[0] >= 3 && nim->dim[3] < 1))
+ nim->nz = nim->dim[3] = 1;
+ else /* just copy vals from arrays */
+ nim->nz = nim->dim[3];
+ nim->dz = nim->pixdim[3];
+
+ if(nim->dim[0] < 4 || (nim->dim[0] >= 4 && nim->dim[4] < 1))
+ nim->nt = nim->dim[4] = 1;
+ else /* just copy vals from arrays */
+ nim->nt = nim->dim[4];
+ nim->dt = nim->pixdim[4];
+
+ if(nim->dim[0] < 5 || (nim->dim[0] >= 5 && nim->dim[5] < 1))
+ nim->nu = nim->dim[5] = 1;
+ else /* just copy vals from arrays */
+ nim->nu = nim->dim[5];
+ nim->du = nim->pixdim[5];
+
+ if(nim->dim[0] < 6 || (nim->dim[0] >= 6 && nim->dim[6] < 1))
+ nim->nv = nim->dim[6] = 1;
+ else /* just copy vals from arrays */
+ nim->nv = nim->dim[6];
+ nim->dv = nim->pixdim[6];
+
+ if(nim->dim[0] < 7 || (nim->dim[0] >= 7 && nim->dim[7] < 1))
+ nim->nw = nim->dim[7] = 1;
+ else /* just copy vals from arrays */
+ nim->nw = nim->dim[7];
+ nim->dw = nim->pixdim[7];
+
+ for( c = 1, nim->nvox = 1; c <= nim->dim[0]; c++ )
+ nim->nvox *= nim->dim[c];
+
+ /* compute ndim, assuming it can be no larger than the old one */
+ for( ndim = nim->dim[0]; (ndim > 1) && (nim->dim[ndim] <= 1); ndim-- )
+ ;
+
+ if( g_opts.debug > 2 ){
+ REprintf("+d ndim = %d -> %d\n",nim->ndim, ndim);
+ REprintf(" --> (%d,%d,%d,%d,%d,%d,%d)\n",
+ nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw);
+ }
+
+ nim->dim[0] = nim->ndim = ndim;
+
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! Load the image data from disk into an already-prepared image struct.
+ *
+ * \param nim - initialized nifti_image, without data
+ * \param nbricks - the length of blist (must be 0 if blist is NULL)
+ * \param blist - an array of xyz volume indices to read (can be NULL)
+ * \param NBL - pointer to struct where resulting data will be stored
+ *
+ * If blist is NULL, read all sub-bricks.
+ *
+ * \return the number of loaded bricks (NBL->nbricks),
+ * 0 on failure, < 0 on error
+ *
+ * NOTE: it is likely that another function will copy the data pointers
+ * out of NBL, in which case the only pointer the calling function
+ * will want to free is NBL->bricks (not each NBL->bricks[i]).
+*//*--------------------------------------------------------------------*/
+int nifti_image_load_bricks( nifti_image * nim , int nbricks,
+ const int * blist, nifti_brick_list * NBL )
+{
+ int * slist = NULL, * sindex = NULL, rv;
+ znzFile fp;
+
+ /* we can have blist == NULL */
+ if( !nim || !NBL ){
+ REprintf("** nifti_image_load_bricks, bad params (%p,%p)\n",
+ (void *)nim, (void *)NBL);
+ return -1;
+ }
+
+ if( blist && nbricks <= 0 ){
+ if( g_opts.debug > 1 )
+ REprintf("-d load_bricks: received blist with nbricks = %d,"
+ "ignoring blist\n", nbricks);
+ blist = NULL; /* pretend nothing was passed */
+ }
+
+ if( blist && ! valid_nifti_brick_list(nim, nbricks, blist, g_opts.debug>0) )
+ return -1;
+
+ /* for efficiency, let's read the file in order */
+ if( blist && nifti_copynsort( nbricks, blist, &slist, &sindex ) != 0 )
+ return -1;
+
+ /* open the file and position the FILE pointer */
+ fp = nifti_image_load_prep( nim );
+ if( !fp ){
+ if( g_opts.debug > 0 )
+ REprintf("** nifti_image_load_bricks, failed load_prep\n");
+ if( blist ){ free(slist); free(sindex); }
+ return -1;
+ }
+
+ /* this will flag to allocate defaults */
+ if( !blist ) nbricks = 0;
+ if( nifti_alloc_NBL_mem( nim, nbricks, NBL ) != 0 ){
+ if( blist ){ free(slist); free(sindex); }
+ znzclose(fp);
+ return -1;
+ }
+
+ rv = nifti_load_NBL_bricks(nim, slist, sindex, NBL, fp);
+
+ if( rv != 0 ){
+ nifti_free_NBL( NBL ); /* failure! */
+ NBL->nbricks = 0; /* repetative, but clear */
+ }
+
+ if( slist ){ free(slist); free(sindex); }
+
+ znzclose(fp);
+
+ return NBL->nbricks;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! nifti_free_NBL - free all pointers and clear structure
+ *
+ * note: this does not presume to free the structure pointer
+*//*--------------------------------------------------------------------*/
+void nifti_free_NBL( nifti_brick_list * NBL )
+{
+ int c;
+
+ if( NBL->bricks ){
+ for( c = 0; c < NBL->nbricks; c++ )
+ if( NBL->bricks[c] ) free(NBL->bricks[c]);
+ free(NBL->bricks);
+ NBL->bricks = NULL;
+ }
+
+ NBL->bsize = NBL->nbricks = 0;
+}
+
+
+/*----------------------------------------------------------------------
+ * nifti_load_NBL_bricks - read the file data into the NBL struct
+ *
+ * return 0 on success, -1 on failure
+ *----------------------------------------------------------------------*/
+static int nifti_load_NBL_bricks( nifti_image * nim , int * slist, int * sindex,
+ nifti_brick_list * NBL, znzFile fp )
+{
+ size_t oposn, fposn; /* orig and current file positions */
+ size_t rv;
+ long test;
+ int c;
+ int prev, isrc, idest; /* previous and current sub-brick, and new index */
+
+ test = znztell(fp); /* store current file position */
+ if( test < 0 ){
+ REprintf("** load bricks: ztell failed??\n");
+ return -1;
+ }
+ fposn = oposn = test;
+
+ /* first, handle the default case, no passed blist */
+ if( !slist ){
+ for( c = 0; c < NBL->nbricks; c++ ) {
+ rv = nifti_read_buffer(fp, NBL->bricks[c], NBL->bsize, nim);
+ if( rv != NBL->bsize ){
+ REprintf("** load bricks: cannot read brick %d from '%s'\n",
+ c, nim->iname ? nim->iname : nim->fname);
+ return -1;
+ }
+ }
+ if( g_opts.debug > 1 )
+ REprintf("+d read %d default %u-byte bricks from file %s\n",
+ NBL->nbricks, (unsigned int)NBL->bsize,
+ nim->iname ? nim->iname:nim->fname );
+ return 0;
+ }
+
+ if( !sindex ){
+ REprintf("** load_NBL_bricks: missing index list\n");
+ return -1;
+ }
+
+ prev = -1; /* use prev for previous sub-brick */
+ for( c = 0; c < NBL->nbricks; c++ ){
+ isrc = slist[c]; /* this is original brick index (c is new one) */
+ idest = sindex[c]; /* this is the destination index for this data */
+
+ /* if this sub-brick is not the previous, we must read from disk */
+ if( isrc != prev ){
+
+ /* if we are not looking at the correct sub-brick, scan forward */
+ if( fposn != (oposn + isrc*NBL->bsize) ){
+ fposn = oposn + isrc*NBL->bsize;
+ if( znzseek(fp, (long)fposn, SEEK_SET) < 0 ){
+ REprintf("** failed to locate brick %d in file '%s'\n",
+ isrc, nim->iname ? nim->iname : nim->fname);
+ return -1;
+ }
+ }
+
+ /* only 10,000 lines later and we're actually reading something! */
+ rv = nifti_read_buffer(fp, NBL->bricks[idest], NBL->bsize, nim);
+ if( rv != NBL->bsize ){
+ REprintf("** failed to read brick %d from file '%s'\n",
+ isrc, nim->iname ? nim->iname : nim->fname);
+ if( g_opts.debug > 1 )
+ REprintf(" (read %u of %u bytes)\n",
+ (unsigned int)rv, (unsigned int)NBL->bsize);
+ return -1;
+ }
+ fposn += NBL->bsize;
+ } else {
+ /* we have already read this sub-brick, just copy the previous one */
+ /* note that this works because they are sorted */
+ memcpy(NBL->bricks[idest], NBL->bricks[sindex[c-1]], NBL->bsize);
+ }
+
+ prev = isrc; /* in any case, note the now previous sub-brick */
+ }
+
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------
+ * nifti_alloc_NBL_mem - allocate memory for bricks
+ *
+ * return 0 on success, -1 on failure
+ *----------------------------------------------------------------------*/
+static int nifti_alloc_NBL_mem(nifti_image * nim, int nbricks,
+ nifti_brick_list * nbl)
+{
+ int c;
+
+ /* if nbricks is not specified, use the default */
+ if( nbricks > 0 ) nbl->nbricks = nbricks;
+ else { /* I missed this one with the 1.17 change 02 Mar 2006 [rickr] */
+ nbl->nbricks = 1;
+ for( c = 4; c <= nim->ndim; c++ )
+ nbl->nbricks *= nim->dim[c];
+ }
+
+ nbl->bsize = (size_t)nim->nx * nim->ny * nim->nz * nim->nbyper;/* bytes */
+ nbl->bricks = (void **)malloc(nbl->nbricks * sizeof(void *));
+
+ if( ! nbl->bricks ){
+ REprintf("** NANM: failed to alloc %d void ptrs\n",nbricks);
+ return -1;
+ }
+
+ for( c = 0; c < nbl->nbricks; c++ ){
+ nbl->bricks[c] = (void *)malloc(nbl->bsize);
+ if( ! nbl->bricks[c] ){
+ REprintf("** NANM: failed to alloc %u bytes for brick %d\n",
+ (unsigned int)nbl->bsize, c);
+ /* so free and clear everything before returning */
+ while( c > 0 ){
+ c--;
+ free(nbl->bricks[c]);
+ }
+ free(nbl->bricks);
+ nbl->bricks = NULL;
+ nbl->bsize = nbl->nbricks = 0;
+ return -1;
+ }
+ }
+
+ if( g_opts.debug > 2 )
+ REprintf("+d NANM: alloc'd %d bricks of %u bytes for NBL\n",
+ nbl->nbricks, (unsigned int)nbl->bsize);
+
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------
+ * nifti_copynsort - copy int list, and sort with indices
+ *
+ * 1. duplicate the incoming list
+ * 2. create an sindex list, and init with 0..nbricks-1
+ * 3. do a slow insertion sort on the small slist, along with sindex list
+ * 4. check results, just to be positive
+ *
+ * So slist is sorted, and sindex hold original positions.
+ *
+ * return 0 on success, -1 on failure
+ *----------------------------------------------------------------------*/
+static int nifti_copynsort(int nbricks, const int * blist, int ** slist,
+ int ** sindex)
+{
+ int * stmp, * itmp; /* for ease of typing/reading */
+ int c1, c2, spos, tmp;
+
+ *slist = (int *)malloc(nbricks * sizeof(int));
+ *sindex = (int *)malloc(nbricks * sizeof(int));
+
+ if( !*slist || !*sindex ){
+ REprintf("** NCS: failed to alloc %d ints for sorting\n",nbricks);
+ if(*slist) free(*slist); /* maybe one succeeded */
+ if(*sindex) free(*sindex);
+ return -1;
+ }
+
+ /* init the lists */
+ memcpy(*slist, blist, nbricks*sizeof(int));
+ for( c1 = 0; c1 < nbricks; c1++ ) (*sindex)[c1] = c1;
+
+ /* now actually sort slist */
+ stmp = *slist;
+ itmp = *sindex;
+ for( c1 = 0; c1 < nbricks-1; c1++ ) {
+ /* find smallest value, init to current */
+ spos = c1;
+ for( c2 = c1+1; c2 < nbricks; c2++ )
+ if( stmp[c2] < stmp[spos] ) spos = c2;
+ if( spos != c1 ) /* swap: fine, don't maintain sub-order, see if I care */
+ {
+ tmp = stmp[c1]; /* first swap the sorting values */
+ stmp[c1] = stmp[spos];
+ stmp[spos] = tmp;
+
+ tmp = itmp[c1]; /* then swap the index values */
+ itmp[c1] = itmp[spos];
+ itmp[spos] = tmp;
+ }
+ }
+
+ if( g_opts.debug > 2 ){
+ REprintf( "+d sorted indexing list:\n");
+ REprintf( " orig : ");
+ for( c1 = 0; c1 < nbricks; c1++ ) REprintf( " %d",blist[c1]);
+ REprintf("\n new : ");
+ for( c1 = 0; c1 < nbricks; c1++ ) REprintf( " %d",stmp[c1]);
+ REprintf("\n indices: ");
+ for( c1 = 0; c1 < nbricks; c1++ ) REprintf( " %d",itmp[c1]);
+ REprintf("\n"); /*fputc('\n', stderr);*/
+ }
+
+ /* check the sort (why not? I've got time...) */
+ for( c1 = 0; c1 < nbricks-1; c1++ ){
+ if( (stmp[c1] > stmp[c1+1]) || (blist[itmp[c1]] != stmp[c1]) ){
+ REprintf("** sorting screw-up, way to go, rick!\n");
+ free(stmp); free(itmp); *slist = NULL; *sindex = NULL;
+ return -1;
+ }
+ }
+
+ if( g_opts.debug > 2 ) REprintf("-d sorting is okay\n");
+
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! valid_nifti_brick_list - check sub-brick list for image
+ *
+ * This function verifies that nbricks and blist are appropriate
+ * for use with this nim, based on the dimensions.
+ *
+ * \param nim nifti_image to check against
+ * \param nbricks number of brick indices in blist
+ * \param blist list of brick indices to check in nim
+ * \param disp_error if this flag is set, report errors to user
+ *
+ * \return 1 if valid, 0 if not
+*//*--------------------------------------------------------------------*/
+int valid_nifti_brick_list(nifti_image * nim , int nbricks,
+ const int * blist, int disp_error)
+{
+ int c, nsubs;
+
+ if( !nim ){
+ if( disp_error || g_opts.debug > 0 )
+ REprintf("** valid_nifti_brick_list: missing nifti image\n");
+ return 0;
+ }
+
+ if( nbricks <= 0 || !blist ){
+ if( disp_error || g_opts.debug > 1 )
+ REprintf("** valid_nifti_brick_list: no brick list to check\n");
+ return 0;
+ }
+
+ if( nim->dim[0] < 3 ){
+ if( disp_error || g_opts.debug > 1 )
+ REprintf("** cannot read explict brick list from %d-D dataset\n",
+ nim->dim[0]);
+ return 0;
+ }
+
+ /* nsubs sub-brick is nt*nu*nv*nw */
+ for( c = 4, nsubs = 1; c <= nim->dim[0]; c++ )
+ nsubs *= nim->dim[c];
+
+ if( nsubs <= 0 ){
+ REprintf("** VNBL warning: bad dim list (%d,%d,%d,%d)\n",
+ nim->dim[4], nim->dim[5], nim->dim[6], nim->dim[7]);
+ return 0;
+ }
+
+ for( c = 0; c < nbricks; c++ )
+ if( (blist[c] < 0) || (blist[c] >= nsubs) ){
+ if( disp_error || g_opts.debug > 1 )
+ REprintf("** volume index %d (#%d) is out of range [0,%d]\n",
+ blist[c], c, nsubs-1);
+ return 0;
+ }
+
+ return 1; /* all is well */
+}
+
+/*----------------------------------------------------------------------*/
+/* verify that NBL struct is a valid data source for the image
+ *
+ * return 1 if so, 0 otherwise
+*//*--------------------------------------------------------------------*/
+static int nifti_NBL_matches_nim(const nifti_image *nim,
+ const nifti_brick_list *NBL)
+{
+ size_t volbytes = 0; /* bytes per volume */
+ int ind, errs = 0, nvols = 0;
+
+
+ if( !nim || !NBL ) {
+ if( g_opts.debug > 0 )
+ REprintf("** nifti_NBL_matches_nim: NULL pointer(s)\n");
+ return 0;
+ }
+
+ /* for nim, compute volbytes and nvols */
+ if( nim->ndim > 0 ) {
+ /* first 3 indices are over a single volume */
+ volbytes = (size_t)nim->nbyper;
+ for( ind = 1; ind <= nim->ndim && ind < 4; ind++ )
+ volbytes *= (size_t)nim->dim[ind];
+
+ for( ind = 4, nvols = 1; ind <= nim->ndim; ind++ )
+ nvols *= nim->dim[ind];
+ }
+
+ if( volbytes != NBL->bsize ) {
+ if( g_opts.debug > 1 )
+ REprintf("** NBL/nim mismatch, volbytes = %u, %u\n",
+ (unsigned)NBL->bsize, (unsigned)volbytes);
+ errs++;
+ }
+
+ if( nvols != NBL->nbricks ) {
+ if( g_opts.debug > 1 )
+ REprintf("** NBL/nim mismatch, nvols = %d, %d\n",
+ NBL->nbricks, nvols);
+ errs++;
+ }
+
+ if( errs ) return 0;
+ else if ( g_opts.debug > 2 )
+ REprintf("-- nim/NBL agree: nvols = %d, nbytes = %u\n",
+ nvols, (unsigned)volbytes);
+
+ return 1;
+}
+
+/* end of new nifti_image_read_bricks() functionality */
+
+/*----------------------------------------------------------------------*/
+/*! display the orientation from the quaternian fields
+ *
+ * \param mesg if non-NULL, display this message first
+ * \param mat the matrix to convert to "nearest" orientation
+ *
+ * \return -1 if results cannot be determined, 0 if okay
+*//*--------------------------------------------------------------------*/
+int nifti_disp_matrix_orient( const char * mesg, mat44 mat )
+{
+ int i, j, k;
+
+ if ( mesg ) Rprintf(mesg); /* use stdout? */
+
+ nifti_mat44_to_orientation( mat, &i,&j,&k );
+ if ( i <= 0 || j <= 0 || k <= 0 ) return -1;
+
+ /* so we have good codes */
+ Rprintf(" i orientation = '%s'\n"
+ " j orientation = '%s'\n"
+ " k orientation = '%s'\n",
+ nifti_orientation_string(i),
+ nifti_orientation_string(j),
+ nifti_orientation_string(k) );
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! duplicate the given string (alloc length+1)
+ *
+ * \return allocated pointer (or NULL on failure)
+*//*--------------------------------------------------------------------*/
+char *nifti_strdup(const char *str)
+{
+ char *dup;
+
+ if( !str ) return NULL; /* allow calls passing NULL */
+
+ dup = (char *)malloc(strlen(str) + 1);
+
+ /* check for failure */
+ if( dup ) strcpy(dup, str);
+ else REprintf("** nifti_strdup: failed to alloc %u bytes\n",
+ (unsigned int)strlen(str)+1);
+
+ return dup;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*! Return a pointer to a string holding the name of a NIFTI datatype.
+
+ \param dt NIfTI-1 datatype
+
+ \return pointer to static string holding the datatype name
+
+ \warning Do not free() or modify this string!
+ It points to static storage.
+
+ \sa NIFTI1_DATATYPES group in nifti1.h
+*//*-------------------------------------------------------------------------*/
+char *nifti_datatype_string( int dt )
+{
+ switch( dt ){
+ case DT_UNKNOWN: return "UNKNOWN" ;
+ case DT_BINARY: return "BINARY" ;
+ case DT_INT8: return "INT8" ;
+ case DT_UINT8: return "UINT8" ;
+ case DT_INT16: return "INT16" ;
+ case DT_UINT16: return "UINT16" ;
+ case DT_INT32: return "INT32" ;
+ case DT_UINT32: return "UINT32" ;
+ case DT_INT64: return "INT64" ;
+ case DT_UINT64: return "UINT64" ;
+ case DT_FLOAT32: return "FLOAT32" ;
+ case DT_FLOAT64: return "FLOAT64" ;
+ case DT_FLOAT128: return "FLOAT128" ;
+ case DT_COMPLEX64: return "COMPLEX64" ;
+ case DT_COMPLEX128: return "COMPLEX128" ;
+ case DT_COMPLEX256: return "COMPLEX256" ;
+ case DT_RGB24: return "RGB24" ;
+ case DT_RGBA32: return "RGBA32" ;
+ }
+ return "**ILLEGAL**" ;
+}
+
+/*----------------------------------------------------------------------*/
+/*! Determine if the datatype code dt is an integer type (1=YES, 0=NO).
+
+ \return whether the given NIfTI-1 datatype code is valid
+
+ \sa NIFTI1_DATATYPES group in nifti1.h
+*//*--------------------------------------------------------------------*/
+int nifti_is_inttype( int dt )
+{
+ switch( dt ){
+ case DT_UNKNOWN: return 0 ;
+ case DT_BINARY: return 0 ;
+ case DT_INT8: return 1 ;
+ case DT_UINT8: return 1 ;
+ case DT_INT16: return 1 ;
+ case DT_UINT16: return 1 ;
+ case DT_INT32: return 1 ;
+ case DT_UINT32: return 1 ;
+ case DT_INT64: return 1 ;
+ case DT_UINT64: return 1 ;
+ case DT_FLOAT32: return 0 ;
+ case DT_FLOAT64: return 0 ;
+ case DT_FLOAT128: return 0 ;
+ case DT_COMPLEX64: return 0 ;
+ case DT_COMPLEX128: return 0 ;
+ case DT_COMPLEX256: return 0 ;
+ case DT_RGB24: return 1 ;
+ case DT_RGBA32: return 1 ;
+ }
+ return 0 ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! Return a pointer to a string holding the name of a NIFTI units type.
+
+ \param uu NIfTI-1 unit code
+
+ \return pointer to static string for the given unit type
+
+ \warning Do not free() or modify this string!
+ It points to static storage.
+
+ \sa NIFTI1_UNITS group in nifti1.h
+*//*-------------------------------------------------------------------------*/
+char *nifti_units_string( int uu )
+{
+ switch( uu ){
+ case NIFTI_UNITS_METER: return "m" ;
+ case NIFTI_UNITS_MM: return "mm" ;
+ case NIFTI_UNITS_MICRON: return "um" ;
+ case NIFTI_UNITS_SEC: return "s" ;
+ case NIFTI_UNITS_MSEC: return "ms" ;
+ case NIFTI_UNITS_USEC: return "us" ;
+ case NIFTI_UNITS_HZ: return "Hz" ;
+ case NIFTI_UNITS_PPM: return "ppm" ;
+ case NIFTI_UNITS_RADS: return "rad/s" ;
+ }
+ return "Unknown" ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! Return a pointer to a string holding the name of a NIFTI transform type.
+
+ \param xx NIfTI-1 xform code
+
+ \return pointer to static string describing xform code
+
+ \warning Do not free() or modify this string!
+ It points to static storage.
+
+ \sa NIFTI1_XFORM_CODES group in nifti1.h
+*//*-------------------------------------------------------------------------*/
+char *nifti_xform_string( int xx )
+{
+ switch( xx ){
+ case NIFTI_XFORM_SCANNER_ANAT: return "Scanner Anat" ;
+ case NIFTI_XFORM_ALIGNED_ANAT: return "Aligned Anat" ;
+ case NIFTI_XFORM_TALAIRACH: return "Talairach" ;
+ case NIFTI_XFORM_MNI_152: return "MNI_152" ;
+ }
+ return "Unknown" ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! Return a pointer to a string holding the name of a NIFTI intent type.
+
+ \param ii NIfTI-1 intent code
+
+ \return pointer to static string describing code
+
+ \warning Do not free() or modify this string!
+ It points to static storage.
+
+ \sa NIFTI1_INTENT_CODES group in nifti1.h
+*//*-------------------------------------------------------------------------*/
+char *nifti_intent_string( int ii )
+{
+ switch( ii ){
+ case NIFTI_INTENT_CORREL: return "Correlation statistic" ;
+ case NIFTI_INTENT_TTEST: return "T-statistic" ;
+ case NIFTI_INTENT_FTEST: return "F-statistic" ;
+ case NIFTI_INTENT_ZSCORE: return "Z-score" ;
+ case NIFTI_INTENT_CHISQ: return "Chi-squared distribution" ;
+ case NIFTI_INTENT_BETA: return "Beta distribution" ;
+ case NIFTI_INTENT_BINOM: return "Binomial distribution" ;
+ case NIFTI_INTENT_GAMMA: return "Gamma distribution" ;
+ case NIFTI_INTENT_POISSON: return "Poisson distribution" ;
+ case NIFTI_INTENT_NORMAL: return "Normal distribution" ;
+ case NIFTI_INTENT_FTEST_NONC: return "F-statistic noncentral" ;
+ case NIFTI_INTENT_CHISQ_NONC: return "Chi-squared noncentral" ;
+ case NIFTI_INTENT_LOGISTIC: return "Logistic distribution" ;
+ case NIFTI_INTENT_LAPLACE: return "Laplace distribution" ;
+ case NIFTI_INTENT_UNIFORM: return "Uniform distribition" ;
+ case NIFTI_INTENT_TTEST_NONC: return "T-statistic noncentral" ;
+ case NIFTI_INTENT_WEIBULL: return "Weibull distribution" ;
+ case NIFTI_INTENT_CHI: return "Chi distribution" ;
+ case NIFTI_INTENT_INVGAUSS: return "Inverse Gaussian distribution" ;
+ case NIFTI_INTENT_EXTVAL: return "Extreme Value distribution" ;
+ case NIFTI_INTENT_PVAL: return "P-value" ;
+
+ case NIFTI_INTENT_LOGPVAL: return "Log P-value" ;
+ case NIFTI_INTENT_LOG10PVAL: return "Log10 P-value" ;
+
+ case NIFTI_INTENT_ESTIMATE: return "Estimate" ;
+ case NIFTI_INTENT_LABEL: return "Label index" ;
+ case NIFTI_INTENT_NEURONAME: return "NeuroNames index" ;
+ case NIFTI_INTENT_GENMATRIX: return "General matrix" ;
+ case NIFTI_INTENT_SYMMATRIX: return "Symmetric matrix" ;
+ case NIFTI_INTENT_DISPVECT: return "Displacement vector" ;
+ case NIFTI_INTENT_VECTOR: return "Vector" ;
+ case NIFTI_INTENT_POINTSET: return "Pointset" ;
+ case NIFTI_INTENT_TRIANGLE: return "Triangle" ;
+ case NIFTI_INTENT_QUATERNION: return "Quaternion" ;
+
+ case NIFTI_INTENT_DIMLESS: return "Dimensionless number" ;
+ }
+ return "Unknown" ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! Return a pointer to a string holding the name of a NIFTI slice_code.
+
+ \param ss NIfTI-1 slice order code
+
+ \return pointer to static string describing code
+
+ \warning Do not free() or modify this string!
+ It points to static storage.
+
+ \sa NIFTI1_SLICE_ORDER group in nifti1.h
+*//*-------------------------------------------------------------------------*/
+char *nifti_slice_string( int ss )
+{
+ switch( ss ){
+ case NIFTI_SLICE_SEQ_INC: return "sequential_increasing" ;
+ case NIFTI_SLICE_SEQ_DEC: return "sequential_decreasing" ;
+ case NIFTI_SLICE_ALT_INC: return "alternating_increasing" ;
+ case NIFTI_SLICE_ALT_DEC: return "alternating_decreasing" ;
+ case NIFTI_SLICE_ALT_INC2: return "alternating_increasing_2" ;
+ case NIFTI_SLICE_ALT_DEC2: return "alternating_decreasing_2" ;
+ }
+ return "Unknown" ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! Return a pointer to a string holding the name of a NIFTI orientation.
+
+ \param ii orientation code
+
+ \return pointer to static string holding the orientation information
+
+ \warning Do not free() or modify the return string!
+ It points to static storage.
+
+ \sa NIFTI_L2R in nifti1_io.h
+*//*-------------------------------------------------------------------------*/
+char *nifti_orientation_string( int ii )
+{
+ switch( ii ){
+ case NIFTI_L2R: return "Left-to-Right" ;
+ case NIFTI_R2L: return "Right-to-Left" ;
+ case NIFTI_P2A: return "Posterior-to-Anterior" ;
+ case NIFTI_A2P: return "Anterior-to-Posterior" ;
+ case NIFTI_I2S: return "Inferior-to-Superior" ;
+ case NIFTI_S2I: return "Superior-to-Inferior" ;
+ }
+ return "Unknown" ;
+}
+
+/*--------------------------------------------------------------------------*/
+/*! Given a datatype code, set number of bytes per voxel and the swapsize.
+
+ \param datatype nifti1 datatype code
+ \param nbyper pointer to return value: number of bytes per voxel
+ \param swapsize pointer to return value: size of swap blocks
+
+ \return appropriate values at nbyper and swapsize
+
+ The swapsize is set to 0 if this datatype doesn't ever need swapping.
+
+ \sa NIFTI1_DATATYPES in nifti1.h
+*//*------------------------------------------------------------------------*/
+void nifti_datatype_sizes( int datatype , int *nbyper, int *swapsize )
+{
+ int nb=0, ss=0 ;
+ switch( datatype ){
+ case DT_INT8:
+ case DT_UINT8: nb = 1 ; ss = 0 ; break ;
+
+ case DT_INT16:
+ case DT_UINT16: nb = 2 ; ss = 2 ; break ;
+
+ case DT_RGB24: nb = 3 ; ss = 0 ; break ;
+ case DT_RGBA32: nb = 4 ; ss = 0 ; break ;
+
+ case DT_INT32:
+ case DT_UINT32:
+ case DT_FLOAT32: nb = 4 ; ss = 4 ; break ;
+
+ case DT_COMPLEX64: nb = 8 ; ss = 4 ; break ;
+
+ case DT_FLOAT64:
+ case DT_INT64:
+ case DT_UINT64: nb = 8 ; ss = 8 ; break ;
+
+ case DT_FLOAT128: nb = 16 ; ss = 16 ; break ;
+
+ case DT_COMPLEX128: nb = 16 ; ss = 8 ; break ;
+
+ case DT_COMPLEX256: nb = 32 ; ss = 16 ; break ;
+ }
+
+ ASSIF(nbyper,nb) ; ASSIF(swapsize,ss) ; return ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! Given the quaternion parameters (etc.), compute a transformation matrix.
+
+ See comments in nifti1.h for details.
+ - qb,qc,qd = quaternion parameters
+ - qx,qy,qz = offset parameters
+ - dx,dy,dz = grid stepsizes (non-negative inputs are set to 1.0)
+ - qfac = sign of dz step (< 0 is negative; >= 0 is positive)
+
+ <pre>
+ If qx=qy=qz=0, dx=dy=dz=1, then the output is a rotation matrix.
+ For qfac >= 0, the rotation is proper.
+ For qfac < 0, the rotation is improper.
+ </pre>
+
+ \see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h
+ \see nifti_mat44_to_quatern, nifti_make_orthog_mat44,
+ nifti_mat44_to_orientation
+
+*//*-------------------------------------------------------------------------*/
+mat44 nifti_quatern_to_mat44( float qb, float qc, float qd,
+ float qx, float qy, float qz,
+ float dx, float dy, float dz, float qfac )
+{
+ mat44 R ;
+ double a,b=qb,c=qc,d=qd , xd,yd,zd ;
+
+ /* last row is always [ 0 0 0 1 ] */
+
+ R.m[3][0]=R.m[3][1]=R.m[3][2] = 0.0 ; R.m[3][3]= 1.0 ;
+
+ /* compute a parameter from b,c,d */
+
+ a = 1.0l - (b*b + c*c + d*d) ;
+ if( a < 1.e-7l ){ /* special case */
+ a = 1.0l / sqrt(b*b+c*c+d*d) ;
+ b *= a ; c *= a ; d *= a ; /* normalize (b,c,d) vector */
+ a = 0.0l ; /* a = 0 ==> 180 degree rotation */
+ } else{
+ a = sqrt(a) ; /* angle = 2*arccos(a) */
+ }
+
+ /* load rotation matrix, including scaling factors for voxel sizes */
+
+ xd = (dx > 0.0) ? dx : 1.0l ; /* make sure are positive */
+ yd = (dy > 0.0) ? dy : 1.0l ;
+ zd = (dz > 0.0) ? dz : 1.0l ;
+
+ if( qfac < 0.0 ) zd = -zd ; /* left handedness? */
+
+ R.m[0][0] = (a*a+b*b-c*c-d*d) * xd ;
+ R.m[0][1] = 2.0l * (b*c-a*d ) * yd ;
+ R.m[0][2] = 2.0l * (b*d+a*c ) * zd ;
+ R.m[1][0] = 2.0l * (b*c+a*d ) * xd ;
+ R.m[1][1] = (a*a+c*c-b*b-d*d) * yd ;
+ R.m[1][2] = 2.0l * (c*d-a*b ) * zd ;
+ R.m[2][0] = 2.0l * (b*d-a*c ) * xd ;
+ R.m[2][1] = 2.0l * (c*d+a*b ) * yd ;
+ R.m[2][2] = (a*a+d*d-c*c-b*b) * zd ;
+
+ /* load offsets */
+
+ R.m[0][3] = qx ; R.m[1][3] = qy ; R.m[2][3] = qz ;
+
+ return R ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! Given the 3x4 upper corner of the matrix R, compute the quaternion
+ parameters that fit it.
+
+ - Any NULL pointer on input won't get assigned (e.g., if you don't want
+ dx,dy,dz, just pass NULL in for those pointers).
+ - If the 3 input matrix columns are NOT orthogonal, they will be
+ orthogonalized prior to calculating the parameters, using
+ the polar decomposition to find the orthogonal matrix closest
+ to the column-normalized input matrix.
+ - However, if the 3 input matrix columns are NOT orthogonal, then
+ the matrix produced by nifti_quatern_to_mat44 WILL have orthogonal
+ columns, so it won't be the same as the matrix input here.
+ This "feature" is because the NIFTI 'qform' transform is
+ deliberately not fully general -- it is intended to model a volume
+ with perpendicular axes.
+ - If the 3 input matrix columns are not even linearly independent,
+ you'll just have to take your luck, won't you?
+
+ \see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h
+
+ \see nifti_quatern_to_mat44, nifti_make_orthog_mat44,
+ nifti_mat44_to_orientation
+*//*-------------------------------------------------------------------------*/
+void nifti_mat44_to_quatern( mat44 R ,
+ float *qb, float *qc, float *qd,
+ float *qx, float *qy, float *qz,
+ float *dx, float *dy, float *dz, float *qfac )
+{
+ double r11,r12,r13 , r21,r22,r23 , r31,r32,r33 ;
+ double xd,yd,zd , a,b,c,d ;
+ mat33 P,Q ;
+
+ /* offset outputs are read write out of input matrix */
+
+ ASSIF(qx,R.m[0][3]) ; ASSIF(qy,R.m[1][3]) ; ASSIF(qz,R.m[2][3]) ;
+
+ /* load 3x3 matrix into local variables */
+
+ r11 = R.m[0][0] ; r12 = R.m[0][1] ; r13 = R.m[0][2] ;
+ r21 = R.m[1][0] ; r22 = R.m[1][1] ; r23 = R.m[1][2] ;
+ r31 = R.m[2][0] ; r32 = R.m[2][1] ; r33 = R.m[2][2] ;
+
+ /* compute lengths of each column; these determine grid spacings */
+
+ xd = sqrt( r11*r11 + r21*r21 + r31*r31 ) ;
+ yd = sqrt( r12*r12 + r22*r22 + r32*r32 ) ;
+ zd = sqrt( r13*r13 + r23*r23 + r33*r33 ) ;
+
+ /* if a column length is zero, patch the trouble */
+
+ if( xd == 0.0l ){ r11 = 1.0l ; r21 = r31 = 0.0l ; xd = 1.0l ; }
+ if( yd == 0.0l ){ r22 = 1.0l ; r12 = r32 = 0.0l ; yd = 1.0l ; }
+ if( zd == 0.0l ){ r33 = 1.0l ; r13 = r23 = 0.0l ; zd = 1.0l ; }
+
+ /* assign the output lengths */
+
+ ASSIF(dx,xd) ; ASSIF(dy,yd) ; ASSIF(dz,zd) ;
+
+ /* normalize the columns */
+
+ r11 /= xd ; r21 /= xd ; r31 /= xd ;
+ r12 /= yd ; r22 /= yd ; r32 /= yd ;
+ r13 /= zd ; r23 /= zd ; r33 /= zd ;
+
+ /* At this point, the matrix has normal columns, but we have to allow
+ for the fact that the hideous user may not have given us a matrix
+ with orthogonal columns.
+
+ So, now find the orthogonal matrix closest to the current matrix.
+
+ One reason for using the polar decomposition to get this
+ orthogonal matrix, rather than just directly orthogonalizing
+ the columns, is so that inputting the inverse matrix to R
+ will result in the inverse orthogonal matrix at this point.
+ If we just orthogonalized the columns, this wouldn't necessarily hold. */
+
+ Q.m[0][0] = r11 ; Q.m[0][1] = r12 ; Q.m[0][2] = r13 ; /* load Q */
+ Q.m[1][0] = r21 ; Q.m[1][1] = r22 ; Q.m[1][2] = r23 ;
+ Q.m[2][0] = r31 ; Q.m[2][1] = r32 ; Q.m[2][2] = r33 ;
+
+ P = nifti_mat33_polar(Q) ; /* P is orthog matrix closest to Q */
+
+ r11 = P.m[0][0] ; r12 = P.m[0][1] ; r13 = P.m[0][2] ; /* unload */
+ r21 = P.m[1][0] ; r22 = P.m[1][1] ; r23 = P.m[1][2] ;
+ r31 = P.m[2][0] ; r32 = P.m[2][1] ; r33 = P.m[2][2] ;
+
+ /* [ r11 r12 r13 ] */
+ /* at this point, the matrix [ r21 r22 r23 ] is orthogonal */
+ /* [ r31 r32 r33 ] */
+
+ /* compute the determinant to determine if it is proper */
+
+ zd = r11*r22*r33-r11*r32*r23-r21*r12*r33
+ +r21*r32*r13+r31*r12*r23-r31*r22*r13 ; /* should be -1 or 1 */
+
+ if( zd > 0 ){ /* proper */
+ ASSIF(qfac,1.0) ;
+ } else { /* improper ==> flip 3rd column */
+ ASSIF(qfac,-1.0) ;
+ r13 = -r13 ; r23 = -r23 ; r33 = -r33 ;
+ }
+
+ /* now, compute quaternion parameters */
+
+ a = r11 + r22 + r33 + 1.0l ;
+
+ if( a > 0.5l ){ /* simplest case */
+ a = 0.5l * sqrt(a) ;
+ b = 0.25l * (r32-r23) / a ;
+ c = 0.25l * (r13-r31) / a ;
+ d = 0.25l * (r21-r12) / a ;
+ } else { /* trickier case */
+ xd = 1.0 + r11 - (r22+r33) ; /* 4*b*b */
+ yd = 1.0 + r22 - (r11+r33) ; /* 4*c*c */
+ zd = 1.0 + r33 - (r11+r22) ; /* 4*d*d */
+ if( xd > 1.0 ){
+ b = 0.5l * sqrt(xd) ;
+ c = 0.25l* (r12+r21) / b ;
+ d = 0.25l* (r13+r31) / b ;
+ a = 0.25l* (r32-r23) / b ;
+ } else if( yd > 1.0 ){
+ c = 0.5l * sqrt(yd) ;
+ b = 0.25l* (r12+r21) / c ;
+ d = 0.25l* (r23+r32) / c ;
+ a = 0.25l* (r13-r31) / c ;
+ } else {
+ d = 0.5l * sqrt(zd) ;
+ b = 0.25l* (r13+r31) / d ;
+ c = 0.25l* (r23+r32) / d ;
+ a = 0.25l* (r21-r12) / d ;
+ }
+ if( a < 0.0l ){ b=-b ; c=-c ; d=-d; a=-a; }
+ }
+
+ ASSIF(qb,b) ; ASSIF(qc,c) ; ASSIF(qd,d) ;
+ return ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! Compute the inverse of a bordered 4x4 matrix.
+
+ <pre>
+ - Some numerical code fragments were generated by Maple 8.
+ - If a singular matrix is input, the output matrix will be all zero.
+ - You can check for this by examining the [3][3] element, which will
+ be 1.0 for the normal case and 0.0 for the bad case.
+
+ The input matrix should have the form:
+ [ r11 r12 r13 v1 ]
+ [ r21 r22 r23 v2 ]
+ [ r31 r32 r33 v3 ]
+ [ 0 0 0 1 ]
+ </pre>
+*//*-------------------------------------------------------------------------*/
+mat44 nifti_mat44_inverse( mat44 R )
+{
+ double r11,r12,r13,r21,r22,r23,r31,r32,r33,v1,v2,v3 , deti ;
+ mat44 Q ;
+ /* INPUT MATRIX IS: */
+ r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 v1 ] */
+ r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 v2 ] */
+ r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 v3 ] */
+ v1 = R.m[0][3]; v2 = R.m[1][3]; v3 = R.m[2][3]; /* [ 0 0 0 1 ] */
+
+ deti = r11*r22*r33-r11*r32*r23-r21*r12*r33
+ +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;
+
+ if( deti != 0.0l ) deti = 1.0l / deti ;
+
+ Q.m[0][0] = deti*( r22*r33-r32*r23) ;
+ Q.m[0][1] = deti*(-r12*r33+r32*r13) ;
+ Q.m[0][2] = deti*( r12*r23-r22*r13) ;
+ Q.m[0][3] = deti*(-r12*r23*v3+r12*v2*r33+r22*r13*v3
+ -r22*v1*r33-r32*r13*v2+r32*v1*r23) ;
+
+ Q.m[1][0] = deti*(-r21*r33+r31*r23) ;
+ Q.m[1][1] = deti*( r11*r33-r31*r13) ;
+ Q.m[1][2] = deti*(-r11*r23+r21*r13) ;
+ Q.m[1][3] = deti*( r11*r23*v3-r11*v2*r33-r21*r13*v3
+ +r21*v1*r33+r31*r13*v2-r31*v1*r23) ;
+
+ Q.m[2][0] = deti*( r21*r32-r31*r22) ;
+ Q.m[2][1] = deti*(-r11*r32+r31*r12) ;
+ Q.m[2][2] = deti*( r11*r22-r21*r12) ;
+ Q.m[2][3] = deti*(-r11*r22*v3+r11*r32*v2+r21*r12*v3
+ -r21*r32*v1-r31*r12*v2+r31*r22*v1) ;
+
+ Q.m[3][0] = Q.m[3][1] = Q.m[3][2] = 0.0l ;
+ Q.m[3][3] = (deti == 0.0l) ? 0.0l : 1.0l ; /* failure flag if deti == 0 */
+
+ return Q ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! Input 9 floats and make an orthgonal mat44 out of them.
+
+ Each row is normalized, then nifti_mat33_polar() is used to orthogonalize
+ them. If row #3 (r31,r32,r33) is input as zero, then it will be taken to
+ be the cross product of rows #1 and #2.
+
+ This function can be used to create a rotation matrix for transforming
+ an oblique volume to anatomical coordinates. For this application:
+ - row #1 (r11,r12,r13) is the direction vector along the image i-axis
+ - row #2 (r21,r22,r23) is the direction vector along the image j-axis
+ - row #3 (r31,r32,r33) is the direction vector along the slice direction
+ (if available; otherwise enter it as 0's)
+
+ The first 2 rows can be taken from the DICOM attribute (0020,0037)
+ "Image Orientation (Patient)".
+
+ After forming the rotation matrix, the complete affine transformation from
+ (i,j,k) grid indexes to (x,y,z) spatial coordinates can be computed by
+ multiplying each column by the appropriate grid spacing:
+ - column #1 (R.m[0][0],R.m[1][0],R.m[2][0]) by delta-x
+ - column #2 (R.m[0][1],R.m[1][1],R.m[2][1]) by delta-y
+ - column #3 (R.m[0][2],R.m[1][2],R.m[2][2]) by delta-z
+
+ and by then placing the center (x,y,z) coordinates of voxel (0,0,0) into
+ the column #4 (R.m[0][3],R.m[1][3],R.m[2][3]).
+
+ \sa nifti_quatern_to_mat44, nifti_mat44_to_quatern,
+ nifti_mat44_to_orientation
+*//*-------------------------------------------------------------------------*/
+mat44 nifti_make_orthog_mat44( float r11, float r12, float r13 ,
+ float r21, float r22, float r23 ,
+ float r31, float r32, float r33 )
+{
+ mat44 R ;
+ mat33 Q , P ;
+ double val ;
+
+ R.m[3][0] = R.m[3][1] = R.m[3][2] = 0.0l ; R.m[3][3] = 1.0l ;
+
+ Q.m[0][0] = r11 ; Q.m[0][1] = r12 ; Q.m[0][2] = r13 ; /* load Q */
+ Q.m[1][0] = r21 ; Q.m[1][1] = r22 ; Q.m[1][2] = r23 ;
+ Q.m[2][0] = r31 ; Q.m[2][1] = r32 ; Q.m[2][2] = r33 ;
+
+ /* normalize row 1 */
+
+ val = Q.m[0][0]*Q.m[0][0] + Q.m[0][1]*Q.m[0][1] + Q.m[0][2]*Q.m[0][2] ;
+ if( val > 0.0l ){
+ val = 1.0l / sqrt(val) ;
+ Q.m[0][0] *= val ; Q.m[0][1] *= val ; Q.m[0][2] *= val ;
+ } else {
+ Q.m[0][0] = 1.0l ; Q.m[0][1] = 0.0l ; Q.m[0][2] = 0.0l ;
+ }
+
+ /* normalize row 2 */
+
+ val = Q.m[1][0]*Q.m[1][0] + Q.m[1][1]*Q.m[1][1] + Q.m[1][2]*Q.m[1][2] ;
+ if( val > 0.0l ){
+ val = 1.0l / sqrt(val) ;
+ Q.m[1][0] *= val ; Q.m[1][1] *= val ; Q.m[1][2] *= val ;
+ } else {
+ Q.m[1][0] = 0.0l ; Q.m[1][1] = 1.0l ; Q.m[1][2] = 0.0l ;
+ }
+
+ /* normalize row 3 */
+
+ val = Q.m[2][0]*Q.m[2][0] + Q.m[2][1]*Q.m[2][1] + Q.m[2][2]*Q.m[2][2] ;
+ if( val > 0.0l ){
+ val = 1.0l / sqrt(val) ;
+ Q.m[2][0] *= val ; Q.m[2][1] *= val ; Q.m[2][2] *= val ;
+ } else {
+ Q.m[2][0] = Q.m[0][1]*Q.m[1][2] - Q.m[0][2]*Q.m[1][1] ; /* cross */
+ Q.m[2][1] = Q.m[0][2]*Q.m[1][0] - Q.m[0][0]*Q.m[1][2] ; /* product */
+ Q.m[2][2] = Q.m[0][0]*Q.m[1][1] - Q.m[0][1]*Q.m[1][0] ;
+ }
+
+ P = nifti_mat33_polar(Q) ; /* P is orthog matrix closest to Q */
+
+ R.m[0][0] = P.m[0][0] ; R.m[0][1] = P.m[0][1] ; R.m[0][2] = P.m[0][2] ;
+ R.m[1][0] = P.m[1][0] ; R.m[1][1] = P.m[1][1] ; R.m[1][2] = P.m[1][2] ;
+ R.m[2][0] = P.m[2][0] ; R.m[2][1] = P.m[2][1] ; R.m[2][2] = P.m[2][2] ;
+
+ R.m[0][3] = R.m[1][3] = R.m[2][3] = 0.0 ; return R ;
+}
+
+/*----------------------------------------------------------------------*/
+/*! compute the inverse of a 3x3 matrix
+*//*--------------------------------------------------------------------*/
+mat33 nifti_mat33_inverse( mat33 R ) /* inverse of 3x3 matrix */
+{
+ double r11,r12,r13,r21,r22,r23,r31,r32,r33 , deti ;
+ mat33 Q ;
+ /* INPUT MATRIX: */
+ r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 ] */
+ r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 ] */
+ r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 ] */
+
+ deti = r11*r22*r33-r11*r32*r23-r21*r12*r33
+ +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;
+
+ if( deti != 0.0l ) deti = 1.0l / deti ;
+
+ Q.m[0][0] = deti*( r22*r33-r32*r23) ;
+ Q.m[0][1] = deti*(-r12*r33+r32*r13) ;
+ Q.m[0][2] = deti*( r12*r23-r22*r13) ;
+
+ Q.m[1][0] = deti*(-r21*r33+r31*r23) ;
+ Q.m[1][1] = deti*( r11*r33-r31*r13) ;
+ Q.m[1][2] = deti*(-r11*r23+r21*r13) ;
+
+ Q.m[2][0] = deti*( r21*r32-r31*r22) ;
+ Q.m[2][1] = deti*(-r11*r32+r31*r12) ;
+ Q.m[2][2] = deti*( r11*r22-r21*r12) ;
+
+ return Q ;
+}
+
+/*----------------------------------------------------------------------*/
+/*! compute the determinant of a 3x3 matrix
+*//*--------------------------------------------------------------------*/
+float nifti_mat33_determ( mat33 R ) /* determinant of 3x3 matrix */
+{
+ double r11,r12,r13,r21,r22,r23,r31,r32,r33 ;
+ /* INPUT MATRIX: */
+ r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 ] */
+ r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 ] */
+ r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 ] */
+
+ return r11*r22*r33-r11*r32*r23-r21*r12*r33
+ +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;
+}
+
+/*----------------------------------------------------------------------*/
+/*! compute the max row norm of a 3x3 matrix
+*//*--------------------------------------------------------------------*/
+float nifti_mat33_rownorm( mat33 A ) /* max row norm of 3x3 matrix */
+{
+ float r1,r2,r3 ;
+
+ r1 = fabs(A.m[0][0])+fabs(A.m[0][1])+fabs(A.m[0][2]) ;
+ r2 = fabs(A.m[1][0])+fabs(A.m[1][1])+fabs(A.m[1][2]) ;
+ r3 = fabs(A.m[2][0])+fabs(A.m[2][1])+fabs(A.m[2][2]) ;
+ if( r1 < r2 ) r1 = r2 ;
+ if( r1 < r3 ) r1 = r3 ;
+ return r1 ;
+}
+
+/*----------------------------------------------------------------------*/
+/*! compute the max column norm of a 3x3 matrix
+*//*--------------------------------------------------------------------*/
+float nifti_mat33_colnorm( mat33 A ) /* max column norm of 3x3 matrix */
+{
+ float r1,r2,r3 ;
+
+ r1 = fabs(A.m[0][0])+fabs(A.m[1][0])+fabs(A.m[2][0]) ;
+ r2 = fabs(A.m[0][1])+fabs(A.m[1][1])+fabs(A.m[2][1]) ;
+ r3 = fabs(A.m[0][2])+fabs(A.m[1][2])+fabs(A.m[2][2]) ;
+ if( r1 < r2 ) r1 = r2 ;
+ if( r1 < r3 ) r1 = r3 ;
+ return r1 ;
+}
+
+/*----------------------------------------------------------------------*/
+/*! multiply 2 3x3 matrices
+*//*--------------------------------------------------------------------*/
+mat33 nifti_mat33_mul( mat33 A , mat33 B ) /* multiply 2 3x3 matrices */
+{
+ mat33 C ; int i,j ;
+ for( i=0 ; i < 3 ; i++ )
+ for( j=0 ; j < 3 ; j++ )
+ C.m[i][j] = A.m[i][0] * B.m[0][j]
+ + A.m[i][1] * B.m[1][j]
+ + A.m[i][2] * B.m[2][j] ;
+ return C ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! polar decomposition of a 3x3 matrix
+
+ This finds the closest orthogonal matrix to input A
+ (in both the Frobenius and L2 norms).
+
+ Algorithm is that from NJ Higham, SIAM J Sci Stat Comput, 7:1160-1174.
+*//*-------------------------------------------------------------------------*/
+mat33 nifti_mat33_polar( mat33 A )
+{
+ mat33 X , Y , Z ;
+ float alp,bet,gam,gmi , dif=1.0 ;
+ int k=0 ;
+
+ X = A ;
+
+ /* force matrix to be nonsingular */
+
+ gam = nifti_mat33_determ(X) ;
+ while( gam == 0.0 ){ /* perturb matrix */
+ gam = 0.00001 * ( 0.001 + nifti_mat33_rownorm(X) ) ;
+ X.m[0][0] += gam ; X.m[1][1] += gam ; X.m[2][2] += gam ;
+ gam = nifti_mat33_determ(X) ;
+ }
+
+ while(1){
+ Y = nifti_mat33_inverse(X) ;
+ if( dif > 0.3 ){ /* far from convergence */
+ alp = sqrt( nifti_mat33_rownorm(X) * nifti_mat33_colnorm(X) ) ;
+ bet = sqrt( nifti_mat33_rownorm(Y) * nifti_mat33_colnorm(Y) ) ;
+ gam = sqrt( bet / alp ) ;
+ gmi = 1.0 / gam ;
+ } else {
+ gam = gmi = 1.0 ; /* close to convergence */
+ }
+ Z.m[0][0] = 0.5 * ( gam*X.m[0][0] + gmi*Y.m[0][0] ) ;
+ Z.m[0][1] = 0.5 * ( gam*X.m[0][1] + gmi*Y.m[1][0] ) ;
+ Z.m[0][2] = 0.5 * ( gam*X.m[0][2] + gmi*Y.m[2][0] ) ;
+ Z.m[1][0] = 0.5 * ( gam*X.m[1][0] + gmi*Y.m[0][1] ) ;
+ Z.m[1][1] = 0.5 * ( gam*X.m[1][1] + gmi*Y.m[1][1] ) ;
+ Z.m[1][2] = 0.5 * ( gam*X.m[1][2] + gmi*Y.m[2][1] ) ;
+ Z.m[2][0] = 0.5 * ( gam*X.m[2][0] + gmi*Y.m[0][2] ) ;
+ Z.m[2][1] = 0.5 * ( gam*X.m[2][1] + gmi*Y.m[1][2] ) ;
+ Z.m[2][2] = 0.5 * ( gam*X.m[2][2] + gmi*Y.m[2][2] ) ;
+
+ dif = fabs(Z.m[0][0]-X.m[0][0])+fabs(Z.m[0][1]-X.m[0][1])
+ +fabs(Z.m[0][2]-X.m[0][2])+fabs(Z.m[1][0]-X.m[1][0])
+ +fabs(Z.m[1][1]-X.m[1][1])+fabs(Z.m[1][2]-X.m[1][2])
+ +fabs(Z.m[2][0]-X.m[2][0])+fabs(Z.m[2][1]-X.m[2][1])
+ +fabs(Z.m[2][2]-X.m[2][2]) ;
+
+ k = k+1 ;
+ if( k > 100 || dif < 3.e-6 ) break ; /* convergence or exhaustion */
+ X = Z ;
+ }
+
+ return Z ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! compute the (closest) orientation from a 4x4 ijk->xyz tranformation matrix
+
+ <pre>
+ Input: 4x4 matrix that transforms (i,j,k) indexes to (x,y,z) coordinates,
+ where +x=Right, +y=Anterior, +z=Superior.
+ (Only the upper-left 3x3 corner of R is used herein.)
+ Output: 3 orientation codes that correspond to the closest "standard"
+ anatomical orientation of the (i,j,k) axes.
+ Method: Find which permutation of (x,y,z) has the smallest angle to the
+ (i,j,k) axes directions, which are the columns of the R matrix.
+ Errors: The codes returned will be zero.
+
+ For example, an axial volume might get return values of
+ *icod = NIFTI_R2L (i axis is mostly Right to Left)
+ *jcod = NIFTI_P2A (j axis is mostly Posterior to Anterior)
+ *kcod = NIFTI_I2S (k axis is mostly Inferior to Superior)
+ </pre>
+
+ \see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h
+
+ \see nifti_quatern_to_mat44, nifti_mat44_to_quatern,
+ nifti_make_orthog_mat44
+*//*-------------------------------------------------------------------------*/
+void nifti_mat44_to_orientation( mat44 R , int *icod, int *jcod, int *kcod )
+{
+ float xi,xj,xk , yi,yj,yk , zi,zj,zk , val,detQ,detP ;
+ mat33 P , Q , M ;
+ int i,j,k=0,p,q,r , ibest,jbest,kbest,pbest,qbest,rbest ;
+ float vbest ;
+
+ if( icod == NULL || jcod == NULL || kcod == NULL ) return ; /* bad */
+
+ *icod = *jcod = *kcod = 0 ; /* error returns, if sh*t happens */
+
+ /* load column vectors for each (i,j,k) direction from matrix */
+
+ /*-- i axis --*/ /*-- j axis --*/ /*-- k axis --*/
+
+ xi = R.m[0][0] ; xj = R.m[0][1] ; xk = R.m[0][2] ;
+ yi = R.m[1][0] ; yj = R.m[1][1] ; yk = R.m[1][2] ;
+ zi = R.m[2][0] ; zj = R.m[2][1] ; zk = R.m[2][2] ;
+
+ /* normalize column vectors to get unit vectors along each ijk-axis */
+
+ /* normalize i axis */
+
+ val = sqrt( xi*xi + yi*yi + zi*zi ) ;
+ if( val == 0.0 ) return ; /* stupid input */
+ xi /= val ; yi /= val ; zi /= val ;
+
+ /* normalize j axis */
+
+ val = sqrt( xj*xj + yj*yj + zj*zj ) ;
+ if( val == 0.0 ) return ; /* stupid input */
+ xj /= val ; yj /= val ; zj /= val ;
+
+ /* orthogonalize j axis to i axis, if needed */
+
+ val = xi*xj + yi*yj + zi*zj ; /* dot product between i and j */
+ if( fabs(val) > 1.e-4 ){
+ xj -= val*xi ; yj -= val*yi ; zj -= val*zi ;
+ val = sqrt( xj*xj + yj*yj + zj*zj ) ; /* must renormalize */
+ if( val == 0.0 ) return ; /* j was parallel to i? */
+ xj /= val ; yj /= val ; zj /= val ;
+ }
+
+ /* normalize k axis; if it is zero, make it the cross product i x j */
+
+ val = sqrt( xk*xk + yk*yk + zk*zk ) ;
+ if( val == 0.0 ){ xk = yi*zj-zi*yj; yk = zi*xj-zj*xi ; zk=xi*yj-yi*xj ; }
+ else { xk /= val ; yk /= val ; zk /= val ; }
+
+ /* orthogonalize k to i */
+
+ val = xi*xk + yi*yk + zi*zk ; /* dot product between i and k */
+ if( fabs(val) > 1.e-4 ){
+ xk -= val*xi ; yk -= val*yi ; zk -= val*zi ;
+ val = sqrt( xk*xk + yk*yk + zk*zk ) ;
+ if( val == 0.0 ) return ; /* bad */
+ xk /= val ; yk /= val ; zk /= val ;
+ }
+
+ /* orthogonalize k to j */
+
+ val = xj*xk + yj*yk + zj*zk ; /* dot product between j and k */
+ if( fabs(val) > 1.e-4 ){
+ xk -= val*xj ; yk -= val*yj ; zk -= val*zj ;
+ val = sqrt( xk*xk + yk*yk + zk*zk ) ;
+ if( val == 0.0 ) return ; /* bad */
+ xk /= val ; yk /= val ; zk /= val ;
+ }
+
+ Q.m[0][0] = xi ; Q.m[0][1] = xj ; Q.m[0][2] = xk ;
+ Q.m[1][0] = yi ; Q.m[1][1] = yj ; Q.m[1][2] = yk ;
+ Q.m[2][0] = zi ; Q.m[2][1] = zj ; Q.m[2][2] = zk ;
+
+ /* at this point, Q is the rotation matrix from the (i,j,k) to (x,y,z) axes */
+
+ detQ = nifti_mat33_determ( Q ) ;
+ if( detQ == 0.0 ) return ; /* shouldn't happen unless user is a DUFIS */
+
+ /* Build and test all possible +1/-1 coordinate permutation matrices P;
+ then find the P such that the rotation matrix M=PQ is closest to the
+ identity, in the sense of M having the smallest total rotation angle. */
+
+ /* Despite the formidable looking 6 nested loops, there are
+ only 3*3*3*2*2*2 = 216 passes, which will run very quickly. */
+
+ vbest = -666.0 ; ibest=pbest=qbest=rbest=1 ; jbest=2 ; kbest=3 ;
+ for( i=1 ; i <= 3 ; i++ ){ /* i = column number to use for row #1 */
+ for( j=1 ; j <= 3 ; j++ ){ /* j = column number to use for row #2 */
+ if( i == j ) continue ;
+ for( k=1 ; k <= 3 ; k++ ){ /* k = column number to use for row #3 */
+ if( i == k || j == k ) continue ;
+ P.m[0][0] = P.m[0][1] = P.m[0][2] =
+ P.m[1][0] = P.m[1][1] = P.m[1][2] =
+ P.m[2][0] = P.m[2][1] = P.m[2][2] = 0.0 ;
+ for( p=-1 ; p <= 1 ; p+=2 ){ /* p,q,r are -1 or +1 */
+ for( q=-1 ; q <= 1 ; q+=2 ){ /* and go into rows #1,2,3 */
+ for( r=-1 ; r <= 1 ; r+=2 ){
+ P.m[0][i-1] = p ; P.m[1][j-1] = q ; P.m[2][k-1] = r ;
+ detP = nifti_mat33_determ(P) ; /* sign of permutation */
+ if( detP * detQ <= 0.0 ) continue ; /* doesn't match sign of Q */
+ M = nifti_mat33_mul(P,Q) ;
+
+ /* angle of M rotation = 2.0*acos(0.5*sqrt(1.0+trace(M))) */
+ /* we want largest trace(M) == smallest angle == M nearest to I */
+
+ val = M.m[0][0] + M.m[1][1] + M.m[2][2] ; /* trace */
+ if( val > vbest ){
+ vbest = val ;
+ ibest = i ; jbest = j ; kbest = k ;
+ pbest = p ; qbest = q ; rbest = r ;
+ }
+ }}}}}}
+
+ /* At this point ibest is 1 or 2 or 3; pbest is -1 or +1; etc.
+
+ The matrix P that corresponds is the best permutation approximation
+ to Q-inverse; that is, P (approximately) takes (x,y,z) coordinates
+ to the (i,j,k) axes.
+
+ For example, the first row of P (which contains pbest in column ibest)
+ determines the way the i axis points relative to the anatomical
+ (x,y,z) axes. If ibest is 2, then the i axis is along the y axis,
+ which is direction P2A (if pbest > 0) or A2P (if pbest < 0).
+
+ So, using ibest and pbest, we can assign the output code for
+ the i axis. Mutatis mutandis for the j and k axes, of course. */
+
+ switch( ibest*pbest ){
+ case 1: i = NIFTI_L2R ; break ;
+ case -1: i = NIFTI_R2L ; break ;
+ case 2: i = NIFTI_P2A ; break ;
+ case -2: i = NIFTI_A2P ; break ;
+ case 3: i = NIFTI_I2S ; break ;
+ case -3: i = NIFTI_S2I ; break ;
+ }
+
+ switch( jbest*qbest ){
+ case 1: j = NIFTI_L2R ; break ;
+ case -1: j = NIFTI_R2L ; break ;
+ case 2: j = NIFTI_P2A ; break ;
+ case -2: j = NIFTI_A2P ; break ;
+ case 3: j = NIFTI_I2S ; break ;
+ case -3: j = NIFTI_S2I ; break ;
+ }
+
+ switch( kbest*rbest ){
+ case 1: k = NIFTI_L2R ; break ;
+ case -1: k = NIFTI_R2L ; break ;
+ case 2: k = NIFTI_P2A ; break ;
+ case -2: k = NIFTI_A2P ; break ;
+ case 3: k = NIFTI_I2S ; break ;
+ case -3: k = NIFTI_S2I ; break ;
+ }
+
+ *icod = i ; *jcod = j ; *kcod = k ; return ;
+}
+
+/*---------------------------------------------------------------------------*/
+/* Routines to swap byte arrays in various ways:
+ - 2 at a time: ab -> ba [short]
+ - 4 at a time: abcd -> dcba [int, float]
+ - 8 at a time: abcdDCBA -> ABCDdcba [long long, double]
+ - 16 at a time: abcdefghHGFEDCBA -> ABCDEFGHhgfedcba [long double]
+-----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------*/
+/*! swap each byte pair from the given list of n pairs
+ *
+ * Due to alignment of structures at some architectures (e.g. on ARM),
+ * stick to char varaibles.
+ * Fixes http://bugs.debian.org/446893 Yaroslav <debian at onerussian.com>
+ *
+*//*--------------------------------------------------------------------*/
+void nifti_swap_2bytes( size_t n , void *ar ) /* 2 bytes at a time */
+{
+ register size_t ii ;
+ unsigned char * cp1 = (unsigned char *)ar, * cp2 ;
+ unsigned char tval;
+
+ for( ii=0 ; ii < n ; ii++ ){
+ cp2 = cp1 + 1;
+ tval = *cp1; *cp1 = *cp2; *cp2 = tval;
+ cp1 += 2;
+ }
+ return ;
+}
+
+/*----------------------------------------------------------------------*/
+/*! swap 4 bytes at a time from the given list of n sets of 4 bytes
+*//*--------------------------------------------------------------------*/
+void nifti_swap_4bytes( size_t n , void *ar ) /* 4 bytes at a time */
+{
+ register size_t ii ;
+ unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ;
+ register unsigned char tval ;
+
+ for( ii=0 ; ii < n ; ii++ ){
+ cp1 = cp0; cp2 = cp0+3;
+ tval = *cp1; *cp1 = *cp2; *cp2 = tval;
+ cp1++; cp2--;
+ tval = *cp1; *cp1 = *cp2; *cp2 = tval;
+ cp0 += 4;
+ }
+ return ;
+}
+
+/*----------------------------------------------------------------------*/
+/*! swap 8 bytes at a time from the given list of n sets of 8 bytes
+ *
+ * perhaps use this style for the general Nbytes, as Yaroslav suggests
+*//*--------------------------------------------------------------------*/
+void nifti_swap_8bytes( size_t n , void *ar ) /* 8 bytes at a time */
+{
+ register size_t ii ;
+ unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ;
+ register unsigned char tval ;
+
+ for( ii=0 ; ii < n ; ii++ ){
+ cp1 = cp0; cp2 = cp0+7;
+ while ( cp2 > cp1 ) /* unroll? */
+ {
+ tval = *cp1 ; *cp1 = *cp2 ; *cp2 = tval ;
+ cp1++; cp2--;
+ }
+ cp0 += 8;
+ }
+ return ;
+}
+
+/*----------------------------------------------------------------------*/
+/*! swap 16 bytes at a time from the given list of n sets of 16 bytes
+*//*--------------------------------------------------------------------*/
+void nifti_swap_16bytes( size_t n , void *ar ) /* 16 bytes at a time */
+{
+ register size_t ii ;
+ unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ;
+ register unsigned char tval ;
+
+ for( ii=0 ; ii < n ; ii++ ){
+ cp1 = cp0; cp2 = cp0+15;
+ while ( cp2 > cp1 )
+ {
+ tval = *cp1 ; *cp1 = *cp2 ; *cp2 = tval ;
+ cp1++; cp2--;
+ }
+ cp0 += 16;
+ }
+ return ;
+}
+
+#if 0 /* not important: save for version update 6 Jul 2010 [rickr] */
+
+/*----------------------------------------------------------------------*/
+/*! generic: swap siz bytes at a time from the given list of n sets
+*//*--------------------------------------------------------------------*/
+void nifti_swap_bytes( size_t n , int siz , void *ar )
+{
+ register size_t ii ;
+ unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ;
+ register unsigned char tval ;
+
+ for( ii=0 ; ii < n ; ii++ ){
+ cp1 = cp0; cp2 = cp0+(siz-1);
+ while ( cp2 > cp1 )
+ {
+ tval = *cp1 ; *cp1 = *cp2 ; *cp2 = tval ;
+ cp1++; cp2--;
+ }
+ cp0 += siz;
+ }
+ return ;
+}
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------*/
+/*! based on siz, call the appropriate nifti_swap_Nbytes() function
+*//*--------------------------------------------------------------------*/
+void nifti_swap_Nbytes( size_t n , int size , void *ar ) /* subsuming case */
+{
+ switch( size ){
+ case 2: nifti_swap_2bytes ( n , ar ) ; break ;
+ case 4: nifti_swap_4bytes ( n , ar ) ; break ;
+ case 8: nifti_swap_8bytes ( n , ar ) ; break ;
+ case 16: nifti_swap_16bytes( n , ar ) ; break ;
+ default: /* nifti_swap_bytes ( n , size, ar ) ; */
+ REprintf("** nifti_swap_Nbytes: cannot swap in %d byte blocks\n", size);
+ break ;
+ }
+ return ;
+}
+
+
+/*-------------------------------------------------------------------------*/
+/*! Byte swap NIFTI-1 file header in various places and ways.
+
+ If is_nifti, swap all (even UNUSED) fields of NIfTI header.
+ Else, swap as a nifti_analyze75 struct.
+*//*---------------------------------------------------------------------- */
+void swap_nifti_header( struct nifti_1_header *h , int is_nifti )
+{
+
+ /* if ANALYZE, swap as such and return */
+ if( ! is_nifti ) {
+ nifti_swap_as_analyze((nifti_analyze75 *)h);
+ return;
+ }
+
+ /* otherwise, swap all NIFTI fields */
+
+ nifti_swap_4bytes(1, &h->sizeof_hdr);
+ nifti_swap_4bytes(1, &h->extents);
+ nifti_swap_2bytes(1, &h->session_error);
+
+ nifti_swap_2bytes(8, h->dim);
+ nifti_swap_4bytes(1, &h->intent_p1);
+ nifti_swap_4bytes(1, &h->intent_p2);
+ nifti_swap_4bytes(1, &h->intent_p3);
+
+ nifti_swap_2bytes(1, &h->intent_code);
+ nifti_swap_2bytes(1, &h->datatype);
+ nifti_swap_2bytes(1, &h->bitpix);
+ nifti_swap_2bytes(1, &h->slice_start);
+
+ nifti_swap_4bytes(8, h->pixdim);
+
+ nifti_swap_4bytes(1, &h->vox_offset);
+ nifti_swap_4bytes(1, &h->scl_slope);
+ nifti_swap_4bytes(1, &h->scl_inter);
+ nifti_swap_2bytes(1, &h->slice_end);
+
+ nifti_swap_4bytes(1, &h->cal_max);
+ nifti_swap_4bytes(1, &h->cal_min);
+ nifti_swap_4bytes(1, &h->slice_duration);
+ nifti_swap_4bytes(1, &h->toffset);
+ nifti_swap_4bytes(1, &h->glmax);
+ nifti_swap_4bytes(1, &h->glmin);
+
+ nifti_swap_2bytes(1, &h->qform_code);
+ nifti_swap_2bytes(1, &h->sform_code);
+
+ nifti_swap_4bytes(1, &h->quatern_b);
+ nifti_swap_4bytes(1, &h->quatern_c);
+ nifti_swap_4bytes(1, &h->quatern_d);
+ nifti_swap_4bytes(1, &h->qoffset_x);
+ nifti_swap_4bytes(1, &h->qoffset_y);
+ nifti_swap_4bytes(1, &h->qoffset_z);
+
+ nifti_swap_4bytes(4, h->srow_x);
+ nifti_swap_4bytes(4, h->srow_y);
+ nifti_swap_4bytes(4, h->srow_z);
+
+ return ;
+}
+
+/*-------------------------------------------------------------------------*/
+/*! Byte swap as an ANALYZE 7.5 header
+ *
+ * return non-zero on failure
+*//*---------------------------------------------------------------------- */
+int nifti_swap_as_analyze( nifti_analyze75 * h )
+{
+ if( !h ) return 1;
+
+ nifti_swap_4bytes(1, &h->sizeof_hdr);
+ nifti_swap_4bytes(1, &h->extents);
+ nifti_swap_2bytes(1, &h->session_error);
+
+ nifti_swap_2bytes(8, h->dim);
+ nifti_swap_2bytes(1, &h->unused8);
+ nifti_swap_2bytes(1, &h->unused9);
+ nifti_swap_2bytes(1, &h->unused10);
+ nifti_swap_2bytes(1, &h->unused11);
+ nifti_swap_2bytes(1, &h->unused12);
+ nifti_swap_2bytes(1, &h->unused13);
+ nifti_swap_2bytes(1, &h->unused14);
+
+ nifti_swap_2bytes(1, &h->datatype);
+ nifti_swap_2bytes(1, &h->bitpix);
+ nifti_swap_2bytes(1, &h->dim_un0);
+
+ nifti_swap_4bytes(8, h->pixdim);
+
+ nifti_swap_4bytes(1, &h->vox_offset);
+ nifti_swap_4bytes(1, &h->funused1);
+ nifti_swap_4bytes(1, &h->funused2);
+ nifti_swap_4bytes(1, &h->funused3);
+
+ nifti_swap_4bytes(1, &h->cal_max);
+ nifti_swap_4bytes(1, &h->cal_min);
+ nifti_swap_4bytes(1, &h->compressed);
+ nifti_swap_4bytes(1, &h->verified);
+
+ nifti_swap_4bytes(1, &h->glmax);
+ nifti_swap_4bytes(1, &h->glmin);
+
+ nifti_swap_4bytes(1, &h->views);
+ nifti_swap_4bytes(1, &h->vols_added);
+ nifti_swap_4bytes(1, &h->start_field);
+ nifti_swap_4bytes(1, &h->field_skip);
+
+ nifti_swap_4bytes(1, &h->omax);
+ nifti_swap_4bytes(1, &h->omin);
+ nifti_swap_4bytes(1, &h->smax);
+ nifti_swap_4bytes(1, &h->smin);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+/*! OLD VERSION of swap_nifti_header (left for undo/compare operations)
+
+ Byte swap NIFTI-1 file header in various places and ways.
+
+ If is_nifti is nonzero, will also swap the NIFTI-specific
+ components of the header; otherwise, only the components
+ common to NIFTI and ANALYZE will be swapped.
+*//*---------------------------------------------------------------------- */
+void old_swap_nifti_header( struct nifti_1_header *h , int is_nifti )
+{
+ /* this stuff is always present, for ANALYZE and NIFTI */
+
+ swap_4(h->sizeof_hdr) ;
+ nifti_swap_2bytes( 8 , h->dim ) ;
+ nifti_swap_4bytes( 8 , h->pixdim ) ;
+
+ swap_2(h->datatype) ;
+ swap_2(h->bitpix) ;
+
+ swap_4(h->vox_offset); swap_4(h->cal_max); swap_4(h->cal_min);
+
+ /* this stuff is NIFTI specific */
+
+ if( is_nifti ){
+ swap_4(h->intent_p1); swap_4(h->intent_p2); swap_4(h->intent_p3);
+ swap_2(h->intent_code);
+
+ swap_2(h->slice_start); swap_2(h->slice_end);
+ swap_4(h->scl_slope); swap_4(h->scl_inter);
+ swap_4(h->slice_duration); swap_4(h->toffset);
+
+ swap_2(h->qform_code); swap_2(h->sform_code);
+ swap_4(h->quatern_b); swap_4(h->quatern_c); swap_4(h->quatern_d);
+ swap_4(h->qoffset_x); swap_4(h->qoffset_y); swap_4(h->qoffset_z);
+ nifti_swap_4bytes(4,h->srow_x);
+ nifti_swap_4bytes(4,h->srow_y);
+ nifti_swap_4bytes(4,h->srow_z);
+ }
+ return ;
+}
+
+
+#define USE_STAT
+#ifdef USE_STAT
+/*---------------------------------------------------------------------------*/
+/* Return the file length (0 if file not found or has no contents).
+ This is a Unix-specific function, since it uses stat().
+-----------------------------------------------------------------------------*/
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/*---------------------------------------------------------------------------*/
+/*! return the size of a file, in bytes
+
+ \return size of file on success, -1 on error or no file
+
+ changed to return int, -1 means no file or error 20 Dec 2004 [rickr]
+*//*-------------------------------------------------------------------------*/
+int nifti_get_filesize( const char *pathname )
+{
+ struct stat buf ; int ii ;
+
+ if( pathname == NULL || *pathname == '\0' ) return -1 ;
+ ii = stat( pathname , &buf ); if( ii != 0 ) return -1 ;
+ return (unsigned int)buf.st_size ;
+}
+
+#else /*---------- non-Unix version of the above, less efficient -----------*/
+
+int nifti_get_filesize( const char *pathname )
+{
+ znzFile fp ; int len ;
+
+ if( pathname == NULL || *pathname == '\0' ) return -1 ;
+ fp = znzopen(pathname,"rb",0); if( znz_isnull(fp) ) return -1 ;
+ znzseek(fp,0L,SEEK_END) ; len = znztell(fp) ;
+ znzclose(fp) ; return len ;
+}
+
+#endif /* USE_STAT */
+
+
+/*----------------------------------------------------------------------*/
+/*! return the total volume size, in bytes
+
+ This is computed as nvox * nbyper.
+*//*--------------------------------------------------------------------*/
+size_t nifti_get_volsize(const nifti_image *nim)
+{
+ return nim->nbyper * nim->nvox ; /* total bytes */
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* Support functions for filenames in read and write
+ - allows for gzipped files
+*/
+
+
+/*----------------------------------------------------------------------*/
+/*! simple check for file existence
+
+ \return 1 on existence, 0 otherwise
+*//*--------------------------------------------------------------------*/
+int nifti_fileexists(const char* fname)
+{
+ znzFile fp;
+ fp = znzopen( fname , "rb" , 1 ) ;
+ if( !znz_isnull(fp) ) { znzclose(fp); return 1; }
+ return 0; /* fp is NULL */
+}
+
+/*----------------------------------------------------------------------*/
+/*! return whether the filename is valid
+
+ Note: uppercase extensions are now valid. 27 Apr 2009 [rickr]
+
+ The name is considered valid if the file basename has length greater than
+ zero, AND one of the valid nifti extensions is provided.
+ fname input | return |
+ ===============================
+ "myimage" | 0 |
+ "myimage.tif" | 0 |
+ "myimage.tif.gz" | 0 |
+ "myimage.nii" | 1 |
+ ".nii" | 0 |
+ ".myhiddenimage" | 0 |
+ ".myhiddenimage.nii" | 1 |
+*//*--------------------------------------------------------------------*/
+int nifti_is_complete_filename(const char* fname)
+{
+ char * ext;
+
+ /* check input file(s) for sanity */
+ if( fname == NULL || *fname == '\0' ){
+ if ( g_opts.debug > 1 )
+ REprintf("-- empty filename in nifti_validfilename()\n");
+ return 0;
+ }
+
+ ext = nifti_find_file_extension(fname);
+ if ( ext == NULL ) { /*Invalid extension given */
+ if ( g_opts.debug > 0 )
+ REprintf("-- no nifti valid extension for filename '%s'\n", fname);
+ return 0;
+ }
+
+ if ( ext && ext == fname ) { /* then no filename prefix */
+ if ( g_opts.debug > 0 )
+ REprintf("-- no prefix for filename '%s'\n", fname);
+ return 0;
+ }
+ return 1;
+}
+
+/*----------------------------------------------------------------------*/
+/*! return whether the filename is valid
+
+ Allow uppercase extensions as valid. 27 Apr 2009 [rickr]
+ Any .gz extension case must match the base extension case.
+
+ The name is considered valid if its length is positive, excluding
+ any nifti filename extension.
+ fname input | return | result of nifti_makebasename
+ ====================================================================
+ "myimage" | 1 | "myimage"
+ "myimage.tif" | 1 | "myimage.tif"
+ "myimage.tif.gz" | 1 | "myimage.tif"
+ "myimage.nii" | 1 | "myimage"
+ ".nii" | 0 | <ERROR - basename has zero length>
+ ".myhiddenimage" | 1 | ".myhiddenimage"
+ ".myhiddenimage.nii | 1 | ".myhiddenimage"
+*//*--------------------------------------------------------------------*/
+int nifti_validfilename(const char* fname)
+{
+ char * ext;
+
+ /* check input file(s) for sanity */
+ if( fname == NULL || *fname == '\0' ){
+ if ( g_opts.debug > 1 )
+ REprintf("-- empty filename in nifti_validfilename()\n");
+ return 0;
+ }
+
+ ext = nifti_find_file_extension(fname);
+
+ if ( ext && ext == fname ) { /* then no filename prefix */
+ if ( g_opts.debug > 0 )
+ REprintf("-- no prefix for filename '%s'\n", fname);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*----------------------------------------------------------------------*/
+/*! check the end of the filename for a valid nifti extension
+
+ Valid extensions are currently .nii, .hdr, .img, .nia,
+ or any of them followed by .gz. Note that '.' is part of
+ the extension.
+
+ Uppercase extensions are also valid, but not mixed case.
+
+ \return a pointer to the extension (within the filename), or NULL
+*//*--------------------------------------------------------------------*/
+char * nifti_find_file_extension( const char * name )
+{
+ char * ext, extcopy[8];
+ int len;
+ char extnii[8] = ".nii"; /* modifiable, for possible uppercase */
+ char exthdr[8] = ".hdr"; /* (leave space for .gz) */
+ char extimg[8] = ".img";
+ char extnia[8] = ".nia";
+ char extgz[4] = ".gz";
+ char * elist[4] = { NULL, NULL, NULL, NULL};
+
+ /* stupid compiler... */
+ elist[0] = extnii; elist[1] = exthdr; elist[2] = extimg; elist[3] = extnia;
+
+ if ( ! name ) return NULL;
+
+ len = (int)strlen(name);
+ if ( len < 4 ) return NULL;
+
+ ext = (char *)name + len - 4;
+
+ /* make manipulation copy, and possibly convert to lowercase */
+ strcpy(extcopy, ext);
+ if( g_opts.allow_upper_fext ) make_lowercase(extcopy);
+
+ /* if it look like a basic extension, fail or return it */
+ if( compare_strlist(extcopy, elist, 4) >= 0 ) {
+ if( is_mixedcase(ext) ) {
+ REprintf("** mixed case extension '%s' is not valid\n", ext);
+ return NULL;
+ }
+ else return ext;
+ }
+
+#ifdef HAVE_LIBZ
+ if ( len < 7 ) return NULL;
+
+ ext = (char *)name + len - 7;
+
+ /* make manipulation copy, and possibly convert to lowercase */
+ strcpy(extcopy, ext);
+ if( g_opts.allow_upper_fext ) make_lowercase(extcopy);
+
+ /* go after .gz extensions using the modifiable strings */
+ strcat(elist[0], extgz); strcat(elist[1], extgz); strcat(elist[2], extgz);
+
+ if( compare_strlist(extcopy, elist, 3) >= 0 ) {
+ if( is_mixedcase(ext) ) {
+ REprintf("** mixed case extension '%s' is not valid\n", ext);
+ return NULL;
+ }
+ else return ext;
+ }
+
+#endif
+
+ if( g_opts.debug > 1 )
+ REprintf("** find_file_ext: failed for name '%s'\n", name);
+
+ return NULL;
+}
+
+/*----------------------------------------------------------------------*/
+/*! return whether the filename ends in ".gz"
+*//*--------------------------------------------------------------------*/
+int nifti_is_gzfile(const char* fname)
+{
+ /* return true if the filename ends with .gz */
+ if (fname == NULL) { return 0; }
+#ifdef HAVE_LIBZ
+ { /* just so len doesn't generate compile warning */
+ int len;
+ len = (int)strlen(fname);
+ if (len < 3) return 0; /* so we don't search before the name */
+ if (fileext_compare(fname + strlen(fname) - 3,".gz")==0) { return 1; }
+ }
+#endif
+ return 0;
+}
+
+/*----------------------------------------------------------------------*/
+/*! return whether the given library was compiled with HAVE_LIBZ set
+*//*--------------------------------------------------------------------*/
+int nifti_compiled_with_zlib(void)
+{
+#ifdef HAVE_LIBZ
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+/*----------------------------------------------------------------------*/
+/*! duplicate the filename, while clearing any extension
+
+ This allocates memory for basename which should eventually be freed.
+*//*--------------------------------------------------------------------*/
+char * nifti_makebasename(const char* fname)
+{
+ char *basename, *ext;
+
+ basename=nifti_strdup(fname);
+
+ ext = nifti_find_file_extension(basename);
+ if ( ext ) *ext = '\0'; /* clear out extension */
+
+ return basename; /* in either case */
+}
+
+/*----------------------------------------------------------------------*/
+/*! set nifti's global debug level, for status reporting
+
+ - 0 : quiet, nothing is printed to the terminal, but errors
+ - 1 : normal execution (the default)
+ - 2, 3 : more details
+*//*--------------------------------------------------------------------*/
+void nifti_set_debug_level( int level )
+{
+ g_opts.debug = level;
+}
+
+/*----------------------------------------------------------------------*/
+/*! set nifti's global skip_blank_ext flag 5 Sep 2006 [rickr]
+
+ explicitly set to 0 or 1
+*//*--------------------------------------------------------------------*/
+void nifti_set_skip_blank_ext( int skip )
+{
+ g_opts.skip_blank_ext = skip ? 1 : 0;
+}
+
+/*----------------------------------------------------------------------*/
+/*! set nifti's global allow_upper_fext flag 28 Apr 2009 [rickr]
+
+ explicitly set to 0 or 1
+*//*--------------------------------------------------------------------*/
+void nifti_set_allow_upper_fext( int allow )
+{
+ g_opts.allow_upper_fext = allow ? 1 : 0;
+}
+
+/*----------------------------------------------------------------------*/
+/*! check current directory for existing header file
+
+ \return filename of header on success and NULL if no appropriate file
+ could be found
+
+ If fname has an uppercase extension, check for uppercase files.
+
+ NB: it allocates memory for hdrname which should be freed
+ when no longer required
+*//*-------------------------------------------------------------------*/
+char * nifti_findhdrname(const char* fname)
+{
+ char *basename, *hdrname, *ext;
+ char elist[2][5] = { ".hdr", ".nii" };
+ char extzip[4] = ".gz";
+ int efirst = 1; /* init to .nii extension */
+ int eisupper = 0; /* init to lowercase extensions */
+
+ /**- check input file(s) for sanity */
+ if( !nifti_validfilename(fname) ) return NULL;
+
+ basename = nifti_makebasename(fname);
+ if( !basename ) return NULL; /* only on string alloc failure */
+
+ /**- return filename if it has a valid extension and exists
+ (except if it is an .img file (and maybe .gz)) */
+ ext = nifti_find_file_extension(fname);
+
+ if( ext ) eisupper = is_uppercase(ext); /* do we look for uppercase? */
+
+ /* if the file exists and is a valid header name (not .img), return it */
+ if ( ext && nifti_fileexists(fname) ) {
+ /* allow for uppercase extension */
+ if ( fileext_n_compare(ext,".img",4) != 0 ){
+ hdrname = nifti_strdup(fname);
+ free(basename);
+ return hdrname;
+ } else
+ efirst = 0; /* note for below */
+ }
+
+ /* So the requested name is a basename, contains .img, or does not exist. */
+ /* In any case, use basename. */
+
+ /**- if .img, look for .hdr, .hdr.gz, .nii, .nii.gz, in that order */
+ /**- else, look for .nii, .nii.gz, .hdr, .hdr.gz, in that order */
+
+ /* if we get more extension choices, this could be a loop */
+
+ /* note: efirst is 0 in the case of ".img" */
+
+ /* if the user passed an uppercase entension (.IMG), search for uppercase */
+ if( eisupper ) {
+ make_uppercase(elist[0]);
+ make_uppercase(elist[1]);
+ make_uppercase(extzip);
+ }
+
+ hdrname = (char *)calloc(sizeof(char),strlen(basename)+8);
+ if( !hdrname ){
+ REprintf("** nifti_findhdrname: failed to alloc hdrname\n");
+ free(basename);
+ return NULL;
+ }
+
+ strcpy(hdrname,basename);
+ strcat(hdrname,elist[efirst]);
+ if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
+#ifdef HAVE_LIBZ
+ strcat(hdrname,extzip);
+ if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
+#endif
+
+ /* okay, try the other possibility */
+
+ efirst = 1 - efirst;
+
+ strcpy(hdrname,basename);
+ strcat(hdrname,elist[efirst]);
+ if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
+#ifdef HAVE_LIBZ
+ strcat(hdrname,extzip);
+ if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
+#endif
+
+ /**- if nothing has been found, return NULL */
+ free(basename);
+ free(hdrname);
+ return NULL;
+}
+
+
+/*------------------------------------------------------------------------*/
+/*! check current directory for existing image file
+
+ \param fname filename to check for
+ \nifti_type nifti_type for dataset - this determines whether to
+ first check for ".nii" or ".img" (since both may exist)
+
+ \return filename of data/img file on success and NULL if no appropriate
+ file could be found
+
+ If fname has a valid, uppercase extension, apply all extensions as
+ uppercase.
+
+ NB: it allocates memory for the image filename, which should be freed
+ when no longer required
+*//*---------------------------------------------------------------------*/
+char * nifti_findimgname(const char* fname , int nifti_type)
+{
+ /* store all extensions as strings, in case we need to go uppercase */
+ char *basename, *imgname, elist[2][5] = { ".nii", ".img" };
+ char extzip[4] = ".gz";
+ char extnia[5] = ".nia";
+ char *ext;
+ int first; /* first extension to use */
+
+ /* check input file(s) for sanity */
+ if( !nifti_validfilename(fname) ) return NULL;
+
+ basename = nifti_makebasename(fname);
+ imgname = (char *)calloc(sizeof(char),strlen(basename)+8);
+ if( !imgname ){
+ REprintf("** nifti_findimgname: failed to alloc imgname\n");
+ free(basename);
+ return NULL;
+ }
+
+ /* if we are looking for uppercase, apply the fact now */
+ ext = nifti_find_file_extension(fname);
+ if( ext && is_uppercase(ext) ) {
+ make_uppercase(elist[0]);
+ make_uppercase(elist[1]);
+ make_uppercase(extzip);
+ make_uppercase(extnia);
+ }
+
+ /* only valid extension for ASCII type is .nia, handle first */
+ if( nifti_type == NIFTI_FTYPE_ASCII ){
+ strcpy(imgname,basename);
+ strcat(imgname,extnia);
+ if (nifti_fileexists(imgname)) { free(basename); return imgname; }
+
+ } else {
+
+ /**- test for .nii and .img (don't assume input type from image type) */
+ /**- if nifti_type = 1, check for .nii first, else .img first */
+
+ /* if we get 3 or more extensions, can make a loop here... */
+
+ if (nifti_type == NIFTI_FTYPE_NIFTI1_1) first = 0; /* should match .nii */
+ else first = 1; /* should match .img */
+
+ strcpy(imgname,basename);
+ strcat(imgname,elist[first]);
+ if (nifti_fileexists(imgname)) { free(basename); return imgname; }
+#ifdef HAVE_LIBZ /* then also check for .gz */
+ strcat(imgname,extzip);
+ if (nifti_fileexists(imgname)) { free(basename); return imgname; }
+#endif
+
+ /* failed to find image file with expected extension, try the other */
+
+ strcpy(imgname,basename);
+ strcat(imgname,elist[1-first]); /* can do this with only 2 choices */
+ if (nifti_fileexists(imgname)) { free(basename); return imgname; }
+#ifdef HAVE_LIBZ /* then also check for .gz */
+ strcat(imgname,extzip);
+ if (nifti_fileexists(imgname)) { free(basename); return imgname; }
+#endif
+ }
+
+ /**- if nothing has been found, return NULL */
+ free(basename);
+ free(imgname);
+ return NULL;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! creates a filename for storing the header, based on nifti_type
+
+ \param prefix - this will be copied before the suffix is added
+ \param nifti_type - determines the extension, unless one is in prefix
+ \param check - check for existence (fail condition)
+ \param comp - add .gz for compressed name
+
+ Note that if prefix provides a file suffix, nifti_type is not used.
+
+ NB: this allocates memory which should be freed
+
+ \sa nifti_set_filenames
+*//*-------------------------------------------------------------------*/
+char * nifti_makehdrname(const char * prefix, int nifti_type, int check,
+ int comp)
+{
+ char * iname, * ext;
+ char extnii[5] = ".nii"; /* modifiable, for possible uppercase */
+ char exthdr[5] = ".hdr";
+ char extimg[5] = ".img";
+ char extnia[5] = ".nia";
+ char extgz[5] = ".gz";
+
+ if( !nifti_validfilename(prefix) ) return NULL;
+
+ /* add space for extension, optional ".gz", and null char */
+ iname = (char *)calloc(sizeof(char),strlen(prefix)+8);
+ if( !iname ){ REprintf("** small malloc failure!\n"); return NULL; }
+ strcpy(iname, prefix);
+
+ /* use any valid extension */
+ if( (ext = nifti_find_file_extension(iname)) != NULL ){
+ /* if uppercase, convert all extensions */
+ if( is_uppercase(ext) ) {
+ make_uppercase(extnii);
+ make_uppercase(exthdr);
+ make_uppercase(extimg);
+ make_uppercase(extnia);
+ make_uppercase(extgz);
+ }
+
+ if( strncmp(ext,extimg,4) == 0 )
+ memcpy(ext,exthdr,4); /* then convert img name to hdr */
+ }
+ /* otherwise, make one up */
+ else if( nifti_type == NIFTI_FTYPE_NIFTI1_1 ) strcat(iname, extnii);
+ else if( nifti_type == NIFTI_FTYPE_ASCII ) strcat(iname, extnia);
+ else strcat(iname, exthdr);
+
+#ifdef HAVE_LIBZ /* if compression is requested, make sure of suffix */
+ if( comp && (!ext || !strstr(iname,extgz)) ) strcat(iname,extgz);
+#endif
+
+ /* check for existence failure */
+ if( check && nifti_fileexists(iname) ){
+ REprintf("** failure: header file '%s' already exists\n",iname);
+ free(iname);
+ return NULL;
+ }
+
+ if(g_opts.debug > 2) REprintf("+d made header filename '%s'\n", iname);
+
+ return iname;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! creates a filename for storing the image, based on nifti_type
+
+ \param prefix - this will be copied before the suffix is added
+ \param nifti_type - determines the extension, unless provided by prefix
+ \param check - check for existence (fail condition)
+ \param comp - add .gz for compressed name
+
+ Note that if prefix provides a file suffix, nifti_type is not used.
+
+ NB: it allocates memory which should be freed
+
+ \sa nifti_set_filenames
+*//*-------------------------------------------------------------------*/
+char * nifti_makeimgname(const char * prefix, int nifti_type, int check,
+ int comp)
+{
+ char * iname, * ext;
+ char extnii[5] = ".nii"; /* modifiable, for possible uppercase */
+ char exthdr[5] = ".hdr";
+ char extimg[5] = ".img";
+ char extnia[5] = ".nia";
+ char extgz[5] = ".gz";
+
+ if( !nifti_validfilename(prefix) ) return NULL;
+
+ /* add space for extension, optional ".gz", and null char */
+ iname = (char *)calloc(sizeof(char),strlen(prefix)+8);
+ if( !iname ){ REprintf("** small malloc failure!\n"); return NULL; }
+ strcpy(iname, prefix);
+
+ /* use any valid extension */
+ if( (ext = nifti_find_file_extension(iname)) != NULL ){
+ /* if uppercase, convert all extensions */
+ if( is_uppercase(ext) ) {
+ make_uppercase(extnii);
+ make_uppercase(exthdr);
+ make_uppercase(extimg);
+ make_uppercase(extnia);
+ make_uppercase(extgz);
+ }
+
+ if( strncmp(ext,exthdr,4) == 0 )
+ memcpy(ext,extimg,4); /* then convert hdr name to img */
+ }
+ /* otherwise, make one up */
+ else if( nifti_type == NIFTI_FTYPE_NIFTI1_1 ) strcat(iname, extnii);
+ else if( nifti_type == NIFTI_FTYPE_ASCII ) strcat(iname, extnia);
+ else strcat(iname, extimg);
+
+#ifdef HAVE_LIBZ /* if compression is requested, make sure of suffix */
+ if( comp && (!ext || !strstr(iname,extgz)) ) strcat(iname,extgz);
+#endif
+
+ /* check for existence failure */
+ if( check && nifti_fileexists(iname) ){
+ REprintf("** failure: image file '%s' already exists\n",iname);
+ free(iname);
+ return NULL;
+ }
+
+ if( g_opts.debug > 2 ) REprintf("+d made image filename '%s'\n",iname);
+
+ return iname;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! create and set new filenames, based on prefix and image type
+
+ \param nim pointer to nifti_image in which to set filenames
+ \param prefix (required) prefix for output filenames
+ \param check check for previous existence of filename
+ (existence is an error condition)
+ \param set_byte_order flag to set nim->byteorder here
+ (this is probably a logical place to do so)
+
+ \return 0 on successful update
+
+ \warning this will free() any existing names and create new ones
+
+ \sa nifti_makeimgname, nifti_makehdrname, nifti_type_and_names_match
+*//*--------------------------------------------------------------------*/
+int nifti_set_filenames( nifti_image * nim, const char * prefix, int check,
+ int set_byte_order )
+{
+ int comp = nifti_is_gzfile(prefix);
+
+ if( !nim || !prefix ){
+ REprintf("** nifti_set_filenames, bad params %p, %p\n",
+ (void *)nim,prefix);
+ return -1;
+ }
+
+ if( g_opts.debug > 1 )
+ REprintf("+d modifying output filenames using prefix %s\n", prefix);
+
+ if( nim->fname ) free(nim->fname);
+ if( nim->iname ) free(nim->iname);
+ nim->fname = nifti_makehdrname(prefix, nim->nifti_type, check, comp);
+ nim->iname = nifti_makeimgname(prefix, nim->nifti_type, check, comp);
+ if( !nim->fname || !nim->iname ){
+ REprintf("nifti_set_filenames: failed to set prefix for %s.\n",prefix);
+ return -1;
+ }
+
+ if( set_byte_order ) nim->byteorder = nifti_short_order() ;
+
+ if( nifti_set_type_from_names(nim) < 0 )
+ return -1;
+
+ if( g_opts.debug > 2 )
+ REprintf("+d have new filenames %s and %s\n",nim->fname,nim->iname);
+
+ return 0;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/*! check whether nifti_type matches fname and iname for the nifti_image
+
+ - if type 0 or 2, expect .hdr/.img pair
+ - if type 1, expect .nii (and names must match)
+
+ \param nim given nifti_image
+ \param show_warn if set, print a warning message for any mis-match
+
+ \return
+ - 1 if the values seem to match
+ - 0 if there is a mis-match
+ - -1 if there is not sufficient information to create file(s)
+
+ \sa NIFTI_FTYPE_* codes in nifti1_io.h
+ \sa nifti_set_type_from_names, is_valid_nifti_type
+*//*------------------------------------------------------------------------*/
+int nifti_type_and_names_match( nifti_image * nim, int show_warn )
+{
+ char func[] = "nifti_type_and_names_match";
+ char * ext_h, * ext_i; /* header and image filename extensions */
+ int errs = 0; /* error counter */
+
+ /* sanity checks */
+ if( !nim ){
+ if( show_warn ) REprintf("** %s: missing nifti_image\n", func);
+ return -1;
+ }
+ if( !nim->fname ){
+ if( show_warn ) REprintf("** %s: missing header filename\n", func);
+ errs++;
+ }
+ if( !nim->iname ){
+ if( show_warn ) REprintf("** %s: missing image filename\n", func);
+ errs++;
+ }
+ if( !is_valid_nifti_type(nim->nifti_type) ){
+ if( show_warn )
+ REprintf("** %s: bad nifti_type %d\n", func, nim->nifti_type);
+ errs++;
+ }
+
+ if( errs ) return -1; /* then do not proceed */
+
+ /* get pointers to extensions */
+ ext_h = nifti_find_file_extension( nim->fname );
+ ext_i = nifti_find_file_extension( nim->iname );
+
+ /* check for filename extensions */
+ if( !ext_h ){
+ if( show_warn )
+ REprintf("-d missing NIFTI extension in header filename, %s\n",
+ nim->fname);
+ errs++;
+ }
+ if( !ext_i ){
+ if( show_warn )
+ REprintf("-d missing NIFTI extension in image filename, %s\n",
+ nim->iname);
+ errs++;
+ }
+
+ if( errs ) return 0; /* do not proceed, but this is just a mis-match */
+
+ /* general tests */
+ if( nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ){ /* .nii */
+ if( fileext_n_compare(ext_h,".nii",4) ) {
+ if( show_warn )
+ REprintf(
+ "-d NIFTI_FTYPE 1, but no .nii extension in header filename, %s\n",
+ nim->fname);
+ errs++;
+ }
+ if( fileext_n_compare(ext_i,".nii",4) ) {
+ if( show_warn )
+ REprintf(
+ "-d NIFTI_FTYPE 1, but no .nii extension in image filename, %s\n",
+ nim->iname);
+ errs++;
+ }
+ if( strcmp(nim->fname, nim->iname) != 0 ){
+ if( show_warn )
+ REprintf(
+ "-d NIFTI_FTYPE 1, but header and image filenames differ: %s, %s\n",
+ nim->fname, nim->iname);
+ errs++;
+ }
+ }
+ else if( (nim->nifti_type == NIFTI_FTYPE_NIFTI1_2) || /* .hdr/.img */
+ (nim->nifti_type == NIFTI_FTYPE_ANALYZE) )
+ {
+ if( fileext_n_compare(ext_h,".hdr",4) != 0 ){
+ if( show_warn )
+ REprintf("-d no '.hdr' extension, but NIFTI type is %d, %s\n",
+ nim->nifti_type, nim->fname);
+ errs++;
+ }
+ if( fileext_n_compare(ext_i,".img",4) != 0 ){
+ if( show_warn )
+ REprintf("-d no '.img' extension, but NIFTI type is %d, %s\n",
+ nim->nifti_type, nim->iname);
+ errs++;
+ }
+ }
+ /* ignore any other nifti_type */
+
+ return 1;
+}
+
+/* like strcmp, but also check against capitalization of known_ext
+ * (test as local string, with max length 7) */
+static int fileext_compare(const char * test_ext, const char * known_ext)
+{
+ char caps[8] = "";
+ int c, cmp, len;
+
+ /* if equal, don't need to check case (store to avoid multiple calls) */
+ cmp = strcmp(test_ext, known_ext);
+ if( cmp == 0 ) return cmp;
+
+ /* if anything odd, use default */
+ if( !test_ext || !known_ext ) return cmp;
+
+ len = strlen(known_ext);
+ if( len > 7 ) return cmp;
+
+ /* if here, strings are different but need to check upper-case */
+
+ for(c = 0; c < len; c++ ) caps[c] = toupper(known_ext[c]);
+ caps[c] = '\0';
+
+ return strcmp(test_ext, caps);
+}
+
+/* like strncmp, but also check against capitalization of known_ext
+ * (test as local string, with max length 7) */
+static int fileext_n_compare(const char * test_ext,
+ const char * known_ext, int maxlen)
+{
+ char caps[8] = "";
+ int c, cmp, len;
+
+ /* if equal, don't need to check case (store to avoid multiple calls) */
+ cmp = strncmp(test_ext, known_ext, maxlen);
+ if( cmp == 0 ) return cmp;
+
+ /* if anything odd, use default */
+ if( !test_ext || !known_ext ) return cmp;
+
+ len = strlen(known_ext);
+ if( len > maxlen ) len = maxlen; /* ignore anything past maxlen */
+ if( len > 7 ) return cmp;
+
+ /* if here, strings are different but need to check upper-case */
+
+ for(c = 0; c < len; c++ ) caps[c] = toupper(known_ext[c]);
+ caps[c] = '\0';
+
+ return strncmp(test_ext, caps, maxlen);
+}
+
+/* return 1 if there are uppercase but no lowercase */
+static int is_uppercase(const char * str)
+{
+ int c, hasupper = 0;
+
+ if( !str || !*str ) return 0;
+
+ for(c = 0; c < strlen(str); c++ ) {
+ if( islower(str[c]) ) return 0;
+ if( !hasupper && isupper(str[c]) ) hasupper = 1;
+ }
+
+ return hasupper;
+}
+
+/* return 1 if there are both uppercase and lowercase characters */
+static int is_mixedcase(const char * str)
+{
+ int c, hasupper = 0, haslower = 0;
+
+ if( !str || !*str ) return 0;
+
+ for(c = 0; c < strlen(str); c++ ) {
+ if( !haslower && islower(str[c]) ) haslower = 1;
+ if( !hasupper && isupper(str[c]) ) hasupper = 1;
+
+ if( haslower && hasupper ) return 1;
+ }
+
+ return 0;
+}
+
+/* convert any lowercase chars to uppercase */
+static int make_uppercase(char * str)
+{
+ int c;
+
+ if( !str || !*str ) return 0;
+
+ for(c = 0; c < strlen(str); c++ )
+ if( islower(str[c]) ) str[c] = toupper(str[c]);
+
+ return 0;
+}
+
+/* convert any uppercase chars to lowercase */
+static int make_lowercase(char * str)
+{
+ int c;
+
+ if( !str || !*str ) return 0;
+
+ for(c = 0; c < strlen(str); c++ )
+ if( isupper(str[c]) ) str[c] = tolower(str[c]);
+
+ return 0;
+}
+
+/* run strcmp against of list of strings
+ * return index of equality, if found
+ * else return -1 */
+static int compare_strlist(const char * str, char ** strlist, int len)
+{
+ int c;
+ if( len <= 0 || !str || !strlist ) return -1;
+ for( c = 0; c < len; c++ )
+ if( strlist[c] && !strcmp(str, strlist[c]) ) return c;
+ return -1;
+}
+
+/*--------------------------------------------------------------------------*/
+/*! check whether the given type is on the "approved" list
+
+ The code is valid if it is non-negative, and does not exceed
+ NIFTI_MAX_FTYPE.
+
+ \return 1 if nifti_type is valid, 0 otherwise
+ \sa NIFTI_FTYPE_* codes in nifti1_io.h
+*//*------------------------------------------------------------------------*/
+int is_valid_nifti_type( int nifti_type )
+{
+ if( nifti_type >= NIFTI_FTYPE_ANALYZE && /* smallest type, 0 */
+ nifti_type <= NIFTI_MAX_FTYPE )
+ return 1;
+ return 0;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/*! check whether the given type is on the "approved" list
+
+ The type is explicitly checked against the NIFTI_TYPE_* list
+ in nifti1.h.
+
+ \return 1 if dtype is valid, 0 otherwise
+ \sa NIFTI_TYPE_* codes in nifti1.h
+*//*------------------------------------------------------------------------*/
+int nifti_is_valid_datatype( int dtype )
+{
+ if( dtype == NIFTI_TYPE_UINT8 ||
+ dtype == NIFTI_TYPE_INT16 ||
+ dtype == NIFTI_TYPE_INT32 ||
+ dtype == NIFTI_TYPE_FLOAT32 ||
+ dtype == NIFTI_TYPE_COMPLEX64 ||
+ dtype == NIFTI_TYPE_FLOAT64 ||
+ dtype == NIFTI_TYPE_RGB24 ||
+ dtype == NIFTI_TYPE_RGBA32 ||
+ dtype == NIFTI_TYPE_INT8 ||
+ dtype == NIFTI_TYPE_UINT16 ||
+ dtype == NIFTI_TYPE_UINT32 ||
+ dtype == NIFTI_TYPE_INT64 ||
+ dtype == NIFTI_TYPE_UINT64 ||
+ dtype == NIFTI_TYPE_FLOAT128 ||
+ dtype == NIFTI_TYPE_COMPLEX128 ||
+ dtype == NIFTI_TYPE_COMPLEX256 ) return 1;
+ return 0;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/*! set the nifti_type field based on fname and iname
+
+ Note that nifti_type is changed only when it does not match
+ the filenames.
+
+ \return 0 on success, -1 on error
+
+ \sa is_valid_nifti_type, nifti_type_and_names_match
+*//*------------------------------------------------------------------------*/
+int nifti_set_type_from_names( nifti_image * nim )
+{
+ /* error checking first */
+ if( !nim ){ REprintf("** NSTFN: no nifti_image\n"); return -1; }
+
+ if( !nim->fname || !nim->iname ){
+ REprintf("** NSTFN: missing filename(s) fname @ %p, iname @ %p\n",
+ nim->fname, nim->iname);
+ return -1;
+ }
+
+ if( ! nifti_validfilename ( nim->fname ) ||
+ ! nifti_validfilename ( nim->iname ) ||
+ ! nifti_find_file_extension( nim->fname ) ||
+ ! nifti_find_file_extension( nim->iname )
+ ) {
+ REprintf("** NSTFN: invalid filename(s) fname='%s', iname='%s'\n",
+ nim->fname, nim->iname);
+ return -1;
+ }
+
+ if( g_opts.debug > 2 )
+ REprintf("-d verify nifti_type from filenames: %d",nim->nifti_type);
+
+ /* type should be NIFTI_FTYPE_ASCII if extension is .nia */
+ if( (fileext_compare(nifti_find_file_extension(nim->fname),".nia")==0)){
+ nim->nifti_type = NIFTI_FTYPE_ASCII;
+ } else {
+ /* not too picky here, do what must be done, and then verify */
+ if( strcmp(nim->fname, nim->iname) == 0 ) /* one file, type 1 */
+ nim->nifti_type = NIFTI_FTYPE_NIFTI1_1;
+ else if( nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ) /* cannot be type 1 */
+ nim->nifti_type = NIFTI_FTYPE_NIFTI1_2;
+ }
+
+ if( g_opts.debug > 2 ) REprintf(" -> %d\n",nim->nifti_type);
+
+ if( g_opts.debug > 1 ) /* warn user about anything strange */
+ nifti_type_and_names_match(nim, 1);
+
+ if( is_valid_nifti_type(nim->nifti_type) ) return 0; /* success! */
+
+ REprintf("** NSTFN: bad nifti_type %d, for '%s' and '%s'\n",
+ nim->nifti_type, nim->fname, nim->iname);
+
+ return -1;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/*! Determine if this is a NIFTI-formatted file.
+
+ <pre>
+ \return 0 if file looks like ANALYZE 7.5 [checks sizeof_hdr field == 348]
+ 1 if file marked as NIFTI (header+data in 1 file)
+ 2 if file marked as NIFTI (header+data in 2 files)
+ -1 if it can't tell, file doesn't exist, etc.
+ </pre>
+*//*------------------------------------------------------------------------*/
+int is_nifti_file( const char *hname )
+{
+ struct nifti_1_header nhdr ;
+ znzFile fp ;
+ int ii ;
+ char *tmpname;
+
+ /* bad input name? */
+
+ if( !nifti_validfilename(hname) ) return -1 ;
+
+ /* open file */
+
+ tmpname = nifti_findhdrname(hname);
+ if( tmpname == NULL ){
+ if( g_opts.debug > 0 )
+ REprintf("** no header file found for '%s'\n",hname);
+ return -1;
+ }
+ fp = znzopen( tmpname , "rb" , nifti_is_gzfile(tmpname) ) ;
+ free(tmpname);
+ if (znz_isnull(fp)) return -1 ; /* bad open? */
+
+ /* read header, close file */
+
+ ii = (int)znzread( &nhdr , 1 , sizeof(nhdr) , fp ) ;
+ znzclose( fp ) ;
+ if( ii < (int) sizeof(nhdr) ) return -1 ; /* bad read? */
+
+ /* check for NIFTI-ness */
+
+ if( NIFTI_VERSION(nhdr) != 0 ){
+ return ( NIFTI_ONEFILE(nhdr) ) ? 1 : 2 ;
+ }
+
+ /* check for ANALYZE-ness (sizeof_hdr field == 348) */
+
+ ii = nhdr.sizeof_hdr ;
+ if( ii == (int)sizeof(nhdr) ) return 0 ; /* matches */
+
+ /* try byte-swapping header */
+
+ swap_4(ii) ;
+ if( ii == (int)sizeof(nhdr) ) return 0 ; /* matches */
+
+ return -1 ; /* not good */
+}
+
+static int print_hex_vals( const char * data, int nbytes)
+{
+ int c;
+
+ if ( !data || nbytes < 1 ) return -1;
+
+ Rprintf("0x");
+ for ( c = 0; c < nbytes; c++ )
+ Rprintf(" %x", data[c]);
+
+ return 0;
+}
+
+/*----------------------------------------------------------------------*/
+/*! display the contents of the nifti_1_header (send to stdout)
+
+ \param info if non-NULL, print this character string
+ \param hp pointer to nifti_1_header
+*//*--------------------------------------------------------------------*/
+int disp_nifti_1_header( const char * info, const nifti_1_header * hp )
+{
+ int c;
+
+ Rprintf( "-------------------------------------------------------\n");
+ if ( info ) Rprintf( info );
+ if ( !hp ){ Rprintf(" ** no nifti_1_header to display!\n"); return 1; }
+
+ Rprintf(" nifti_1_header :\n"
+ " sizeof_hdr = %d\n"
+ " data_type[10] = ", hp->sizeof_hdr);
+ print_hex_vals(hp->data_type, 10);
+ Rprintf( "\n"
+ " db_name[18] = ");
+ print_hex_vals(hp->db_name, 18);
+ Rprintf( "\n"
+ " extents = %d\n"
+ " session_error = %d\n"
+ " regular = 0x%x\n"
+ " dim_info = 0x%x\n",
+ hp->extents, hp->session_error, hp->regular, hp->dim_info );
+ Rprintf( " dim[8] =");
+ for ( c = 0; c < 8; c++ ) Rprintf(" %d", hp->dim[c]);
+ Rprintf( "\n"
+ " intent_p1 = %f\n"
+ " intent_p2 = %f\n"
+ " intent_p3 = %f\n"
+ " intent_code = %d\n"
+ " datatype = %d\n"
+ " bitpix = %d\n"
+ " slice_start = %d\n"
+ " pixdim[8] =",
+ hp->intent_p1, hp->intent_p2, hp->intent_p3, hp->intent_code,
+ hp->datatype, hp->bitpix, hp->slice_start);
+ /* break pixdim over 2 lines */
+ for ( c = 0; c < 4; c++ ) Rprintf(" %f", hp->pixdim[c]);
+ Rprintf( "\n ");
+ for ( c = 4; c < 8; c++ ) Rprintf(" %f", hp->pixdim[c]);
+ Rprintf( "\n"
+ " vox_offset = %f\n"
+ " scl_slope = %f\n"
+ " scl_inter = %f\n"
+ " slice_end = %d\n"
+ " slice_code = %d\n"
+ " xyzt_units = 0x%x\n"
+ " cal_max = %f\n"
+ " cal_min = %f\n"
+ " slice_duration = %f\n"
+ " toffset = %f\n"
+ " glmax = %d\n"
+ " glmin = %d\n",
+ hp->vox_offset, hp->scl_slope, hp->scl_inter, hp->slice_end,
+ hp->slice_code, hp->xyzt_units, hp->cal_max, hp->cal_min,
+ hp->slice_duration, hp->toffset, hp->glmax, hp->glmin);
+ Rprintf(
+ " descrip = '%.80s'\n"
+ " aux_file = '%.24s'\n"
+ " qform_code = %d\n"
+ " sform_code = %d\n"
+ " quatern_b = %f\n"
+ " quatern_c = %f\n"
+ " quatern_d = %f\n"
+ " qoffset_x = %f\n"
+ " qoffset_y = %f\n"
+ " qoffset_z = %f\n"
+ " srow_x[4] = %f, %f, %f, %f\n"
+ " srow_y[4] = %f, %f, %f, %f\n"
+ " srow_z[4] = %f, %f, %f, %f\n"
+ " intent_name = '%-.16s'\n"
+ " magic = '%-.4s'\n",
+ hp->descrip, hp->aux_file, hp->qform_code, hp->sform_code,
+ hp->quatern_b, hp->quatern_c, hp->quatern_d,
+ hp->qoffset_x, hp->qoffset_y, hp->qoffset_z,
+ hp->srow_x[0], hp->srow_x[1], hp->srow_x[2], hp->srow_x[3],
+ hp->srow_y[0], hp->srow_y[1], hp->srow_y[2], hp->srow_y[3],
+ hp->srow_z[0], hp->srow_z[1], hp->srow_z[2], hp->srow_z[3],
+ hp->intent_name, hp->magic);
+ Rprintf( "-------------------------------------------------------\n");
+ /*fflush(stdout);*/
+
+ return 0;
+}
+
+
+#undef ERREX
+#define ERREX(msg) \
+ do{ REprintf("** ERROR: nifti_convert_nhdr2nim: %s\n", (msg) ) ; \
+ return NULL ; } while(0)
+
+/*----------------------------------------------------------------------*/
+/*! convert a nifti_1_header into a nift1_image
+
+ \return an allocated nifti_image, or NULL on failure
+*//*--------------------------------------------------------------------*/
+nifti_image* nifti_convert_nhdr2nim(struct nifti_1_header nhdr,
+ const char * fname)
+{
+ int ii , doswap , ioff ;
+ int is_nifti , is_onefile ;
+ nifti_image *nim;
+
+ nim = (nifti_image *)calloc( 1 , sizeof(nifti_image) ) ;
+ if( !nim ) ERREX("failed to allocate nifti image");
+
+ /* be explicit with pointers */
+ nim->fname = NULL;
+ nim->iname = NULL;
+ nim->data = NULL;
+
+ /**- check if we must swap bytes */
+
+ doswap = need_nhdr_swap(nhdr.dim[0], nhdr.sizeof_hdr); /* swap data flag */
+
+ if( doswap < 0 ){
+ if( doswap == -1 ) ERREX("bad dim[0]") ;
+ ERREX("bad sizeof_hdr") ; /* else */
+ }
+
+ /**- determine if this is a NIFTI-1 compliant header */
+
+ is_nifti = NIFTI_VERSION(nhdr) ;
+ /*
+ * before swapping header, record the Analyze75 orient code
+ */
+ if(!is_nifti)
+ {
+ /**- in analyze75, the orient code is at the same address as
+ * qform_code, but it's just one byte
+ * the qform_code will be zero, at which point you can check
+ * analyze75_orient if you care to.
+ */
+ unsigned char c = *((char *)(&nhdr.qform_code));
+ nim->analyze75_orient = (analyze_75_orient_code)c;
+ }
+ if( doswap ) {
+ if ( g_opts.debug > 3 ) disp_nifti_1_header("-d ni1 pre-swap: ", &nhdr);
+ swap_nifti_header( &nhdr , is_nifti ) ;
+ }
+
+ if ( g_opts.debug > 2 ) disp_nifti_1_header("-d nhdr2nim : ", &nhdr);
+
+ if( nhdr.datatype == DT_BINARY ||
+ nhdr.datatype == DT_UNKNOWN ) ERREX("bad datatype") ;
+
+ if( nhdr.dim[1] <= 0 ) ERREX("bad dim[1]") ;
+
+ /* fix bad dim[] values in the defined dimension range */
+ for( ii=2 ; ii <= nhdr.dim[0] ; ii++ )
+ if( nhdr.dim[ii] <= 0 ) nhdr.dim[ii] = 1 ;
+
+ /* fix any remaining bad dim[] values, so garbage does not propagate */
+ /* (only values 0 or 1 seem rational, otherwise set to arbirary 1) */
+ for( ii=nhdr.dim[0]+1 ; ii <= 7 ; ii++ )
+ if( nhdr.dim[ii] != 1 && nhdr.dim[ii] != 0) nhdr.dim[ii] = 1 ;
+
+#if 0 /* rely on dim[0], do not attempt to modify it 16 Nov 2005 [rickr] */
+
+ /**- get number of dimensions (ignoring dim[0] now) */
+ for( ii=7 ; ii >= 2 ; ii-- ) /* loop backwards until we */
+ if( nhdr.dim[ii] > 1 ) break ; /* find a dim bigger than 1 */
+ ndim = ii ;
+#endif
+
+ /**- set bad grid spacings to 1.0 */
+
+ for( ii=1 ; ii <= nhdr.dim[0] ; ii++ ){
+ if( nhdr.pixdim[ii] == 0.0 ||
+ !IS_GOOD_FLOAT(nhdr.pixdim[ii]) ) nhdr.pixdim[ii] = 1.0 ;
+ }
+
+ is_onefile = is_nifti && NIFTI_ONEFILE(nhdr) ;
+
+ if( is_nifti ) nim->nifti_type = (is_onefile) ? NIFTI_FTYPE_NIFTI1_1
+ : NIFTI_FTYPE_NIFTI1_2 ;
+ else nim->nifti_type = NIFTI_FTYPE_ANALYZE ;
+
+ ii = nifti_short_order() ;
+ if( doswap ) nim->byteorder = REVERSE_ORDER(ii) ;
+ else nim->byteorder = ii ;
+
+
+ /**- set dimensions of data array */
+
+ nim->ndim = nim->dim[0] = nhdr.dim[0];
+ nim->nx = nim->dim[1] = nhdr.dim[1];
+ nim->ny = nim->dim[2] = nhdr.dim[2];
+ nim->nz = nim->dim[3] = nhdr.dim[3];
+ nim->nt = nim->dim[4] = nhdr.dim[4];
+ nim->nu = nim->dim[5] = nhdr.dim[5];
+ nim->nv = nim->dim[6] = nhdr.dim[6];
+ nim->nw = nim->dim[7] = nhdr.dim[7];
+
+ for( ii=1, nim->nvox=1; ii <= nhdr.dim[0]; ii++ )
+ nim->nvox *= nhdr.dim[ii];
+
+ /**- set the type of data in voxels and how many bytes per voxel */
+
+ nim->datatype = nhdr.datatype ;
+
+ nifti_datatype_sizes( nim->datatype , &(nim->nbyper) , &(nim->swapsize) ) ;
+ if( nim->nbyper == 0 ){ free(nim); ERREX("bad datatype"); }
+
+ /**- set the grid spacings */
+
+ nim->dx = nim->pixdim[1] = nhdr.pixdim[1] ;
+ nim->dy = nim->pixdim[2] = nhdr.pixdim[2] ;
+ nim->dz = nim->pixdim[3] = nhdr.pixdim[3] ;
+ nim->dt = nim->pixdim[4] = nhdr.pixdim[4] ;
+ nim->du = nim->pixdim[5] = nhdr.pixdim[5] ;
+ nim->dv = nim->pixdim[6] = nhdr.pixdim[6] ;
+ nim->dw = nim->pixdim[7] = nhdr.pixdim[7] ;
+
+ /**- compute qto_xyz transformation from pixel indexes (i,j,k) to (x,y,z) */
+
+ if( !is_nifti || nhdr.qform_code <= 0 ){
+ /**- if not nifti or qform_code <= 0, use grid spacing for qto_xyz */
+
+ nim->qto_xyz.m[0][0] = nim->dx ; /* grid spacings */
+ nim->qto_xyz.m[1][1] = nim->dy ; /* along diagonal */
+ nim->qto_xyz.m[2][2] = nim->dz ;
+
+ /* off diagonal is zero */
+
+ nim->qto_xyz.m[0][1]=nim->qto_xyz.m[0][2]=nim->qto_xyz.m[0][3] = 0.0;
+ nim->qto_xyz.m[1][0]=nim->qto_xyz.m[1][2]=nim->qto_xyz.m[1][3] = 0.0;
+ nim->qto_xyz.m[2][0]=nim->qto_xyz.m[2][1]=nim->qto_xyz.m[2][3] = 0.0;
+
+ /* last row is always [ 0 0 0 1 ] */
+
+ nim->qto_xyz.m[3][0]=nim->qto_xyz.m[3][1]=nim->qto_xyz.m[3][2] = 0.0;
+ nim->qto_xyz.m[3][3]= 1.0 ;
+
+ nim->qform_code = NIFTI_XFORM_UNKNOWN ;
+
+ if( g_opts.debug > 1 ) REprintf("-d no qform provided\n");
+ } else {
+ /**- else NIFTI: use the quaternion-specified transformation */
+
+ nim->quatern_b = FIXED_FLOAT( nhdr.quatern_b ) ;
+ nim->quatern_c = FIXED_FLOAT( nhdr.quatern_c ) ;
+ nim->quatern_d = FIXED_FLOAT( nhdr.quatern_d ) ;
+
+ nim->qoffset_x = FIXED_FLOAT(nhdr.qoffset_x) ;
+ nim->qoffset_y = FIXED_FLOAT(nhdr.qoffset_y) ;
+ nim->qoffset_z = FIXED_FLOAT(nhdr.qoffset_z) ;
+
+ nim->qfac = (nhdr.pixdim[0] < 0.0) ? -1.0 : 1.0 ; /* left-handedness? */
+
+ nim->qto_xyz = nifti_quatern_to_mat44(
+ nim->quatern_b, nim->quatern_c, nim->quatern_d,
+ nim->qoffset_x, nim->qoffset_y, nim->qoffset_z,
+ nim->dx , nim->dy , nim->dz ,
+ nim->qfac ) ;
+
+ nim->qform_code = nhdr.qform_code ;
+
+ if( g_opts.debug > 1 )
+ nifti_disp_matrix_orient("-d qform orientations:\n", nim->qto_xyz);
+ }
+
+ /**- load inverse transformation (x,y,z) -> (i,j,k) */
+
+ nim->qto_ijk = nifti_mat44_inverse( nim->qto_xyz ) ;
+
+ /**- load sto_xyz affine transformation, if present */
+
+ if( !is_nifti || nhdr.sform_code <= 0 ){
+ /**- if not nifti or sform_code <= 0, then no sto transformation */
+
+ nim->sform_code = NIFTI_XFORM_UNKNOWN ;
+
+ if( g_opts.debug > 1 ) REprintf("-d no sform provided\n");
+
+ } else {
+ /**- else set the sto transformation from srow_*[] */
+
+ nim->sto_xyz.m[0][0] = nhdr.srow_x[0] ;
+ nim->sto_xyz.m[0][1] = nhdr.srow_x[1] ;
+ nim->sto_xyz.m[0][2] = nhdr.srow_x[2] ;
+ nim->sto_xyz.m[0][3] = nhdr.srow_x[3] ;
+
+ nim->sto_xyz.m[1][0] = nhdr.srow_y[0] ;
+ nim->sto_xyz.m[1][1] = nhdr.srow_y[1] ;
+ nim->sto_xyz.m[1][2] = nhdr.srow_y[2] ;
+ nim->sto_xyz.m[1][3] = nhdr.srow_y[3] ;
+
+ nim->sto_xyz.m[2][0] = nhdr.srow_z[0] ;
+ nim->sto_xyz.m[2][1] = nhdr.srow_z[1] ;
+ nim->sto_xyz.m[2][2] = nhdr.srow_z[2] ;
+ nim->sto_xyz.m[2][3] = nhdr.srow_z[3] ;
+
+ /* last row is always [ 0 0 0 1 ] */
+
+ nim->sto_xyz.m[3][0]=nim->sto_xyz.m[3][1]=nim->sto_xyz.m[3][2] = 0.0;
+ nim->sto_xyz.m[3][3]= 1.0 ;
+
+ nim->sto_ijk = nifti_mat44_inverse( nim->sto_xyz ) ;
+
+ nim->sform_code = nhdr.sform_code ;
+
+ if( g_opts.debug > 1 )
+ nifti_disp_matrix_orient("-d sform orientations:\n", nim->sto_xyz);
+ }
+
+ /**- set miscellaneous NIFTI stuff */
+
+ if( is_nifti ){
+ nim->scl_slope = FIXED_FLOAT( nhdr.scl_slope ) ;
+ nim->scl_inter = FIXED_FLOAT( nhdr.scl_inter ) ;
+
+ nim->intent_code = nhdr.intent_code ;
+
+ nim->intent_p1 = FIXED_FLOAT( nhdr.intent_p1 ) ;
+ nim->intent_p2 = FIXED_FLOAT( nhdr.intent_p2 ) ;
+ nim->intent_p3 = FIXED_FLOAT( nhdr.intent_p3 ) ;
+
+ nim->toffset = FIXED_FLOAT( nhdr.toffset ) ;
+
+ memcpy(nim->intent_name,nhdr.intent_name,15); nim->intent_name[15] = '\0';
+
+ nim->xyz_units = XYZT_TO_SPACE(nhdr.xyzt_units) ;
+ nim->time_units = XYZT_TO_TIME (nhdr.xyzt_units) ;
+
+ nim->freq_dim = DIM_INFO_TO_FREQ_DIM ( nhdr.dim_info ) ;
+ nim->phase_dim = DIM_INFO_TO_PHASE_DIM( nhdr.dim_info ) ;
+ nim->slice_dim = DIM_INFO_TO_SLICE_DIM( nhdr.dim_info ) ;
+
+ nim->slice_code = nhdr.slice_code ;
+ nim->slice_start = nhdr.slice_start ;
+ nim->slice_end = nhdr.slice_end ;
+ nim->slice_duration = FIXED_FLOAT(nhdr.slice_duration) ;
+ }
+
+ /**- set Miscellaneous ANALYZE stuff */
+
+ nim->cal_min = FIXED_FLOAT(nhdr.cal_min) ;
+ nim->cal_max = FIXED_FLOAT(nhdr.cal_max) ;
+
+ memcpy(nim->descrip ,nhdr.descrip ,79) ; nim->descrip [79] = '\0' ;
+ memcpy(nim->aux_file,nhdr.aux_file,23) ; nim->aux_file[23] = '\0' ;
+
+ /**- set ioff from vox_offset (but at least sizeof(header)) */
+
+ is_onefile = is_nifti && NIFTI_ONEFILE(nhdr) ;
+
+ if( is_onefile ){
+ ioff = (int)nhdr.vox_offset ;
+ if( ioff < (int) sizeof(nhdr) ) ioff = (int) sizeof(nhdr) ;
+ } else {
+ ioff = (int)nhdr.vox_offset ;
+ }
+ nim->iname_offset = ioff ;
+
+
+ /**- deal with file names if set */
+ if (fname!=NULL) {
+ nifti_set_filenames(nim,fname,0,0);
+ if (nim->iname==NULL) { ERREX("bad filename"); }
+ } else {
+ nim->fname = NULL;
+ nim->iname = NULL;
+ }
+
+ /* clear extension fields */
+ nim->num_ext = 0;
+ nim->ext_list = NULL;
+
+ return nim;
+}
+
+#undef ERREX
+#define ERREX(msg) \
+ do{ REprintf("** ERROR: nifti_image_open(%s): %s\n", \
+ (hname != NULL) ? hname : "(null)" , (msg) ) ; \
+ return fptr ; } while(0)
+
+/***************************************************************
+ * nifti_image_open
+ ***************************************************************/
+/*! znzFile nifti_image_open( char *hname, char *opts , nifti_image **nim)
+ \brief Read in NIFTI-1 or ANALYZE-7.5 file (pair) header information into a nifti_image struct.
+
+ - The image data is not read from disk (it may be read later using
+ nifti_image_load(), for example).
+ - The image data will be stored in whatever data format the
+ input data is; no scaling will be applied.
+ - DT_BINARY data is not supported.
+ - nifti_image_free() can be used to delete the returned struct,
+ when you are done with it.
+
+ \param hname filename of dataset .hdr or .nii file
+ \param opts options string for opening the header file
+ \param nim pointer to pointer to nifti_image struct
+ (this routine allocates the nifti_image struct)
+ \return file pointer (gzippable) to the file with the image data,
+ ready for reading.
+ <br>NULL if something fails badly.
+ \sa nifti_image_load, nifti_image_free
+ */
+znzFile nifti_image_open(const char * hname, char * opts, nifti_image ** nim)
+{
+ znzFile fptr=NULL;
+ /* open the hdr and reading it in, but do not load the data */
+ *nim = nifti_image_read(hname,0);
+ /* open the image file, ready for reading (compressed works for all reads) */
+ if( ((*nim) == NULL) || ((*nim)->iname == NULL) ||
+ ((*nim)->nbyper <= 0) || ((*nim)->nvox <= 0) )
+ ERREX("bad header info") ;
+
+ /* open image data file */
+ fptr = znzopen( (*nim)->iname, opts, nifti_is_gzfile((*nim)->iname) );
+ if( znz_isnull(fptr) ) ERREX("Can't open data file") ;
+
+ return fptr;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! return an allocated and filled nifti_1_header struct
+
+ Read the binary header from disk, and swap bytes if necessary.
+
+ \return an allocated nifti_1_header struct, or NULL on failure
+
+ \param hname name of file containing header
+ \param swapped if not NULL, return whether header bytes were swapped
+ \param check flag to check for invalid nifti_1_header
+
+ \warning ASCII header type is not supported
+
+ \sa nifti_image_read, nifti_image_free, nifti_image_read_bricks
+*//*--------------------------------------------------------------------*/
+nifti_1_header * nifti_read_header(const char * hname, int * swapped, int check)
+{
+ nifti_1_header nhdr, * hptr;
+ znzFile fp;
+ int bytes, lswap;
+ char * hfile;
+ char fname[] = { "nifti_read_header" };
+
+ /* determine file name to use for header */
+ hfile = nifti_findhdrname(hname);
+ if( hfile == NULL ){
+ if( g_opts.debug > 0 )
+ LNI_FERR(fname,"failed to find header file for", hname);
+ return NULL;
+ } else if( g_opts.debug > 1 )
+ REprintf("-d %s: found header filename '%s'\n",fname,hfile);
+
+ fp = znzopen( hfile, "rb", nifti_is_gzfile(hfile) );
+ if( znz_isnull(fp) ){
+ if( g_opts.debug > 0 ) LNI_FERR(fname,"failed to open header file",hfile);
+ free(hfile);
+ return NULL;
+ }
+
+ free(hfile); /* done with filename */
+
+ if( has_ascii_header(fp) == 1 ){
+ znzclose( fp );
+ if( g_opts.debug > 0 )
+ LNI_FERR(fname,"ASCII header type not supported",hname);
+ return NULL;
+ }
+
+ /* read the binary header */
+ bytes = (int)znzread( &nhdr, 1, sizeof(nhdr), fp );
+ znzclose( fp ); /* we are done with the file now */
+
+ if( bytes < (int)sizeof(nhdr) ){
+ if( g_opts.debug > 0 ){
+ LNI_FERR(fname,"bad binary header read for file", hname);
+ REprintf(" - read %d of %d bytes\n",bytes, (int)sizeof(nhdr));
+ }
+ return NULL;
+ }
+
+ /* now just decide on byte swapping */
+ lswap = need_nhdr_swap(nhdr.dim[0], nhdr.sizeof_hdr); /* swap data flag */
+ if( check && lswap < 0 ){
+ LNI_FERR(fname,"bad nifti_1_header for file", hname);
+ return NULL;
+ } else if ( lswap < 0 ) {
+ lswap = 0; /* if swapping does not help, don't do it */
+ if(g_opts.debug > 1) REprintf("-- swap failure, none applied\n");
+ }
+
+ if( lswap ) {
+ if ( g_opts.debug > 3 ) disp_nifti_1_header("-d nhdr pre-swap: ", &nhdr);
+ swap_nifti_header( &nhdr , NIFTI_VERSION(nhdr) ) ;
+ }
+
+ if ( g_opts.debug > 2 ) disp_nifti_1_header("-d nhdr post-swap: ", &nhdr);
+
+ if ( check && ! nifti_hdr_looks_good(&nhdr) ){
+ LNI_FERR(fname,"nifti_1_header looks bad for file", hname);
+ return NULL;
+ }
+
+ /* all looks good, so allocate memory for and return the header */
+ hptr = (nifti_1_header *)malloc(sizeof(nifti_1_header));
+ if( ! hptr ){
+ REprintf("** nifti_read_hdr: failed to alloc nifti_1_header\n");
+ return NULL;
+ }
+
+ if( swapped ) *swapped = lswap; /* only if they care <sniff!> */
+
+ memcpy(hptr, &nhdr, sizeof(nifti_1_header));
+
+ return hptr;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! decide if this nifti_1_header structure looks reasonable
+
+ Check dim[0], dim[1], sizeof_hdr, and datatype.
+ Check magic string for "n+1".
+ Maybe more tests will follow.
+
+ \return 1 if the header seems valid, 0 otherwise
+
+ \sa nifti_nim_is_valid, valid_nifti_extensions
+*//*--------------------------------------------------------------------*/
+int nifti_hdr_looks_good(const nifti_1_header * hdr)
+{
+ int is_nifti, c, errs = 0;
+
+ /* check dim[0] and sizeof_hdr */
+ if( need_nhdr_swap(hdr->dim[0], hdr->sizeof_hdr) < 0 ){
+ if( g_opts.debug > 0 )
+ REprintf("** bad nhdr fields: dim0, sizeof_hdr = %d, %d\n",
+ hdr->dim[0], hdr->sizeof_hdr);
+ errs++;
+ }
+
+ /* check the valid dimension sizes (maybe dim[0] is bad) */
+ for( c = 1; c <= hdr->dim[0] && c <= 7; c++ )
+ if( hdr->dim[c] <= 0 ){
+ if( g_opts.debug > 0 )
+ REprintf("** bad nhdr field: dim[%d] = %d\n",c,hdr->dim[c]);
+ errs++;
+ }
+
+ is_nifti = NIFTI_VERSION(*hdr); /* determine header type */
+
+ if( is_nifti ){ /* NIFTI */
+
+ if( ! nifti_datatype_is_valid(hdr->datatype, 1) ){
+ if( g_opts.debug > 0 )
+ REprintf("** bad NIFTI datatype in hdr, %d\n",hdr->datatype);
+ errs++;
+ }
+
+ } else { /* ANALYZE 7.5 */
+
+ if( g_opts.debug > 1 ) /* maybe tell user it's an ANALYZE hdr */
+ REprintf(
+ "-- nhdr magic field implies ANALYZE: magic = '%.4s'\n",hdr->magic);
+
+ if( ! nifti_datatype_is_valid(hdr->datatype, 0) ){
+ if( g_opts.debug > 0 )
+ REprintf("** bad ANALYZE datatype in hdr, %d\n",hdr->datatype);
+ errs++;
+ }
+ }
+
+ if( errs ) return 0; /* problems */
+
+ if( g_opts.debug > 2 ) REprintf("-d nifti header looks good\n");
+
+ return 1; /* looks good */
+}
+
+
+/*----------------------------------------------------------------------
+ * check whether byte swapping is needed
+ *
+ * dim[0] should be in [0,7], and sizeof_hdr should be accurate
+ *
+ * \returns > 0 : needs swap
+ * 0 : does not need swap
+ * < 0 : error condition
+ *----------------------------------------------------------------------*/
+static int need_nhdr_swap( short dim0, int hdrsize )
+{
+ short d0 = dim0; /* so we won't have to swap them on the stack */
+ int hsize = hdrsize;
+
+ if( d0 != 0 ){ /* then use it for the check */
+ if( d0 > 0 && d0 <= 7 ) return 0;
+
+ nifti_swap_2bytes(1, &d0); /* swap? */
+ if( d0 > 0 && d0 <= 7 ) return 1;
+
+ if( g_opts.debug > 1 ){
+ REprintf("** NIFTI: bad swapped d0 = %d, unswapped = ", d0);
+ nifti_swap_2bytes(1, &d0); /* swap? */
+ REprintf("%d\n", d0);
+ }
+
+ return -1; /* bad, naughty d0 */
+ }
+
+ /* dim[0] == 0 should not happen, but could, so try hdrsize */
+ if( hsize == sizeof(nifti_1_header) ) return 0;
+
+ nifti_swap_4bytes(1, &hsize); /* swap? */
+ if( hsize == sizeof(nifti_1_header) ) return 1;
+
+ if( g_opts.debug > 1 ){
+ REprintf("** NIFTI: bad swapped hsize = %d, unswapped = ", hsize);
+ nifti_swap_4bytes(1, &hsize); /* swap? */
+ REprintf("%d\n", hsize);
+ }
+
+ return -2; /* bad, naughty hsize */
+}
+
+
+/* use macro LNI_FILE_ERROR instead of ERREX()
+#undef ERREX
+#define ERREX(msg) \
+ do{ fprintf(stderr,"** ERROR: nifti_image_read(%s): %s\n", \
+ (hname != NULL) ? hname : "(null)" , (msg) ) ; \
+ return NULL ; } while(0)
+*/
+
+
+/***************************************************************
+ * nifti_image_read
+ ***************************************************************/
+/*! \brief Read a nifti header and optionally the data, creating a nifti_image.
+
+ - The data buffer will be byteswapped if necessary.
+ - The data buffer will not be scaled.
+ - The data buffer is allocated with calloc().
+
+ \param hname filename of the nifti dataset
+ \param read_data Flag, true=read data blob, false=don't read blob.
+ \return A pointer to the nifti_image data structure.
+
+ \sa nifti_image_free, nifti_free_extensions, nifti_image_read_bricks
+*/
+nifti_image *nifti_image_read_NaN( const char *hname , int read_data , int rmNaN)
+{
+ struct nifti_1_header nhdr ;
+ nifti_image *nim ;
+ znzFile fp ;
+ int rv, ii , filesize, remaining;
+ char fname[] = { "nifti_image_read_NaN" };
+ char *hfile=NULL;
+
+ if( g_opts.debug > 1 ){
+ REprintf("-d image_read from '%s', read_data = %d",hname,read_data);
+#ifdef HAVE_LIBZ
+ REprintf(", HAVE_LIBZ = 1\n");
+#else
+ REprintf(", HAVE_LIBZ = 0\n");
+#endif
+ }
+
+ /**- determine filename to use for header */
+ hfile = nifti_findhdrname(hname);
+ if( hfile == NULL ){
+ if(g_opts.debug > 0)
+ LNI_FERR(fname,"failed to find header file for", hname);
+ return NULL; /* check return */
+ } else if( g_opts.debug > 1 )
+ REprintf("-d %s: found header filename '%s'\n",fname,hfile);
+
+ if( nifti_is_gzfile(hfile) ) filesize = -1; /* unknown */
+ else filesize = nifti_get_filesize(hfile);
+
+ fp = znzopen(hfile, "rb", nifti_is_gzfile(hfile));
+ if( znz_isnull(fp) ){
+ if( g_opts.debug > 0 ) LNI_FERR(fname,"failed to open header file",hfile);
+ free(hfile);
+ return NULL;
+ }
+
+ rv = has_ascii_header( fp );
+ if( rv < 0 ){
+ if( g_opts.debug > 0 ) LNI_FERR(fname,"short header read",hfile);
+ znzclose( fp );
+ free(hfile);
+ return NULL;
+ }
+ else if ( rv == 1 ) /* process special file type */
+ return nifti_read_ascii_image( fp, hfile, filesize, read_data );
+
+ /* else, just process normally */
+
+ /**- read binary header */
+
+ ii = (int)znzread( &nhdr , 1 , sizeof(nhdr) , fp ) ; /* read the thing */
+
+ /* keep file open so we can check for exts. after nifti_convert_nhdr2nim() */
+
+ if( ii < (int) sizeof(nhdr) ){
+ if( g_opts.debug > 0 ){
+ LNI_FERR(fname,"bad binary header read for file", hfile);
+ REprintf(" - read %d of %d bytes\n",ii, (int)sizeof(nhdr));
+ }
+ znzclose(fp) ;
+ free(hfile);
+ return NULL;
+ }
+
+ /* create output image struct and set it up */
+
+ /**- convert all nhdr fields to nifti_image fields */
+ nim = nifti_convert_nhdr2nim(nhdr,hfile);
+
+ if( nim == NULL ){
+ znzclose( fp ) ; /* close the file */
+ if( g_opts.debug > 0 )
+ LNI_FERR(fname,"cannot create nifti image from header",hfile);
+ free(hfile); /* had to save this for debug message */
+ return NULL;
+ }
+
+ if( g_opts.debug > 3 ){
+ REprintf("+d nifti_image_read(), have nifti image:\n");
+ if( g_opts.debug > 2 ) nifti_image_infodump(nim);
+ }
+
+ /**- check for extensions (any errors here means no extensions) */
+ if( NIFTI_ONEFILE(nhdr) ) remaining = nim->iname_offset - sizeof(nhdr);
+ else remaining = filesize - sizeof(nhdr);
+
+ (void)nifti_read_extensions(nim, fp, remaining);
+
+ znzclose( fp ) ; /* close the file */
+ free(hfile);
+
+ /**- read the data if desired, then bug out */
+ if( read_data ){
+ if( nifti_image_load_NaN( nim , rmNaN) < 0 ){
+ nifti_image_free(nim); /* take ball, go home. */
+ return NULL;
+ }
+ }
+ else nim->data = NULL ;
+
+ return nim ;
+}
+
+/***************************************************************
+ * nifti_image_read
+ ***************************************************************/
+/*! \brief Read a nifti header and optionally the data, creating a nifti_image.
+
+ - The data buffer will be byteswapped if necessary.
+ - The data buffer will not be scaled.
+ - The data buffer is allocated with calloc().
+
+ \param hname filename of the nifti dataset
+ \param read_data Flag, true=read data blob, false=don't read blob.
+ \return A pointer to the nifti_image data structure.
+
+ \sa nifti_image_free, nifti_free_extensions, nifti_image_read_bricks
+*/
+nifti_image *nifti_image_read( const char *hname , int read_data)
+{
+ return nifti_image_read_NaN( hname , read_data, 1);
+}
+
+/*----------------------------------------------------------------------
+ * has_ascii_header - see if the NIFTI header is an ASCII format
+ *
+ * If the file starts with the ASCII string "<nifti_image", then
+ * process the dataset as a type-3 .nia file.
+ *
+ * return: -1 on error, 1 if true, or 0 if false
+ *
+ * NOTE: this is NOT part of the NIFTI-1 standard
+ *----------------------------------------------------------------------*/
+static int has_ascii_header( znzFile fp )
+{
+ char buf[16];
+ int nread;
+
+ if( znz_isnull(fp) ) return 0;
+
+ nread = (int)znzread( buf, 1, 12, fp );
+ buf[12] = '\0';
+
+ if( nread < 12 ) return -1;
+
+ znzrewind(fp); /* move back to the beginning, and check */
+
+ if( strcmp(buf, "<nifti_image") == 0 ) return 1;
+
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! nifti_read_ascii_image - process as a type-3 .nia image file
+
+ return NULL on failure
+
+ NOTE: this is NOT part of the NIFTI-1 standard
+*//*--------------------------------------------------------------------*/
+nifti_image * nifti_read_ascii_image(znzFile fp, char *fname, int flen,
+ int read_data)
+{
+ nifti_image * nim;
+ int slen, txt_size, remain, rv = 0;
+ char * sbuf, lfunc[25] = { "nifti_read_ascii_image" };
+
+ if( nifti_is_gzfile(fname) ){
+ LNI_FERR(lfunc,"compression not supported for file type NIFTI_FTYPE_ASCII",
+ fname);
+ free(fname); znzclose(fp); return NULL;
+ }
+ slen = flen; /* slen will be our buffer length */
+
+ if( g_opts.debug > 1 )
+ REprintf("-d %s: have ASCII NIFTI file of size %d\n",fname,slen);
+
+ if( slen > 65530 ) slen = 65530 ;
+ sbuf = (char *)calloc(sizeof(char),slen+1) ;
+ if( !sbuf ){
+ REprintf("** %s: failed to alloc %d bytes for sbuf",lfunc,65530);
+ free(fname); znzclose(fp); return NULL;
+ }
+ znzread( sbuf , 1 , slen , fp ) ;
+ nim = nifti_image_from_ascii( sbuf, &txt_size ) ; free( sbuf ) ;
+ if( nim == NULL ){
+ LNI_FERR(lfunc,"failed nifti_image_from_ascii()",fname);
+ free(fname); znzclose(fp); return NULL;
+ }
+ nim->nifti_type = NIFTI_FTYPE_ASCII ;
+
+ /* compute remaining space for extensions */
+ remain = flen - txt_size - (int)nifti_get_volsize(nim);
+ if( remain > 4 ){
+ /* read extensions (reposition file pointer, first) */
+ znzseek(fp, txt_size, SEEK_SET);
+ (void) nifti_read_extensions(nim, fp, remain);
+ }
+
+ free(fname);
+ znzclose( fp ) ;
+
+ nim->iname_offset = -1 ; /* check from the end of the file */
+
+ if( read_data ) rv = nifti_image_load( nim ) ;
+ else nim->data = NULL ;
+
+ /* check for nifti_image_load() failure, maybe bail out */
+ if( read_data && rv != 0 ){
+ if( g_opts.debug > 1 )
+ REprintf("-d failed image_load, free nifti image struct\n");
+ free(nim);
+ return NULL;
+ }
+
+ return nim ;
+}
+
+
+/*----------------------------------------------------------------------
+ * Read the extensions into the nifti_image struct 08 Dec 2004 [rickr]
+ *
+ * This function is called just after the header struct is read in, and
+ * it is assumed the file pointer has not moved. The value in remain
+ * is assumed to be accurate, reflecting the bytes of space for potential
+ * extensions.
+ *
+ * return the number of extensions read in, or < 0 on error
+ *----------------------------------------------------------------------*/
+static int nifti_read_extensions( nifti_image *nim, znzFile fp, int remain )
+{
+ nifti1_extender extdr; /* defines extension existence */
+ nifti1_extension extn; /* single extension to process */
+ nifti1_extension * Elist; /* list of processed extensions */
+ int posn, count;
+
+ if( !nim || znz_isnull(fp) ) {
+ if( g_opts.debug > 0 )
+ REprintf("** nifti_read_extensions: bad inputs (%p,%p)\n",
+ (void *)nim, (void *)fp);
+ return -1;
+ }
+
+ posn = znztell(fp);
+
+ if( (posn != sizeof(nifti_1_header)) &&
+ (nim->nifti_type != NIFTI_FTYPE_ASCII) )
+ REprintf("** WARNING: posn not header size (%d, %d)\n",
+ posn, (int)sizeof(nifti_1_header));
+
+ if( g_opts.debug > 2 )
+ REprintf("-d nre: posn = %d, offset = %d, type = %d, remain = %d\n",
+ posn, nim->iname_offset, nim->nifti_type, remain);
+
+ if( remain < 16 ){
+ if( g_opts.debug > 2 ){
+ if( g_opts.skip_blank_ext )
+ REprintf("-d no extender in '%s' is okay, as "
+ "skip_blank_ext is set\n",nim->fname);
+ else
+ REprintf("-d remain=%d, no space for extensions\n",remain);
+ }
+ return 0;
+ }
+
+ count = (int)znzread( extdr.extension, 1, 4, fp ); /* get extender */
+
+ if( count < 4 ){
+ if( g_opts.debug > 1 )
+ REprintf("-d file '%s' is too short for an extender\n",
+ nim->fname);
+ return 0;
+ }
+
+ if( extdr.extension[0] != 1 ){
+ if( g_opts.debug > 2 )
+ REprintf("-d extender[0] (%d) shows no extensions for '%s'\n",
+ extdr.extension[0], nim->fname);
+ return 0;
+ }
+
+ remain -= 4;
+ if( g_opts.debug > 2 )
+ REprintf("-d found valid 4-byte extender, remain = %d\n", remain);
+
+ /* so we expect extensions, but have no idea of how many there may be */
+
+ count = 0;
+ Elist = NULL;
+ while (nifti_read_next_extension(&extn, nim, remain, fp) > 0)
+ {
+ if( nifti_add_exten_to_list(&extn, &Elist, count+1) < 0 ){
+ if( g_opts.debug > 0 )
+ REprintf("** failed adding ext %d to list\n", count);
+ return -1;
+ }
+
+ /* we have a new extension */
+ if( g_opts.debug > 1 ){
+ REprintf("+d found extension #%d, code = 0x%x, size = %d\n",
+ count, extn.ecode, extn.esize);
+ if( extn.ecode == NIFTI_ECODE_AFNI && g_opts.debug > 2 ) /* ~XML */
+ REprintf(" AFNI extension: %.*s\n",
+ extn.esize-8,extn.edata);
+ else if( extn.ecode == NIFTI_ECODE_COMMENT && g_opts.debug > 2 )
+ REprintf(" COMMENT extension: %.*s\n", /* TEXT */
+ extn.esize-8,extn.edata);
+ }
+ remain -= extn.esize;
+ count++;
+ }
+
+ if( g_opts.debug > 2 ) REprintf("+d found %d extension(s)\n", count);
+
+ nim->num_ext = count;
+ nim->ext_list = Elist;
+
+ return count;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! nifti_add_extension - add an extension, with a copy of the data
+
+ Add an extension to the nim->ext_list array.
+ Fill this extension with a copy of the data, noting the
+ length and extension code.
+
+ \param nim - nifti_image to add extension to
+ \param data - raw extension data
+ \param length - length of raw extension data
+ \param ecode - extension code
+
+ \sa extension codes NIFTI_ECODE_* in nifti1_io.h
+ \sa nifti_free_extensions, valid_nifti_extensions, nifti_copy_extensions
+
+ \return 0 on success, -1 on error (and free the entire list)
+*//*--------------------------------------------------------------------*/
+int nifti_add_extension(nifti_image *nim, const char * data, int len, int ecode)
+{
+ nifti1_extension ext;
+
+ /* error are printed in functions */
+ if( nifti_fill_extension(&ext, data, len, ecode) ) return -1;
+ if( nifti_add_exten_to_list(&ext, &nim->ext_list, nim->num_ext+1)) return -1;
+
+ nim->num_ext++; /* success, so increment */
+
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------*/
+/* nifti_add_exten_to_list - add a new nifti1_extension to the list
+
+ We will append via "malloc, copy and free", because on an error,
+ the list will revert to the previous one (sorry realloc(), only
+ quality dolphins get to become part of St at rk!st brand tunafish).
+
+ return 0 on success, -1 on error (and free the entire list)
+*//*--------------------------------------------------------------------*/
+static int nifti_add_exten_to_list( nifti1_extension * new_ext,
+ nifti1_extension ** list, int new_length )
+{
+ nifti1_extension * tmplist;
+
+ tmplist = *list;
+ *list = (nifti1_extension *)malloc(new_length * sizeof(nifti1_extension));
+
+ /* check for failure first */
+ if( ! *list ){
+ REprintf("** failed to alloc %d extension structs (%d bytes)\n",
+ new_length, new_length*(int)sizeof(nifti1_extension));
+ if( !tmplist ) return -1; /* no old list to lose */
+
+ *list = tmplist; /* reset list to old one */
+ return -1;
+ }
+
+ /* if an old list exists, copy the pointers and free the list */
+ if( tmplist ){
+ memcpy(*list, tmplist, (new_length-1)*sizeof(nifti1_extension));
+ free(tmplist);
+ }
+
+ /* for some reason, I just don't like struct copy... */
+ (*list)[new_length-1].esize = new_ext->esize;
+ (*list)[new_length-1].ecode = new_ext->ecode;
+ (*list)[new_length-1].edata = new_ext->edata;
+
+ if( g_opts.debug > 2 )
+ REprintf("+d allocated and appended extension #%d to list\n",
+ new_length);
+
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------*/
+/* nifti_fill_extension - given data and length, fill an extension struct
+
+ Allocate memory for data, copy data, set the size and code.
+
+ return 0 on success, -1 on error (and free the entire list)
+*//*--------------------------------------------------------------------*/
+static int nifti_fill_extension( nifti1_extension *ext, const char * data,
+ int len, int ecode)
+{
+ int esize;
+
+ if( !ext || !data || len < 0 ){
+ REprintf("** fill_ext: bad params (%p,%p,%d)\n",
+ (void *)ext, data, len);
+ return -1;
+ } else if( ! nifti_is_valid_ecode(ecode) ){
+ REprintf("** fill_ext: invalid ecode %d\n", ecode);
+ return -1;
+ }
+
+ /* compute esize, first : len+8, and take ceiling up to a mult of 16 */
+ esize = len+8;
+ if( esize & 0xf ) esize = (esize + 0xf) & ~0xf;
+ ext->esize = esize;
+
+ /* allocate esize-8 (maybe more than len), using calloc for fill */
+ ext->edata = (char *)calloc(esize-8, sizeof(char));
+ if( !ext->edata ){
+ REprintf("** NFE: failed to alloc %d bytes for extension\n",len);
+ return -1;
+ }
+
+ memcpy(ext->edata, data, len); /* copy the data, using len */
+ ext->ecode = ecode; /* set the ecode */
+
+ if( g_opts.debug > 2 )
+ REprintf("+d alloc %d bytes for ext len %d, ecode %d, esize %d\n",
+ esize-8, len, ecode, esize);
+
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------
+ * nifti_read_next_extension - read a single extension from the file
+ *
+ * return (>= 0 is okay):
+ *
+ * success : esize
+ * no extension : 0
+ * error : -1
+ *----------------------------------------------------------------------*/
+static int nifti_read_next_extension( nifti1_extension * nex, nifti_image *nim,
+ int remain, znzFile fp )
+{
+ int swap = nim->byteorder != nifti_short_order();
+ int count, size, code;
+
+ /* first clear nex */
+ nex->esize = nex->ecode = 0;
+ nex->edata = NULL;
+
+ if( remain < 16 ){
+ if( g_opts.debug > 2 )
+ REprintf("-d only %d bytes remain, so no extension\n", remain);
+ return 0;
+ }
+
+ /* must start with 4-byte size and code */
+ count = (int)znzread( &size, 4, 1, fp );
+ if( count == 1 ) count += (int)znzread( &code, 4, 1, fp );
+
+ if( count != 2 ){
+ if( g_opts.debug > 2 )
+ REprintf("-d current extension read failed\n");
+ znzseek(fp, -4*count, SEEK_CUR); /* back up past any read */
+ return 0; /* no extension, no error condition */
+ }
+
+ if( swap ){
+ if( g_opts.debug > 2 )
+ REprintf("-d pre-swap exts: code %d, size %d\n", code, size);
+
+ nifti_swap_4bytes(1, &size);
+ nifti_swap_4bytes(1, &code);
+ }
+
+ if( g_opts.debug > 2 )
+ REprintf("-d potential extension: code %d, size %d\n", code, size);
+
+ if( !nifti_check_extension(nim, size, code, remain) ){
+ if( znzseek(fp, -8, SEEK_CUR) < 0 ){ /* back up past any read */
+ REprintf("** failure to back out of extension read!\n");
+ return -1;
+ }
+ return 0;
+ }
+
+ /* now get the actual data */
+ nex->esize = size;
+ nex->ecode = code;
+
+ size -= 8; /* subtract space for size and code in extension */
+ nex->edata = (char *)malloc(size * sizeof(char));
+ if( !nex->edata ){
+ REprintf("** failed to allocate %d bytes for extension\n",size);
+ return -1;
+ }
+
+ count = (int)znzread(nex->edata, 1, size, fp);
+ if( count < size ){
+ if( g_opts.debug > 0 )
+ REprintf("-d read only %d (of %d) bytes for extension\n",
+ count, size);
+ free(nex->edata);
+ nex->edata = NULL;
+ return -1;
+ }
+
+ /* success! */
+ if( g_opts.debug > 2 )
+ REprintf("+d successfully read extension, code %d, size %d\n",
+ nex->ecode, nex->esize);
+
+ return nex->esize;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! for each extension, check code, size and data pointer
+*//*--------------------------------------------------------------------*/
+int valid_nifti_extensions(const nifti_image * nim)
+{
+ nifti1_extension * ext;
+ int c, errs;
+
+ if( nim->num_ext <= 0 || nim->ext_list == NULL ){
+ if( g_opts.debug > 2 ) REprintf("-d empty extension list\n");
+ return 0;
+ }
+
+ /* for each extension, check code, size and data pointer */
+ ext = nim->ext_list;
+ errs = 0;
+ for ( c = 0; c < nim->num_ext; c++ ){
+ if( ! nifti_is_valid_ecode(ext->ecode) ) {
+ if( g_opts.debug > 1 )
+ REprintf("-d ext %d, invalid code %d\n", c, ext->ecode);
+ errs++;
+ }
+
+ if( ext->esize <= 0 ){
+ if( g_opts.debug > 1 )
+ REprintf("-d ext %d, bad size = %d\n", c, ext->esize);
+ errs++;
+ } else if( ext->esize & 0xf ){
+ if( g_opts.debug > 1 )
+ REprintf("-d ext %d, size %d not multiple of 16\n",
+ c, ext->esize);
+ errs++;
+ }
+
+ if( ext->edata == NULL ){
+ if( g_opts.debug > 1 ) REprintf("-d ext %d, missing data\n", c);
+ errs++;
+ }
+
+ ext++;
+ }
+
+ if( errs > 0 ){
+ if( g_opts.debug > 0 )
+ REprintf("-d had %d extension errors, none will be written\n",
+ errs);
+ return 0;
+ }
+
+ /* if we're here, we're good */
+ return 1;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! check whether the extension code is valid
+
+ \return 1 if valid, 0 otherwise
+*//*--------------------------------------------------------------------*/
+int nifti_is_valid_ecode( int ecode )
+{
+ if( ecode < NIFTI_ECODE_IGNORE || /* minimum code number (0) */
+ ecode > NIFTI_MAX_ECODE || /* maximum code number */
+ ecode & 1 ) /* cannot be odd */
+ return 0;
+
+ return 1;
+}
+
+
+/*----------------------------------------------------------------------
+ * check for valid size and code, as well as can be done
+ *----------------------------------------------------------------------*/
+static int nifti_check_extension(nifti_image *nim, int size, int code, int rem)
+{
+ /* check for bad code before bad size */
+ if( ! nifti_is_valid_ecode(code) ) {
+ if( g_opts.debug > 2 )
+ REprintf("-d invalid extension code %d\n",code);
+ return 0;
+ }
+
+ if( size < 16 ){
+ if( g_opts.debug > 2 )
+ REprintf("-d ext size %d, no extension\n",size);
+ return 0;
+ }
+
+ if( size > rem ){
+ if( g_opts.debug > 2 )
+ REprintf("-d ext size %d, space %d, no extension\n", size, rem);
+ return 0;
+ }
+
+ if( size & 0xf ){
+ if( g_opts.debug > 2 )
+ REprintf("-d nifti extension size %d not multiple of 16\n",size);
+ return 0;
+ }
+
+ if( nim->nifti_type == NIFTI_FTYPE_ASCII && size > LNI_MAX_NIA_EXT_LEN ){
+ if( g_opts.debug > 2 )
+ REprintf("-d NVE, bad nifti_type 3 size %d\n", size);
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/*----------------------------------------------------------------------
+ * nifti_image_load_prep - prepare to read data
+ *
+ * Check nifti_image fields, open the file and seek to the appropriate
+ * offset for reading.
+ *
+ * return NULL on failure
+ *----------------------------------------------------------------------*/
+static znzFile nifti_image_load_prep( nifti_image *nim )
+{
+ /* set up data space, open data file and seek, then call nifti_read_buffer */
+ size_t ntot , ii , ioff;
+ znzFile fp;
+ char *tmpimgname;
+ char fname[] = { "nifti_image_load_prep" };
+
+ /**- perform sanity checks */
+ if( nim == NULL || nim->iname == NULL ||
+ nim->nbyper <= 0 || nim->nvox <= 0 )
+ {
+ if ( g_opts.debug > 0 ){
+ if( !nim ) REprintf("** ERROR: N_image_load: no nifti image\n");
+ else REprintf("** ERROR: N_image_load: bad params (%p,%d,%u)\n",
+ nim->iname, nim->nbyper, (unsigned)nim->nvox);
+ }
+ return NULL;
+ }
+
+ ntot = nifti_get_volsize(nim) ; /* total bytes to read */
+
+ /**- open image data file */
+
+ tmpimgname = nifti_findimgname(nim->iname , nim->nifti_type);
+ if( tmpimgname == NULL ){
+ if( g_opts.debug > 0 )
+ REprintf("** no image file found for '%s'\n",nim->iname);
+ return NULL;
+ }
+
+ fp = znzopen(tmpimgname, "rb", nifti_is_gzfile(tmpimgname));
+ if (znz_isnull(fp)){
+ if(g_opts.debug > 0) LNI_FERR(fname,"cannot open data file",tmpimgname);
+ free(tmpimgname);
+ return NULL; /* bad open? */
+ }
+ free(tmpimgname);
+
+ /**- get image offset: a negative offset means to figure from end of file */
+ if( nim->iname_offset < 0 ){
+ if( nifti_is_gzfile(nim->iname) ){
+ if( g_opts.debug > 0 )
+ LNI_FERR(fname,"negative offset for compressed file",nim->iname);
+ znzclose(fp);
+ return NULL;
+ }
+ ii = nifti_get_filesize( nim->iname ) ;
+ if( ii <= 0 ){
+ if( g_opts.debug > 0 ) LNI_FERR(fname,"empty data file",nim->iname);
+ znzclose(fp);
+ return NULL;
+ }
+ ioff = (ii > ntot) ? ii-ntot : 0 ;
+ } else { /* non-negative offset */
+ ioff = nim->iname_offset ; /* means use it directly */
+ }
+
+ /**- seek to the appropriate read position */
+ if( znzseek(fp , (long)ioff , SEEK_SET) < 0 ){
+ REprintf("** could not seek to offset %u in file '%s'\n",
+ (unsigned)ioff, nim->iname);
+ znzclose(fp);
+ return NULL;
+ }
+
+ /**- and return the File pointer */
+ return fp;
+}
+
+
+/*----------------------------------------------------------------------
+ * nifti_image_load
+ *----------------------------------------------------------------------*/
+/*! \fn int nifti_image_load( nifti_image *nim )
+ \brief Load the image blob into a previously initialized nifti_image.
+
+ - If not yet set, the data buffer is allocated with calloc().
+ - The data buffer will be byteswapped if necessary.
+ - The data buffer will not be scaled.
+
+ This function is used to read the image from disk. It should be used
+ after a function such as nifti_image_read(), so that the nifti_image
+ structure is already initialized.
+
+ \param nim pointer to a nifti_image (previously initialized)
+ \return 0 on success, -1 on failure
+ \sa nifti_image_read, nifti_image_free, nifti_image_unload
+*/
+int nifti_image_load_NaN( nifti_image *nim , int rmNaN)
+{
+ /* set up data space, open data file and seek, then call nifti_read_buffer */
+ size_t ntot , ii ;
+ znzFile fp ;
+
+ /**- open the file and position the FILE pointer */
+ fp = nifti_image_load_prep( nim );
+
+ if( fp == NULL ){
+ if( g_opts.debug > 0 )
+ REprintf("** nifti_image_load, failed load_prep\n");
+ return -1;
+ }
+
+ ntot = nifti_get_volsize(nim);
+
+ /**- if the data pointer is not yet set, get memory space for the image */
+
+ if( nim->data == NULL )
+ {
+ nim->data = (void *)calloc(1,ntot) ; /* create image memory */
+ if( nim->data == NULL ){
+ if( g_opts.debug > 0 )
+ REprintf("** failed to alloc %d bytes for image data\n",
+ (int)ntot);
+ znzclose(fp);
+ return -1;
+ }
+ }
+
+ /**- now that everything is set up, do the reading */
+ ii = nifti_read_buffer_NaN(fp,nim->data,ntot,nim, rmNaN);
+ if( ii < ntot ){
+ znzclose(fp) ;
+ free(nim->data) ;
+ nim->data = NULL ;
+ return -1 ; /* errors were printed in nifti_read_buffer() */
+ }
+
+ /**- close the file */
+ znzclose( fp ) ;
+
+ return 0 ;
+}
+
+/*----------------------------------------------------------------------
+ * nifti_image_load
+ *----------------------------------------------------------------------*/
+/*! \fn int nifti_image_load( nifti_image *nim )
+ \brief Load the image blob into a previously initialized nifti_image.
+
+ - If not yet set, the data buffer is allocated with calloc().
+ - The data buffer will be byteswapped if necessary.
+ - The data buffer will not be scaled.
+
+ This function is used to read the image from disk. It should be used
+ after a function such as nifti_image_read(), so that the nifti_image
+ structure is already initialized.
+
+ \param nim pointer to a nifti_image (previously initialized)
+ \return 0 on success, -1 on failure
+ \sa nifti_image_read, nifti_image_free, nifti_image_unload
+*/
+int nifti_image_load( nifti_image *nim)
+{
+ return nifti_image_load_NaN( nim , 1);
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! read ntot bytes of data from an open file and byte swaps if necessary
+
+ note that nifti_image is required for information on datatype, bsize
+ (for any needed byte swapping), etc.
+
+ This function does not allocate memory, so dataptr must be valid.
+*//*--------------------------------------------------------------------*/
+size_t nifti_read_buffer_NaN(znzFile fp, void* dataptr, size_t ntot,
+ nifti_image *nim, int rmNaN)
+{
+ size_t ii;
+
+ if( dataptr == NULL ){
+ if( g_opts.debug > 0 )
+ REprintf("** ERROR: nifti_read_buffer: NULL dataptr\n");
+ return -1;
+ }
+
+ ii = znzread( dataptr , 1 , ntot , fp ) ; /* data input */
+
+ /* if read was short, fail */
+ if( ii < ntot ){
+ if( g_opts.debug > 0 )
+ REprintf("++ WARNING: nifti_read_buffer(%s):\n"
+ " data bytes needed = %u\n"
+ " data bytes input = %u\n"
+ " number missing = %u (set to 0)\n",
+ nim->iname , (unsigned int)ntot ,
+ (unsigned int)ii , (unsigned int)(ntot-ii) ) ;
+ /* memset( (char *)(dataptr)+ii , 0 , ntot-ii ) ; now failure [rickr] */
+ return -1 ;
+ }
+
+ if( g_opts.debug > 2 )
+ REprintf("+d nifti_read_buffer: read %u bytes\n", (unsigned)ii);
+
+ /* byte swap array if needed */
+
+ /* ntot/swapsize might not fit as int, use size_t 6 Jul 2010 [rickr] */
+ if( nim->swapsize > 1 && nim->byteorder != nifti_short_order() ) {
+ if( g_opts.debug > 1 )
+ REprintf("+d nifti_read_buffer: swapping data bytes...\n");
+ nifti_swap_Nbytes( ntot / nim->swapsize, nim->swapsize , dataptr ) ;
+ }
+
+#ifdef isfinite
+if(rmNaN)
+{
+ /* check input float arrays for goodness, and fix bad floats */
+ int fix_count = 0 ;
+
+ switch( nim->datatype ){
+
+ case NIFTI_TYPE_FLOAT32:
+ case NIFTI_TYPE_COMPLEX64:{
+ register float *far = (float *)dataptr ; register size_t jj,nj ;
+ nj = ntot / sizeof(float) ;
+ for( jj=0 ; jj < nj ; jj++ ) /* count fixes 30 Nov 2004 [rickr] */
+ if( !IS_GOOD_FLOAT(far[jj]) ){
+ far[jj] = 0 ;
+ fix_count++ ;
+ }
+ }
+ break ;
+
+ case NIFTI_TYPE_FLOAT64:
+ case NIFTI_TYPE_COMPLEX128:{
+ register double *far = (double *)dataptr ; register size_t jj,nj ;
+ nj = ntot / sizeof(double) ;
+ for( jj=0 ; jj < nj ; jj++ ) /* count fixes 30 Nov 2004 [rickr] */
+ if( !IS_GOOD_FLOAT(far[jj]) ){
+ far[jj] = 0 ;
+ fix_count++ ;
+ }
+ }
+ break ;
+
+ }
+
+ if( g_opts.debug > 1 )
+ REprintf("+d in image, %d bad floats were set to 0\n", fix_count);
+}
+
+#endif
+
+ return ii;
+}
+
+size_t nifti_read_buffer(znzFile fp, void* dataptr, size_t ntot,
+ nifti_image *nim)
+{
+ return nifti_read_buffer_NaN(fp, dataptr, ntot, nim, 1); // call new function with NaN flag support!
+}
+
+
+
+
+/*--------------------------------------------------------------------------*/
+/*! Unload the data in a nifti_image struct, but keep the metadata.
+*//*------------------------------------------------------------------------*/
+void nifti_image_unload( nifti_image *nim )
+{
+ if( nim != NULL && nim->data != NULL ){
+ free(nim->data) ; nim->data = NULL ;
+ }
+ return ;
+}
+
+/*--------------------------------------------------------------------------*/
+/*! free 'everything' about a nifti_image struct (including the passed struct)
+
+ free (only fields which are not NULL):
+ - fname and iname
+ - data
+ - any ext_list[i].edata
+ - ext_list
+ - nim
+*//*------------------------------------------------------------------------*/
+void nifti_image_free( nifti_image *nim )
+{
+ if( nim == NULL ) return ;
+ if( nim->fname != NULL ) free(nim->fname) ;
+ if( nim->iname != NULL ) free(nim->iname) ;
+ if( nim->data != NULL ) free(nim->data ) ;
+ (void)nifti_free_extensions( nim ) ;
+ free(nim) ; return ;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/*! free the nifti extensions
+
+ - If any edata pointer is set in the extension list, free() it.
+ - Free ext_list, if it is set.
+ - Clear num_ext and ext_list from nim.
+
+ \return 0 on success, -1 on error
+
+ \sa nifti_add_extension, nifti_copy_extensions
+*//*------------------------------------------------------------------------*/
+int nifti_free_extensions( nifti_image *nim )
+{
+ int c ;
+ if( nim == NULL ) return -1;
+ if( nim->num_ext > 0 && nim->ext_list ){
+ for( c = 0; c < nim->num_ext; c++ )
+ if ( nim->ext_list[c].edata ) free(nim->ext_list[c].edata);
+ free(nim->ext_list);
+ }
+ /* or if it is inconsistent, warn the user (if we are not in quiet mode) */
+ else if ( (nim->num_ext > 0 || nim->ext_list != NULL) && (g_opts.debug > 0) )
+ REprintf("** warning: nifti extension num/ptr mismatch (%d,%p)\n",
+ nim->num_ext, (void *)nim->ext_list);
+
+ if( g_opts.debug > 2 )
+ REprintf("+d free'd %d extension(s)\n", nim->num_ext);
+
+ nim->num_ext = 0;
+ nim->ext_list = NULL;
+
+ return 0;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/*! Print to stdout some info about a nifti_image struct.
+*//*------------------------------------------------------------------------*/
+void nifti_image_infodump( const nifti_image *nim )
+{
+ char *str = nifti_image_to_ascii( nim ) ;
+ /* stdout -> stderr 2 Dec 2004 [rickr] */
+ if( str != NULL ){ REprintf(str); /*fputs(str,stderr)*/ ; free(str) ; }
+ return ;
+}
+
+
+/*--------------------------------------------------------------------------
+ * nifti_write_buffer just check for a null znzFile and call znzwrite
+ *--------------------------------------------------------------------------*/
+/*! \fn size_t nifti_write_buffer(znzFile fp, void *buffer, size_t numbytes)
+ \brief write numbytes of buffer to file, fp
+
+ \param fp File pointer (from znzopen) to gzippable nifti datafile
+ \param buffer data buffer to be written
+ \param numbytes number of bytes in buffer to write
+ \return number of bytes successfully written
+*/
+size_t nifti_write_buffer(znzFile fp, const void *buffer, size_t numbytes)
+{
+ /* Write all the image data at once (no swapping here) */
+ size_t ss;
+ if (znz_isnull(fp)){
+ REprintf("** ERROR: nifti_write_buffer: null file pointer\n");
+ return 0;
+ }
+ ss = znzwrite( (void*)buffer , 1 , numbytes , fp ) ;
+ return ss;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! write the nifti_image data to file (from nim->data or from NBL)
+
+ If NBL is not NULL, write the data from that structure. Otherwise,
+ write it out from nim->data. No swapping is done here.
+
+ \param fp : File pointer
+ \param nim : nifti_image corresponding to the data
+ \param NBL : optional source of write data (if NULL use nim->data)
+
+ \return 0 on success, -1 on failure
+
+ Note: the nifti_image byte_order is set as that of the current CPU.
+ This is because such a conversion was made to the data upon
+ reading, while byte_order was not set (so the programs would
+ know what format the data was on disk). Effectively, since
+ byte_order should match what is on disk, it should bet set to
+ that of the current CPU whenever new filenames are assigned.
+*//*--------------------------------------------------------------------*/
+int nifti_write_all_data(znzFile fp, nifti_image * nim,
+ const nifti_brick_list * NBL)
+{
+ size_t ss;
+ int bnum;
+
+ if( !NBL ){ /* just write one buffer and get out of here */
+ if( nim->data == NULL ){
+ REprintf("** NWAD: no image data to write\n");
+ return -1;
+ }
+
+ ss = nifti_write_buffer(fp,nim->data,nim->nbyper * nim->nvox);
+ if (ss < nim->nbyper * nim->nvox){
+ REprintf(
+ "** ERROR: NWAD: wrote only %u of %u bytes to file\n",
+ (unsigned)ss, (unsigned)(nim->nbyper * nim->nvox));
+ return -1;
+ }
+
+ if( g_opts.debug > 1 )
+ REprintf("+d wrote single image of %u bytes\n", (unsigned)ss);
+ } else {
+ if( ! NBL->bricks || NBL->nbricks <= 0 || NBL->bsize <= 0 ){
+ REprintf("** NWAD: no brick data to write (%p,%d,%u)\n",
+ (void *)NBL->bricks, NBL->nbricks, (unsigned)NBL->bsize);
+ return -1;
+ }
+
+ for( bnum = 0; bnum < NBL->nbricks; bnum++ ){
+ ss = nifti_write_buffer(fp, NBL->bricks[bnum], NBL->bsize);
+ if( ss < NBL->bsize ){
+ REprintf(
+ "** NWAD ERROR: wrote %u of %u bytes of brick %d of %d to file",
+ (unsigned)ss, (unsigned)NBL->bsize, bnum+1, NBL->nbricks);
+ return -1;
+ }
+ }
+ if( g_opts.debug > 1 )
+ REprintf("+d wrote image of %d brick(s), each of %u bytes\n",
+ NBL->nbricks, (unsigned int)NBL->bsize);
+ }
+
+ /* mark as being in this CPU byte order */
+ nim->byteorder = nifti_short_order() ;
+
+ return 0;
+}
+
+/* return number of extensions written, or -1 on error */
+static int nifti_write_extensions(znzFile fp, nifti_image *nim)
+{
+ nifti1_extension * list;
+ char extdr[4] = { 0, 0, 0, 0 };
+ int c, size, ok = 1;
+
+ if( znz_isnull(fp) || !nim || nim->num_ext < 0 ){
+ if( g_opts.debug > 0 )
+ REprintf("** nifti_write_extensions, bad params\n");
+ return -1;
+ }
+
+ /* if no extensions and user requests it, skip extender */
+ if( g_opts.skip_blank_ext && (nim->num_ext == 0 || ! nim->ext_list ) ){
+ if( g_opts.debug > 1 )
+ REprintf("-d no exts and skip_blank_ext set, "
+ "so skipping 4-byte extender\n");
+ return 0;
+ }
+
+ /* if invalid extension list, clear num_ext */
+ if( ! valid_nifti_extensions(nim) ) nim->num_ext = 0;
+
+ /* write out extender block */
+ if( nim->num_ext > 0 ) extdr[0] = 1;
+ if( nifti_write_buffer(fp, extdr, 4) != 4 ){
+ REprintf("** failed to write extender\n");
+ return -1;
+ }
+
+ list = nim->ext_list;
+ for ( c = 0; c < nim->num_ext; c++ ){
+ size = (int)nifti_write_buffer(fp, &list->esize, sizeof(int));
+ ok = (size == (int)sizeof(int));
+ if( ok ){
+ size = (int)nifti_write_buffer(fp, &list->ecode, sizeof(int));
+ ok = (size == (int)sizeof(int));
+ }
+ if( ok ){
+ size = (int)nifti_write_buffer(fp, list->edata, list->esize - 8);
+ ok = (size == list->esize - 8);
+ }
+
+ if( !ok ){
+ REprintf("** failed while writing extension #%d\n",c);
+ return -1;
+ } else if ( g_opts.debug > 2 )
+ REprintf("+d wrote extension %d of %d bytes\n", c, size);
+
+ list++;
+ }
+
+ if( g_opts.debug > 1 )
+ REprintf("+d wrote out %d extension(s)\n", nim->num_ext);
+
+ return nim->num_ext;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! basic initialization of a nifti_image struct (to a 1x1x1 image)
+*//*--------------------------------------------------------------------*/
+nifti_image* nifti_simple_init_nim(void)
+{
+ nifti_image *nim;
+ struct nifti_1_header nhdr;
+ int nbyper, swapsize;
+
+ memset(&nhdr,0,sizeof(nhdr)) ; /* zero out header, to be safe */
+
+ nhdr.sizeof_hdr = sizeof(nhdr) ;
+ nhdr.regular = 'r' ; /* for some stupid reason */
+
+ nhdr.dim[0] = 3 ;
+ nhdr.dim[1] = 1 ; nhdr.dim[2] = 1 ; nhdr.dim[3] = 1 ;
+ nhdr.dim[4] = 0 ;
+
+ nhdr.pixdim[0] = 0.0 ;
+ nhdr.pixdim[1] = 1.0 ; nhdr.pixdim[2] = 1.0 ;
+ nhdr.pixdim[3] = 1.0 ;
+
+ nhdr.datatype = DT_FLOAT32 ;
+ nifti_datatype_sizes( nhdr.datatype , &nbyper, &swapsize );
+ nhdr.bitpix = 8 * nbyper ;
+
+ strcpy(nhdr.magic, "n+1"); /* init to single file */
+
+ nim = nifti_convert_nhdr2nim(nhdr,NULL);
+ nim->fname = NULL;
+ nim->iname = NULL;
+ return nim;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! basic initialization of a nifti_1_header struct (with given dimensions)
+
+ Return an allocated nifti_1_header struct, based on the given
+ dimensions and datatype.
+
+ \param arg_dims : optional dim[8] array (default {3,1,1,1,0,0,0,0})
+ \param arg_dtype : optional datatype (default DT_FLOAT32)
+
+ \return pointer to allocated nifti_1_header struct
+*//*--------------------------------------------------------------------*/
+nifti_1_header * nifti_make_new_header(const int arg_dims[], int arg_dtype)
+{
+ nifti_1_header * nhdr;
+ const int default_dims[8] = { 3, 1, 1, 1, 0, 0, 0, 0 };
+ const int * dim; /* either passed or default dims */
+ int dtype; /* either passed or default dtype */
+ int c, nbyper, swapsize;
+
+ /* if arg_dims is passed, apply it */
+ if( arg_dims ) dim = arg_dims;
+ else dim = default_dims;
+
+ /* validate dim: if there is any problem, apply default_dims */
+ if( dim[0] < 1 || dim[0] > 7 ) {
+ REprintf("** nifti_simple_hdr_with_dims: bad dim[0]=%d\n",dim[0]);
+ dim = default_dims;
+ } else {
+ for( c = 1; c <= dim[0]; c++ )
+ if( dim[c] < 1 )
+ {
+ REprintf(
+ "** nifti_simple_hdr_with_dims: bad dim[%d]=%d\n",c,dim[c]);
+ dim = default_dims;
+ break;
+ }
+ }
+
+ /* validate dtype, too */
+ dtype = arg_dtype;
+ if( ! nifti_is_valid_datatype(dtype) ) {
+ REprintf("** nifti_simple_hdr_with_dims: bad dtype %d\n",dtype);
+ dtype = DT_FLOAT32;
+ }
+
+ /* now populate the header struct */
+
+ if( g_opts.debug > 1 )
+ REprintf("+d nifti_make_new_header, dim[0] = %d, datatype = %d\n",
+ dim[0], dtype);
+
+ nhdr = (nifti_1_header *)calloc(1,sizeof(nifti_1_header));
+ if( !nhdr ){
+ REprintf("** nifti_make_new_header: failed to alloc hdr\n");
+ return NULL;
+ }
+
+ nhdr->sizeof_hdr = sizeof(nifti_1_header) ;
+ nhdr->regular = 'r' ; /* for some stupid reason */
+
+ /* init dim and pixdim */
+ nhdr->dim[0] = dim[0] ;
+ nhdr->pixdim[0] = 0.0;
+ for( c = 1; c <= dim[0]; c++ ) {
+ nhdr->dim[c] = dim[c];
+ nhdr->pixdim[c] = 1.0;
+ }
+
+ nhdr->datatype = dtype ;
+ nifti_datatype_sizes( nhdr->datatype , &nbyper, &swapsize );
+ nhdr->bitpix = 8 * nbyper ;
+
+ strcpy(nhdr->magic, "n+1"); /* init to single file */
+
+ return nhdr;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! basic creation of a nifti_image struct
+
+ Create a nifti_image from the given dimensions and data type.
+ Optinally, allocate zero-filled data.
+
+ \param dims : optional dim[8] (default {3,1,1,1,0,0,0,0})
+ \param datatype : optional datatype (default DT_FLOAT32)
+ \param data_fill : if flag is set, allocate zero-filled data for image
+
+ \return pointer to allocated nifti_image struct
+*//*--------------------------------------------------------------------*/
+nifti_image * nifti_make_new_nim(const int dims[], int datatype, int data_fill)
+{
+ nifti_image * nim;
+ nifti_1_header * nhdr;
+
+ nhdr = nifti_make_new_header(dims, datatype);
+ if( !nhdr ) return NULL; /* error already printed */
+
+ nim = nifti_convert_nhdr2nim(*nhdr,NULL);
+ free(nhdr); /* in any case, we are done with this */
+ if( !nim ){
+ REprintf("** NMNN: nifti_convert_nhdr2nim failure\n");
+ return NULL;
+ }
+
+ if( g_opts.debug > 1 )
+ REprintf("+d nifti_make_new_nim, data_fill = %d\n",data_fill);
+
+ if( data_fill ) {
+ nim->data = calloc(nim->nvox, nim->nbyper);
+
+ /* if we cannot allocate data, take ball and go home */
+ if( !nim->data ) {
+ REprintf("** NMNN: failed to alloc %u bytes for data\n",
+ (unsigned)(nim->nvox*nim->nbyper));
+ nifti_image_free(nim);
+ nim = NULL;
+ }
+ }
+
+ return nim;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! convert a nifti_image structure to a nifti_1_header struct
+
+ No allocation is done, this should be used via structure copy.
+ As in:
+ <pre>
+ nifti_1_header my_header;
+ my_header = nifti_convert_nim2nhdr(my_nim_pointer);
+ </pre>
+*//*--------------------------------------------------------------------*/
+struct nifti_1_header nifti_convert_nim2nhdr(const nifti_image * nim)
+{
+ struct nifti_1_header nhdr;
+
+ memset(&nhdr,0,sizeof(nhdr)) ; /* zero out header, to be safe */
+
+
+ /**- load the ANALYZE-7.5 generic parts of the header struct */
+
+ nhdr.sizeof_hdr = sizeof(nhdr) ;
+ nhdr.regular = 'r' ; /* for some stupid reason */
+
+ nhdr.dim[0] = nim->ndim ;
+ nhdr.dim[1] = nim->nx ; nhdr.dim[2] = nim->ny ; nhdr.dim[3] = nim->nz ;
+ nhdr.dim[4] = nim->nt ; nhdr.dim[5] = nim->nu ; nhdr.dim[6] = nim->nv ;
+ nhdr.dim[7] = nim->nw ;
+
+ nhdr.pixdim[0] = 0.0 ;
+ nhdr.pixdim[1] = nim->dx ; nhdr.pixdim[2] = nim->dy ;
+ nhdr.pixdim[3] = nim->dz ; nhdr.pixdim[4] = nim->dt ;
+ nhdr.pixdim[5] = nim->du ; nhdr.pixdim[6] = nim->dv ;
+ nhdr.pixdim[7] = nim->dw ;
+
+ nhdr.datatype = nim->datatype ;
+ nhdr.bitpix = 8 * nim->nbyper ;
+
+ if( nim->cal_max > nim->cal_min ){
+ nhdr.cal_max = nim->cal_max ;
+ nhdr.cal_min = nim->cal_min ;
+ }
+
+ if( nim->scl_slope != 0.0 ){
+ nhdr.scl_slope = nim->scl_slope ;
+ nhdr.scl_inter = nim->scl_inter ;
+ }
+
+ if( nim->descrip[0] != '\0' ){
+ memcpy(nhdr.descrip ,nim->descrip ,79) ; nhdr.descrip[79] = '\0' ;
+ }
+ if( nim->aux_file[0] != '\0' ){
+ memcpy(nhdr.aux_file ,nim->aux_file ,23) ; nhdr.aux_file[23] = '\0' ;
+ }
+
+ /**- Load NIFTI specific stuff into the header */
+
+ if( nim->nifti_type > NIFTI_FTYPE_ANALYZE ){ /* then not ANALYZE */
+
+ if( nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ) strcpy(nhdr.magic,"n+1") ;
+ else strcpy(nhdr.magic,"ni1") ;
+
+ nhdr.pixdim[1] = fabs(nhdr.pixdim[1]) ; nhdr.pixdim[2] = fabs(nhdr.pixdim[2]) ;
+ nhdr.pixdim[3] = fabs(nhdr.pixdim[3]) ; nhdr.pixdim[4] = fabs(nhdr.pixdim[4]) ;
+ nhdr.pixdim[5] = fabs(nhdr.pixdim[5]) ; nhdr.pixdim[6] = fabs(nhdr.pixdim[6]) ;
+ nhdr.pixdim[7] = fabs(nhdr.pixdim[7]) ;
+
+ nhdr.intent_code = nim->intent_code ;
+ nhdr.intent_p1 = nim->intent_p1 ;
+ nhdr.intent_p2 = nim->intent_p2 ;
+ nhdr.intent_p3 = nim->intent_p3 ;
+ if( nim->intent_name[0] != '\0' ){
+ memcpy(nhdr.intent_name,nim->intent_name,15) ;
+ nhdr.intent_name[15] = '\0' ;
+ }
+
+ nhdr.vox_offset = (float) nim->iname_offset ;
+ nhdr.xyzt_units = SPACE_TIME_TO_XYZT( nim->xyz_units, nim->time_units ) ;
+ nhdr.toffset = nim->toffset ;
+
+ if( nim->qform_code > 0 ){
+ nhdr.qform_code = nim->qform_code ;
+ nhdr.quatern_b = nim->quatern_b ;
+ nhdr.quatern_c = nim->quatern_c ;
+ nhdr.quatern_d = nim->quatern_d ;
+ nhdr.qoffset_x = nim->qoffset_x ;
+ nhdr.qoffset_y = nim->qoffset_y ;
+ nhdr.qoffset_z = nim->qoffset_z ;
+ nhdr.pixdim[0] = (nim->qfac >= 0.0) ? 1.0 : -1.0 ;
+ }
+
+ if( nim->sform_code > 0 ){
+ nhdr.sform_code = nim->sform_code ;
+ nhdr.srow_x[0] = nim->sto_xyz.m[0][0] ;
+ nhdr.srow_x[1] = nim->sto_xyz.m[0][1] ;
+ nhdr.srow_x[2] = nim->sto_xyz.m[0][2] ;
+ nhdr.srow_x[3] = nim->sto_xyz.m[0][3] ;
+ nhdr.srow_y[0] = nim->sto_xyz.m[1][0] ;
+ nhdr.srow_y[1] = nim->sto_xyz.m[1][1] ;
+ nhdr.srow_y[2] = nim->sto_xyz.m[1][2] ;
+ nhdr.srow_y[3] = nim->sto_xyz.m[1][3] ;
+ nhdr.srow_z[0] = nim->sto_xyz.m[2][0] ;
+ nhdr.srow_z[1] = nim->sto_xyz.m[2][1] ;
+ nhdr.srow_z[2] = nim->sto_xyz.m[2][2] ;
+ nhdr.srow_z[3] = nim->sto_xyz.m[2][3] ;
+ }
+
+ nhdr.dim_info = FPS_INTO_DIM_INFO( nim->freq_dim ,
+ nim->phase_dim , nim->slice_dim ) ;
+ nhdr.slice_code = nim->slice_code ;
+ nhdr.slice_start = nim->slice_start ;
+ nhdr.slice_end = nim->slice_end ;
+ nhdr.slice_duration = nim->slice_duration ;
+ }
+
+ return nhdr;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! \fn int nifti_copy_extensions(nifti_image * nim_dest, nifti_image * nim_src)
+ \brief copy the nifti1_extension list from src to dest
+
+ Duplicate the list of nifti1_extensions. The dest structure must
+ be clear of extensions.
+ \return 0 on success, -1 on failure
+
+ \sa nifti_add_extension, nifti_free_extensions
+*/
+int nifti_copy_extensions(nifti_image * nim_dest, const nifti_image * nim_src)
+{
+ char * data;
+ size_t bytes;
+ int c, size, old_size;
+
+ if( nim_dest->num_ext > 0 || nim_dest->ext_list != NULL ){
+ REprintf("** will not copy extensions over existing ones\n");
+ return -1;
+ }
+
+ if( g_opts.debug > 1 )
+ REprintf("+d duplicating %d extension(s)\n", nim_src->num_ext);
+
+ if( nim_src->num_ext <= 0 ) return 0;
+
+ bytes = nim_src->num_ext * sizeof(nifti1_extension); /* I'm lazy */
+ nim_dest->ext_list = (nifti1_extension *)malloc(bytes);
+ if( !nim_dest->ext_list ){
+ REprintf("** failed to allocate %d nifti1_extension structs\n",
+ nim_src->num_ext);
+ return -1;
+ }
+
+ /* copy the extension data */
+ nim_dest->num_ext = 0;
+ for( c = 0; c < nim_src->num_ext; c++ ){
+ size = old_size = nim_src->ext_list[c].esize;
+ if( size & 0xf ) size = (size + 0xf) & ~0xf; /* make multiple of 16 */
+ if( g_opts.debug > 2 )
+ REprintf("+d dup'ing ext #%d of size %d (from size %d)\n",
+ c, size, old_size);
+ /* data length is size-8, as esize includes space for esize and ecode */
+ data = (char *)calloc(size-8,sizeof(char)); /* maybe size > old */
+ if( !data ){
+ REprintf("** failed to alloc %d bytes for extention\n", size);
+ if( c == 0 ) { free(nim_dest->ext_list); nim_dest->ext_list = NULL; }
+ /* otherwise, keep what we have (a.o.t. deleting them all) */
+ return -1;
+ }
+ /* finally, fill the new structure */
+ nim_dest->ext_list[c].esize = size;
+ nim_dest->ext_list[c].ecode = nim_src->ext_list[c].ecode;
+ nim_dest->ext_list[c].edata = data;
+ memcpy(data, nim_src->ext_list[c].edata, old_size-8);
+
+ nim_dest->num_ext++;
+ }
+
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! compute the total size of all extensions
+
+ \return the total of all esize fields
+
+ Note that each esize includes 4 bytes for ecode, 4 bytes for esize,
+ and the bytes used for the data. Each esize also needs to be a
+ multiple of 16, so it may be greater than the sum of its 3 parts.
+*//*--------------------------------------------------------------------*/
+int nifti_extension_size(nifti_image *nim)
+{
+ int c, size = 0;
+
+ if( !nim || nim->num_ext <= 0 ) return 0;
+
+ if( g_opts.debug > 2 ) REprintf("-d ext sizes:");
+
+ for ( c = 0; c < nim->num_ext; c++ ){
+ size += nim->ext_list[c].esize;
+ if( g_opts.debug > 2 ) REprintf(" %d",nim->ext_list[c].esize);
+ }
+
+ if( g_opts.debug > 2 ) REprintf(" (total = %d)\n",size);
+
+ return size;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! set the nifti_image iname_offset field, based on nifti_type
+
+ - if writing to 2 files, set offset to 0
+ - if writing to a single NIFTI-1 file, set the offset to
+ 352 + total extension size, then align to 16-byte boundary
+ - if writing an ASCII header, set offset to -1
+*//*--------------------------------------------------------------------*/
+void nifti_set_iname_offset(nifti_image *nim)
+{
+ int offset;
+
+ switch( nim->nifti_type ){
+
+ default: /* writing into 2 files */
+ /* we only write files with 0 offset in the 2 file format */
+ nim->iname_offset = 0 ;
+ break ;
+
+ /* NIFTI-1 single binary file - always update */
+ case NIFTI_FTYPE_NIFTI1_1:
+ offset = nifti_extension_size(nim)+sizeof(struct nifti_1_header)+4;
+ /* be sure offset is aligned to a 16 byte boundary */
+ if ( ( offset % 16 ) != 0 ) offset = ((offset + 0xf) & ~0xf);
+ if( nim->iname_offset != offset ){
+ if( g_opts.debug > 1 )
+ REprintf("+d changing offset from %d to %d\n",
+ nim->iname_offset, offset);
+ nim->iname_offset = offset;
+ }
+ break ;
+
+ /* non-standard case: NIFTI-1 ASCII header + binary data (single file) */
+ case NIFTI_FTYPE_ASCII:
+ nim->iname_offset = -1 ; /* compute offset from filesize */
+ break ;
+ }
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! write the nifti_image dataset to disk, optionally including data
+
+ This is just a front-end for nifti_image_write_hdr_img2.
+
+ \param nim nifti_image to write to disk
+ \param write_data write options (see nifti_image_write_hdr_img2)
+ \param opts file open options ("wb" from nifti_image_write)
+
+ \sa nifti_image_write, nifti_image_write_hdr_img2, nifti_image_free,
+ nifti_set_filenames
+*//*--------------------------------------------------------------------*/
+znzFile nifti_image_write_hdr_img( nifti_image *nim , int write_data ,
+ const char* opts )
+{
+ return nifti_image_write_hdr_img2(nim,write_data,opts,NULL,NULL);
+}
+
+
+#undef ERREX
+#define ERREX(msg) \
+ do{ REprintf("** ERROR: nifti_image_write_hdr_img: %s\n",(msg)) ; \
+ return fp ; } while(0)
+
+
+/* ----------------------------------------------------------------------*/
+/*! This writes the header (and optionally the image data) to file
+ *
+ * If the image data file is left open it returns a valid znzFile handle.
+ * It also uses imgfile as the open image file is not null, and modifies
+ * it inside.
+ *
+ * \param nim nifti_image to write to disk
+ * \param write_opts flags whether to write data and/or close file (see below)
+ * \param opts file-open options, probably "wb" from nifti_image_write()
+ * \param imgfile optional open znzFile struct, for writing image data
+ (may be NULL)
+ * \param NBL optional nifti_brick_list, containing the image data
+ (may be NULL)
+ *
+ * Values for write_opts mode are based on two binary flags
+ * ( 0/1 for no-write/write data, and 0/2 for close/leave-open files ) :
+ * - 0 = do not write data and close (do not open data file)
+ * - 1 = write data and close
+ * - 2 = do not write data and leave data file open
+ * - 3 = write data and leave data file open
+ *
+ * \sa nifti_image_write, nifti_image_write_hdr_img, nifti_image_free,
+ * nifti_set_filenames
+*//*---------------------------------------------------------------------*/
+znzFile nifti_image_write_hdr_img2(nifti_image *nim, int write_opts,
+ const char * opts, znzFile imgfile, const nifti_brick_list * NBL)
+{
+ struct nifti_1_header nhdr ;
+ znzFile fp=NULL;
+ size_t ss ;
+ int write_data, leave_open;
+ char func[] = { "nifti_image_write_hdr_img2" };
+
+ write_data = write_opts & 1; /* just separate the bits now */
+ leave_open = write_opts & 2;
+
+ if( ! nim ) ERREX("NULL input") ;
+ if( ! nifti_validfilename(nim->fname) ) ERREX("bad fname input") ;
+ if( write_data && ! nim->data && ! NBL ) ERREX("no image data") ;
+
+ if( write_data && NBL && ! nifti_NBL_matches_nim(nim, NBL) )
+ ERREX("NBL does not match nim");
+
+ nifti_set_iname_offset(nim);
+
+ if( g_opts.debug > 1 ){
+ REprintf("-d writing nifti file '%s'...\n", nim->fname);
+ if( g_opts.debug > 2 )
+ REprintf("-d nifti type %d, offset %d\n",
+ nim->nifti_type, nim->iname_offset);
+ }
+
+ if( nim->nifti_type == NIFTI_FTYPE_ASCII ) /* non-standard case */
+ return nifti_write_ascii_image(nim,NBL,opts,write_data,leave_open);
+
+ nhdr = nifti_convert_nim2nhdr(nim); /* create the nifti1_header struct */
+
+ /* if writing to 2 files, make sure iname is set and different from fname */
+ if( nim->nifti_type != NIFTI_FTYPE_NIFTI1_1 ){
+ if( nim->iname && strcmp(nim->iname,nim->fname) == 0 ){
+ free(nim->iname) ; nim->iname = NULL ;
+ }
+ if( nim->iname == NULL ){ /* then make a new one */
+ nim->iname = nifti_makeimgname(nim->fname,nim->nifti_type,0,0);
+ if( nim->iname == NULL ) return NULL;
+ }
+ }
+
+ /* if we have an imgfile and will write the header there, use it */
+ if( ! znz_isnull(imgfile) && nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ){
+ if( g_opts.debug > 2 ) REprintf("+d using passed file for hdr\n");
+ fp = imgfile;
+ }
+ else {
+ if( g_opts.debug > 2 )
+ REprintf("+d opening output file %s [%s]\n",nim->fname,opts);
+ fp = znzopen( nim->fname , opts , nifti_is_gzfile(nim->fname) ) ;
+ if( znz_isnull(fp) ){
+ LNI_FERR(func,"cannot open output file",nim->fname);
+ return fp;
+ }
+ }
+
+ /* write the header and extensions */
+
+ ss = znzwrite(&nhdr , 1 , sizeof(nhdr) , fp); /* write header */
+ if( ss < sizeof(nhdr) ){
+ LNI_FERR(func,"bad header write to output file",nim->fname);
+ znzclose(fp); return fp;
+ }
+
+ /* partial file exists, and errors have been printed, so ignore return */
+ if( nim->nifti_type != NIFTI_FTYPE_ANALYZE )
+ (void)nifti_write_extensions(fp,nim);
+
+ /* if the header is all we want, we are done */
+ if( ! write_data && ! leave_open ){
+ if( g_opts.debug > 2 ) REprintf("-d header is all we want: done\n");
+ znzclose(fp); return(fp);
+ }
+
+ if( nim->nifti_type != NIFTI_FTYPE_NIFTI1_1 ){ /* get a new file pointer */
+ znzclose(fp); /* first, close header file */
+ if( ! znz_isnull(imgfile) ){
+ if(g_opts.debug > 2) REprintf("+d using passed file for img\n");
+ fp = imgfile;
+ }
+ else {
+ if( g_opts.debug > 2 )
+ REprintf("+d opening img file '%s'\n", nim->iname);
+ fp = znzopen( nim->iname , opts , nifti_is_gzfile(nim->iname) ) ;
+ if( znz_isnull(fp) ) ERREX("cannot open image file") ;
+ }
+ }
+
+ znzseek(fp, nim->iname_offset, SEEK_SET); /* in any case, seek to offset */
+
+ if( write_data ) nifti_write_all_data(fp,nim,NBL);
+ if( ! leave_open ) znzclose(fp);
+
+ return fp;
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! write a nifti_image to disk in ASCII format
+*//*--------------------------------------------------------------------*/
+znzFile nifti_write_ascii_image(nifti_image *nim, const nifti_brick_list * NBL,
+ const char *opts, int write_data, int leave_open)
+{
+ znzFile fp;
+ char * hstr;
+
+ hstr = nifti_image_to_ascii( nim ) ; /* get header in ASCII form */
+ if( ! hstr ){ REprintf("** failed image_to_ascii()\n"); return NULL; }
+
+ fp = znzopen( nim->fname , opts , nifti_is_gzfile(nim->fname) ) ;
+ if( znz_isnull(fp) ){
+ free(hstr);
+ REprintf("** failed to open '%s' for ascii write\n",nim->fname);
+ return fp;
+ }
+
+ znzputs(hstr,fp); /* header */
+ nifti_write_extensions(fp,nim); /* extensions */
+
+ if ( write_data ) { nifti_write_all_data(fp,nim,NBL); } /* data */
+ if ( ! leave_open ) { znzclose(fp); }
+ free(hstr);
+ return fp; /* returned but may be closed */
+}
+
+
+/*--------------------------------------------------------------------------*/
+/*! Write a nifti_image to disk.
+
+ Since data is properly byte-swapped upon reading, it is assumed
+ to be in the byte-order of the current CPU at write time. Thus,
+ nim->byte_order should match that of the current CPU. Note that
+ the nifti_set_filenames() function takes the flag, set_byte_order.
+
+ The following fields of nim affect how the output appears:
+ - nifti_type = 0 ==> ANALYZE-7.5 format file pair will be written
+ - nifti_type = 1 ==> NIFTI-1 format single file will be written
+ (data offset will be 352+extensions)
+ - nifti_type = 2 ==> NIFTI_1 format file pair will be written
+ - nifti_type = 3 ==> NIFTI_1 ASCII single file will be written
+ - fname is the name of the output file (header or header+data)
+ - if a file pair is being written, iname is the name of the data file
+ - existing files WILL be overwritten with extreme prejudice
+ - if qform_code > 0, the quatern_*, qoffset_*, and qfac fields determine
+ the qform output, NOT the qto_xyz matrix; if you want to compute these
+ fields from the qto_xyz matrix, you can use the utility function
+ nifti_mat44_to_quatern()
+
+ \sa nifti_image_write_bricks, nifti_image_free, nifti_set_filenames,
+ nifti_image_write_hdr_img
+*//*------------------------------------------------------------------------*/
+void nifti_image_write( nifti_image *nim )
+{
+ znzFile fp = nifti_image_write_hdr_img(nim,1,"wb");
+ if( fp ){
+ if( g_opts.debug > 2 ) REprintf("-d niw: done with znzFile\n");
+ free(fp);
+ }
+ if( g_opts.debug > 1 ) REprintf("-d nifti_image_write: done\n");
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! similar to nifti_image_write, but data is in NBL struct, not nim->data
+
+ \sa nifti_image_write, nifti_image_free, nifti_set_filenames, nifti_free_NBL
+*//*--------------------------------------------------------------------*/
+void nifti_image_write_bricks( nifti_image *nim, const nifti_brick_list * NBL )
+{
+ znzFile fp = nifti_image_write_hdr_img2(nim,1,"wb",NULL,NBL);
+ if( fp ){
+ if( g_opts.debug > 2 ) REprintf("-d niwb: done with znzFile\n");
+ free(fp);
+ }
+ if( g_opts.debug > 1 ) REprintf("-d niwb: done writing bricks\n");
+}
+
+
+/*----------------------------------------------------------------------*/
+/*! copy the nifti_image structure, without data
+
+ Duplicate the structure, including fname, iname and extensions.
+ Leave the data pointer as NULL.
+*//*--------------------------------------------------------------------*/
+nifti_image * nifti_copy_nim_info(const nifti_image * src)
+{
+ nifti_image *dest;
+ dest = (nifti_image *)calloc(1,sizeof(nifti_image));
+ if( !dest ){
+ REprintf("** NCNI: failed to alloc nifti_image\n");
+ return NULL;
+ }
+ memcpy(dest, src, sizeof(nifti_image));
+ if( src->fname ) dest->fname = nifti_strdup(src->fname);
+ if( src->iname ) dest->iname = nifti_strdup(src->iname);
+ dest->num_ext = 0;
+ dest->ext_list = NULL;
+ /* errors will be printed in NCE(), continue in either case */
+ (void)nifti_copy_extensions(dest, src);
+
+ dest->data = NULL;
+
+ return dest;
+}
+
+
+/*------------------------------------------------------------------------*/
+/* Un-escape a C string in place -- that is, convert XML escape sequences
+ back into their characters. (This can be done in place since the
+ replacement is always smaller than the input.) Escapes recognized are:
+ - < -> <
+ - > -> >
+ - " -> "
+ - ' -> '
+ - & -> &
+ Also replace CR LF pair (Microsoft), or CR alone (Macintosh) with
+ LF (Unix), per the XML standard.
+ Return value is number of replacements made (if you care).
+--------------------------------------------------------------------------*/
+
+#undef CR
+#undef LF
+#define CR 0x0D
+#define LF 0x0A
+
+static int unescape_string( char *str )
+{
+ int ii,jj , nn,ll ;
+
+ if( str == NULL ) return 0 ; /* no string? */
+ ll = (int)strlen(str) ; if( ll == 0 ) return 0 ;
+
+ /* scan for escapes: &something; */
+
+ for( ii=jj=nn=0 ; ii<ll ; ii++,jj++ ){ /* scan at ii; results go in at jj */
+
+ if( str[ii] == '&' ){ /* start of escape? */
+
+ if( ii+3 < ll && /* < */
+ str[ii+1] == 'l' &&
+ str[ii+2] == 't' &&
+ str[ii+3] == ';' ){ str[jj] = '<' ; ii += 3 ; nn++ ; }
+
+ else if( ii+3 < ll && /* > */
+ str[ii+1] == 'g' &&
+ str[ii+2] == 't' &&
+ str[ii+3] == ';' ){ str[jj] = '>' ; ii += 3 ; nn++ ; }
+
+ else if( ii+5 < ll && /* " */
+ str[ii+1] == 'q' &&
+ str[ii+2] == 'u' &&
+ str[ii+3] == 'o' &&
+ str[ii+4] == 't' &&
+ str[ii+5] == ';' ){ str[jj] = '"' ; ii += 5 ; nn++ ; }
+
+ else if( ii+5 < ll && /* ' */
+ str[ii+1] == 'a' &&
+ str[ii+2] == 'p' &&
+ str[ii+3] == 'o' &&
+ str[ii+4] == 's' &&
+ str[ii+5] == ';' ){ str[jj] = '\'' ; ii += 5 ; nn++ ; }
+
+ else if( ii+4 < ll && /* & */
+ str[ii+1] == 'a' &&
+ str[ii+2] == 'm' &&
+ str[ii+3] == 'p' &&
+ str[ii+4] == ';' ){ str[jj] = '&' ; ii += 4 ; nn++ ; }
+
+ /* although the comments above don't mention it,
+ we also look for XML style numeric escapes
+ of the forms (decimal) and ý (hex) */
+
+ else if( ii+3 < ll &&
+ str[ii+1] == '#' &&
+ isdigit(str[ii+2]) ){ /* &#dec; */
+
+ unsigned int val='?' ; int kk=ii+3 ;
+ while( kk < ll && kk != ';' ) kk++ ;
+ sscanf( str+ii+2 , "%u" , &val ) ;
+ str[jj] = (char) val ; ii = kk ; nn++ ;
+ }
+
+ else if( ii+4 < ll &&
+ str[ii+1] == '#' &&
+ str[ii+2] == 'x' &&
+ isxdigit(str[ii+3]) ){ /* &#hex; */
+
+ unsigned int val='?' ; int kk=ii+4 ;
+ while( kk < ll && kk != ';' ) kk++ ;
+ sscanf( str+ii+3 , "%x" , &val ) ;
+ str[jj] = (char) val ; ii = kk ; nn++ ;
+ }
+
+ /* didn't start a recognized escape, so just copy as normal */
+
+ else if( jj < ii ){ str[jj] = str[ii] ; }
+
+ } else if( str[ii] == CR ) { /* is a carriage return */
+
+ if( str[ii+1] == LF ){ str[jj] = LF ; ii++ ; nn++ ; } /* CR LF */
+ else { str[jj] = LF ; ; nn++ ; } /* CR only */
+
+ } else { /* is a normal character, just copy to output */
+
+ if( jj < ii ){ str[jj] = str[ii] ; }
+ }
+
+ /* at this point, ii=index of last character used up in scan
+ jj=index of last character written to (jj <= ii) */
+ }
+
+ if( jj < ll ) str[jj] = '\0' ; /* end string properly */
+
+ return nn ;
+}
+
+/*------------------------------------------------------------------------*/
+/* Quotize (and escapize) one string, returning a new string.
+ Approximately speaking, this is the inverse of unescape_string().
+ The result should be free()-ed when you are done with it.
+--------------------------------------------------------------------------*/
+
+static char *escapize_string( const char * str )
+{
+ int ii,jj , lstr,lout ;
+ char *out ;
+
+ if( str == NULL || (lstr=(int)strlen(str)) == 0 ){ /* 0 length */
+ out = nifti_strdup("''") ; return out ; /* string?? */
+ }
+
+ lout = 4 ; /* initialize length of output */
+ for( ii=0 ; ii < lstr ; ii++ ){ /* count characters for output */
+ switch( str[ii] ){
+ case '&': lout += 5 ; break ; /* replace '&' with "&" */
+
+ case '<':
+ case '>': lout += 4 ; break ; /* replace '<' with "<" */
+
+ case '"' :
+ case '\'': lout += 6 ; break ; /* replace '"' with """ */
+
+ case CR:
+ case LF: lout += 6 ; break ; /* replace CR with "
"
+ LF with "
" */
+
+ default: lout++ ; break ; /* copy all other chars */
+ }
+ }
+ out = (char *)calloc(1,lout) ; /* allocate output string */
+ if( !out ){
+ REprintf("** escapize_string: failed to alloc %d bytes\n",lout);
+ return NULL;
+ }
+ out[0] = '\'' ; /* opening quote mark */
+ for( ii=0,jj=1 ; ii < lstr ; ii++ ){
+ switch( str[ii] ){
+ default: out[jj++] = str[ii] ; break ; /* normal characters */
+
+ case '&': memcpy(out+jj,"&",5) ; jj+=5 ; break ;
+
+ case '<': memcpy(out+jj,"<",4) ; jj+=4 ; break ;
+ case '>': memcpy(out+jj,">",4) ; jj+=4 ; break ;
+
+ case '"' : memcpy(out+jj,""",6) ; jj+=6 ; break ;
+
+ case '\'': memcpy(out+jj,"'",6) ; jj+=6 ; break ;
+
+ case CR: memcpy(out+jj,"
",6) ; jj+=6 ; break ;
+ case LF: memcpy(out+jj,"
",6) ; jj+=6 ; break ;
+ }
+ }
+ out[jj++] = '\'' ; /* closing quote mark */
+ out[jj] = '\0' ; /* terminate the string */
+ return out ;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! Dump the information in a NIFTI image header to an XML-ish ASCII string
+ that can later be converted back into a NIFTI header in
+ nifti_image_from_ascii().
+
+ The resulting string can be free()-ed when you are done with it.
+*//*-------------------------------------------------------------------------*/
+char *nifti_image_to_ascii( const nifti_image *nim )
+{
+ char *buf , *ebuf ; int nbuf ;
+
+ if( nim == NULL ) return NULL ; /* stupid caller */
+
+ buf = (char *)calloc(1,65534); nbuf = 0; /* longer than needed, to be safe */
+ if( !buf ){
+ REprintf("** NITA: failed to alloc %d bytes\n",65534);
+ return NULL;
+ }
+
+ sprintf( buf , "<nifti_image\n" ) ; /* XML-ish opener */
+
+ sprintf( buf+strlen(buf) , " nifti_type = '%s'\n" ,
+ (nim->nifti_type == NIFTI_FTYPE_NIFTI1_1) ? "NIFTI-1+"
+ :(nim->nifti_type == NIFTI_FTYPE_NIFTI1_2) ? "NIFTI-1"
+ :(nim->nifti_type == NIFTI_FTYPE_ASCII ) ? "NIFTI-1A"
+ : "ANALYZE-7.5" ) ;
+
+ /** Strings that we don't control (filenames, etc.) that might
+ contain "weird" characters (like quotes) are "escaped":
+ - A few special characters are replaced by XML-style escapes, using
+ the function escapize_string().
+ - On input, function unescape_string() reverses this process.
+ - The result is that the NIFTI ASCII-format header is XML-compliant. */
+
+ ebuf = escapize_string(nim->fname) ;
+ sprintf( buf+strlen(buf) , " header_filename = %s\n",ebuf); free(ebuf);
+
+ ebuf = escapize_string(nim->iname) ;
+ sprintf( buf+strlen(buf) , " image_filename = %s\n", ebuf); free(ebuf);
+
+ sprintf( buf+strlen(buf) , " image_offset = '%d'\n" , nim->iname_offset );
+
+ sprintf( buf+strlen(buf), " ndim = '%d'\n", nim->ndim);
+ sprintf( buf+strlen(buf), " nx = '%d'\n", nim->nx );
+ if( nim->ndim > 1 ) sprintf( buf+strlen(buf), " ny = '%d'\n", nim->ny );
+ if( nim->ndim > 2 ) sprintf( buf+strlen(buf), " nz = '%d'\n", nim->nz );
+ if( nim->ndim > 3 ) sprintf( buf+strlen(buf), " nt = '%d'\n", nim->nt );
+ if( nim->ndim > 4 ) sprintf( buf+strlen(buf), " nu = '%d'\n", nim->nu );
+ if( nim->ndim > 5 ) sprintf( buf+strlen(buf), " nv = '%d'\n", nim->nv );
+ if( nim->ndim > 6 ) sprintf( buf+strlen(buf), " nw = '%d'\n", nim->nw );
+ sprintf( buf+strlen(buf), " dx = '%g'\n", nim->dx );
+ if( nim->ndim > 1 ) sprintf( buf+strlen(buf), " dy = '%g'\n", nim->dy );
+ if( nim->ndim > 2 ) sprintf( buf+strlen(buf), " dz = '%g'\n", nim->dz );
+ if( nim->ndim > 3 ) sprintf( buf+strlen(buf), " dt = '%g'\n", nim->dt );
+ if( nim->ndim > 4 ) sprintf( buf+strlen(buf), " du = '%g'\n", nim->du );
+ if( nim->ndim > 5 ) sprintf( buf+strlen(buf), " dv = '%g'\n", nim->dv );
+ if( nim->ndim > 6 ) sprintf( buf+strlen(buf), " dw = '%g'\n", nim->dw );
+
+ sprintf( buf+strlen(buf) , " datatype = '%d'\n" , nim->datatype ) ;
+ sprintf( buf+strlen(buf) , " datatype_name = '%s'\n" ,
+ nifti_datatype_string(nim->datatype) ) ;
+
+ sprintf( buf+strlen(buf) , " nvox = '%u'\n" , (unsigned)nim->nvox ) ;
+ sprintf( buf+strlen(buf) , " nbyper = '%d'\n" , nim->nbyper ) ;
+
+ sprintf( buf+strlen(buf) , " byteorder = '%s'\n" ,
+ (nim->byteorder==MSB_FIRST) ? "MSB_FIRST" : "LSB_FIRST" ) ;
+
+ if( nim->cal_min < nim->cal_max ){
+ sprintf( buf+strlen(buf) , " cal_min = '%g'\n", nim->cal_min ) ;
+ sprintf( buf+strlen(buf) , " cal_max = '%g'\n", nim->cal_max ) ;
+ }
+
+ if( nim->scl_slope != 0.0 ){
+ sprintf( buf+strlen(buf) , " scl_slope = '%g'\n" , nim->scl_slope ) ;
+ sprintf( buf+strlen(buf) , " scl_inter = '%g'\n" , nim->scl_inter ) ;
+ }
+
+ if( nim->intent_code > 0 ){
+ sprintf( buf+strlen(buf) , " intent_code = '%d'\n", nim->intent_code ) ;
+ sprintf( buf+strlen(buf) , " intent_code_name = '%s'\n" ,
+ nifti_intent_string(nim->intent_code) ) ;
+ sprintf( buf+strlen(buf) , " intent_p1 = '%g'\n" , nim->intent_p1 ) ;
+ sprintf( buf+strlen(buf) , " intent_p2 = '%g'\n" , nim->intent_p2 ) ;
+ sprintf( buf+strlen(buf) , " intent_p3 = '%g'\n" , nim->intent_p3 ) ;
+
+ if( nim->intent_name[0] != '\0' ){
+ ebuf = escapize_string(nim->intent_name) ;
+ sprintf( buf+strlen(buf) , " intent_name = %s\n",ebuf) ;
+ free(ebuf) ;
+ }
+ }
+
+ if( nim->toffset != 0.0 )
+ sprintf( buf+strlen(buf) , " toffset = '%g'\n",nim->toffset ) ;
+
+ if( nim->xyz_units > 0 )
+ sprintf( buf+strlen(buf) ,
+ " xyz_units = '%d'\n"
+ " xyz_units_name = '%s'\n" ,
+ nim->xyz_units , nifti_units_string(nim->xyz_units) ) ;
+
+ if( nim->time_units > 0 )
+ sprintf( buf+strlen(buf) ,
+ " time_units = '%d'\n"
+ " time_units_name = '%s'\n" ,
+ nim->time_units , nifti_units_string(nim->time_units) ) ;
+
+ if( nim->freq_dim > 0 )
+ sprintf( buf+strlen(buf) , " freq_dim = '%d'\n",nim->freq_dim ) ;
+ if( nim->phase_dim > 0 )
+ sprintf( buf+strlen(buf) , " phase_dim = '%d'\n",nim->phase_dim ) ;
+ if( nim->slice_dim > 0 )
+ sprintf( buf+strlen(buf) , " slice_dim = '%d'\n",nim->slice_dim ) ;
+ if( nim->slice_code > 0 )
+ sprintf( buf+strlen(buf) ,
+ " slice_code = '%d'\n"
+ " slice_code_name = '%s'\n" ,
+ nim->slice_code , nifti_slice_string(nim->slice_code) ) ;
+ if( nim->slice_start >= 0 && nim->slice_end > nim->slice_start )
+ sprintf( buf+strlen(buf) ,
+ " slice_start = '%d'\n"
+ " slice_end = '%d'\n" , nim->slice_start , nim->slice_end ) ;
+ if( nim->slice_duration != 0.0 )
+ sprintf( buf+strlen(buf) , " slice_duration = '%g'\n",
+ nim->slice_duration ) ;
+
+ if( nim->descrip[0] != '\0' ){
+ ebuf = escapize_string(nim->descrip) ;
+ sprintf( buf+strlen(buf) , " descrip = %s\n",ebuf) ;
+ free(ebuf) ;
+ }
+
+ if( nim->aux_file[0] != '\0' ){
+ ebuf = escapize_string(nim->aux_file) ;
+ sprintf( buf+strlen(buf) , " aux_file = %s\n",ebuf) ;
+ free(ebuf) ;
+ }
+
+ if( nim->qform_code > 0 ){
+ int i,j,k ;
+
+ sprintf( buf+strlen(buf) ,
+ " qform_code = '%d'\n"
+ " qform_code_name = '%s'\n"
+ " qto_xyz_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
+ nim->qform_code , nifti_xform_string(nim->qform_code) ,
+ nim->qto_xyz.m[0][0] , nim->qto_xyz.m[0][1] ,
+ nim->qto_xyz.m[0][2] , nim->qto_xyz.m[0][3] ,
+ nim->qto_xyz.m[1][0] , nim->qto_xyz.m[1][1] ,
+ nim->qto_xyz.m[1][2] , nim->qto_xyz.m[1][3] ,
+ nim->qto_xyz.m[2][0] , nim->qto_xyz.m[2][1] ,
+ nim->qto_xyz.m[2][2] , nim->qto_xyz.m[2][3] ,
+ nim->qto_xyz.m[3][0] , nim->qto_xyz.m[3][1] ,
+ nim->qto_xyz.m[3][2] , nim->qto_xyz.m[3][3] ) ;
+
+ sprintf( buf+strlen(buf) ,
+ " qto_ijk_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
+ nim->qto_ijk.m[0][0] , nim->qto_ijk.m[0][1] ,
+ nim->qto_ijk.m[0][2] , nim->qto_ijk.m[0][3] ,
+ nim->qto_ijk.m[1][0] , nim->qto_ijk.m[1][1] ,
+ nim->qto_ijk.m[1][2] , nim->qto_ijk.m[1][3] ,
+ nim->qto_ijk.m[2][0] , nim->qto_ijk.m[2][1] ,
+ nim->qto_ijk.m[2][2] , nim->qto_ijk.m[2][3] ,
+ nim->qto_ijk.m[3][0] , nim->qto_ijk.m[3][1] ,
+ nim->qto_ijk.m[3][2] , nim->qto_ijk.m[3][3] ) ;
+
+ sprintf( buf+strlen(buf) ,
+ " quatern_b = '%g'\n"
+ " quatern_c = '%g'\n"
+ " quatern_d = '%g'\n"
+ " qoffset_x = '%g'\n"
+ " qoffset_y = '%g'\n"
+ " qoffset_z = '%g'\n"
+ " qfac = '%g'\n" ,
+ nim->quatern_b , nim->quatern_c , nim->quatern_d ,
+ nim->qoffset_x , nim->qoffset_y , nim->qoffset_z , nim->qfac ) ;
+
+ nifti_mat44_to_orientation( nim->qto_xyz , &i,&j,&k ) ;
+ if( i > 0 && j > 0 && k > 0 )
+ sprintf( buf+strlen(buf) ,
+ " qform_i_orientation = '%s'\n"
+ " qform_j_orientation = '%s'\n"
+ " qform_k_orientation = '%s'\n" ,
+ nifti_orientation_string(i) ,
+ nifti_orientation_string(j) ,
+ nifti_orientation_string(k) ) ;
+ }
+
+ if( nim->sform_code > 0 ){
+ int i,j,k ;
+
+ sprintf( buf+strlen(buf) ,
+ " sform_code = '%d'\n"
+ " sform_code_name = '%s'\n"
+ " sto_xyz_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
+ nim->sform_code , nifti_xform_string(nim->sform_code) ,
+ nim->sto_xyz.m[0][0] , nim->sto_xyz.m[0][1] ,
+ nim->sto_xyz.m[0][2] , nim->sto_xyz.m[0][3] ,
+ nim->sto_xyz.m[1][0] , nim->sto_xyz.m[1][1] ,
+ nim->sto_xyz.m[1][2] , nim->sto_xyz.m[1][3] ,
+ nim->sto_xyz.m[2][0] , nim->sto_xyz.m[2][1] ,
+ nim->sto_xyz.m[2][2] , nim->sto_xyz.m[2][3] ,
+ nim->sto_xyz.m[3][0] , nim->sto_xyz.m[3][1] ,
+ nim->sto_xyz.m[3][2] , nim->sto_xyz.m[3][3] ) ;
+
+ sprintf( buf+strlen(buf) ,
+ " sto_ijk matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
+ nim->sto_ijk.m[0][0] , nim->sto_ijk.m[0][1] ,
+ nim->sto_ijk.m[0][2] , nim->sto_ijk.m[0][3] ,
+ nim->sto_ijk.m[1][0] , nim->sto_ijk.m[1][1] ,
+ nim->sto_ijk.m[1][2] , nim->sto_ijk.m[1][3] ,
+ nim->sto_ijk.m[2][0] , nim->sto_ijk.m[2][1] ,
+ nim->sto_ijk.m[2][2] , nim->sto_ijk.m[2][3] ,
+ nim->sto_ijk.m[3][0] , nim->sto_ijk.m[3][1] ,
+ nim->sto_ijk.m[3][2] , nim->sto_ijk.m[3][3] ) ;
+
+ nifti_mat44_to_orientation( nim->sto_xyz , &i,&j,&k ) ;
+ if( i > 0 && j > 0 && k > 0 )
+ sprintf( buf+strlen(buf) ,
+ " sform_i_orientation = '%s'\n"
+ " sform_j_orientation = '%s'\n"
+ " sform_k_orientation = '%s'\n" ,
+ nifti_orientation_string(i) ,
+ nifti_orientation_string(j) ,
+ nifti_orientation_string(k) ) ;
+ }
+
+ sprintf( buf+strlen(buf) , " num_ext = '%d'\n", nim->num_ext ) ;
+
+ sprintf( buf+strlen(buf) , "/>\n" ) ; /* XML-ish closer */
+
+ nbuf = (int)strlen(buf) ;
+ buf = (char *)realloc((void *)buf, nbuf+1); /* cut back to proper length */
+ if( !buf ) REprintf("** NITA: failed to realloc %d bytes\n",nbuf+1);
+ return buf ;
+}
+
+/*---------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------*/
+/*! get the byte order for this CPU
+
+ - LSB_FIRST means least significant byte, first (little endian)
+ - MSB_FIRST means most significant byte, first (big endian)
+*//*--------------------------------------------------------------------*/
+int nifti_short_order(void) /* determine this CPU's byte order */
+{
+ union { unsigned char bb[2] ;
+ short ss ; } fred ;
+
+ fred.bb[0] = 1 ; fred.bb[1] = 0 ;
+
+ return (fred.ss == 1) ? LSB_FIRST : MSB_FIRST ;
+}
+
+/*---------------------------------------------------------------------------*/
+
+#undef QQNUM
+#undef QNUM
+#undef QSTR
+
+/* macro to check lhs string against "n1"; if it matches,
+ interpret rhs string as a number, and put it into nim->"n2" */
+
+#define QQNUM(n1,n2) if( strcmp(lhs,#n1)==0 ) nim->n2=strtod(rhs,NULL)
+
+/* same, but where "n1" == "n2" */
+
+#define QNUM(nam) QQNUM(nam,nam)
+
+/* macro to check lhs string against "nam"; if it matches,
+ put rhs string into nim->"nam" string, with max length = "ml" */
+
+#define QSTR(nam,ml) if( strcmp(lhs,#nam) == 0 ) \
+ strncpy(nim->nam,rhs,ml), nim->nam[ml]='\0'
+
+/*---------------------------------------------------------------------------*/
+/*! Take an XML-ish ASCII string and create a NIFTI image header to match.
+
+ NULL is returned if enough information isn't present in the input string.
+ - The image data can later be loaded with nifti_image_load().
+ - The struct returned here can be liberated with nifti_image_free().
+ - Not a lot of error checking is done here to make sure that the
+ input values are reasonable!
+*//*-------------------------------------------------------------------------*/
+nifti_image *nifti_image_from_ascii( const char *str, int * bytes_read )
+{
+ char lhs[1024] , rhs[1024] ;
+ int ii , spos, nn , slen ;
+ nifti_image *nim ; /* will be output */
+
+ if( str == NULL || *str == '\0' ) return NULL ; /* bad input!? */
+
+ /* scan for opening string */
+
+ spos = 0 ; slen = (int)strlen(str) ;
+ ii = sscanf( str+spos , "%1023s%n" , lhs , &nn ) ; spos += nn ;
+ if( ii == 0 || strcmp(lhs,"<nifti_image") != 0 ) return NULL ;
+
+ /* create empty image struct */
+
+ nim = (nifti_image *)calloc( 1 , sizeof(nifti_image) ) ;
+ if( !nim ){
+ REprintf("** NIFA: failed to alloc nifti_image\n");
+ return NULL;
+ }
+
+ nim->nx = nim->ny = nim->nz = nim->nt
+ = nim->nu = nim->nv = nim->nw = 1 ;
+ nim->dx = nim->dy = nim->dz = nim->dt
+ = nim->du = nim->dv = nim->dw = 0 ;
+ nim->qfac = 1.0 ;
+
+ nim->byteorder = nifti_short_order() ;
+
+ /* starting at str[spos], scan for "equations" of the form
+ lhs = 'rhs'
+ and assign rhs values into the struct component named by lhs */
+
+ while(1){
+
+ while( isspace((int) str[spos]) ) spos++ ; /* skip whitespace */
+ if( str[spos] == '\0' ) break ; /* end of string? */
+
+ /* get lhs string */
+
+ ii = sscanf( str+spos , "%1023s%n" , lhs , &nn ) ; spos += nn ;
+ if( ii == 0 || strcmp(lhs,"/>") == 0 ) break ; /* end of input? */
+
+ /* skip whitespace and the '=' marker */
+
+ while( isspace((int) str[spos]) || str[spos] == '=' ) spos++ ;
+ if( str[spos] == '\0' ) break ; /* end of string? */
+
+ /* if next character is a quote ', copy everything up to next '
+ otherwise, copy everything up to next nonblank */
+
+ if( str[spos] == '\'' ){
+ ii = spos+1 ;
+ while( str[ii] != '\0' && str[ii] != '\'' ) ii++ ;
+ nn = ii-spos-1 ; if( nn > 1023 ) nn = 1023 ;
+ memcpy(rhs,str+spos+1,nn) ; rhs[nn] = '\0' ;
+ spos = (str[ii] == '\'') ? ii+1 : ii ;
+ } else {
+ ii = sscanf( str+spos , "%1023s%n" , rhs , &nn ) ; spos += nn ;
+ if( ii == 0 ) break ; /* nothing found? */
+ }
+ unescape_string(rhs) ; /* remove any XML escape sequences */
+
+ /* Now can do the assignment, based on lhs string.
+ Start with special cases that don't fit the QNUM/QSTR macros. */
+
+ if( strcmp(lhs,"nifti_type") == 0 ){
+ if( strcmp(rhs,"ANALYZE-7.5") == 0 )
+ nim->nifti_type = NIFTI_FTYPE_ANALYZE ;
+ else if( strcmp(rhs,"NIFTI-1+") == 0 )
+ nim->nifti_type = NIFTI_FTYPE_NIFTI1_1 ;
+ else if( strcmp(rhs,"NIFTI-1") == 0 )
+ nim->nifti_type = NIFTI_FTYPE_NIFTI1_2 ;
+ else if( strcmp(rhs,"NIFTI-1A") == 0 )
+ nim->nifti_type = NIFTI_FTYPE_ASCII ;
+ }
+ else if( strcmp(lhs,"header_filename") == 0 ){
+ nim->fname = nifti_strdup(rhs) ;
+ }
+ else if( strcmp(lhs,"image_filename") == 0 ){
+ nim->iname = nifti_strdup(rhs) ;
+ }
+ else if( strcmp(lhs,"sto_xyz_matrix") == 0 ){
+ sscanf( rhs , "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f" ,
+ &(nim->sto_xyz.m[0][0]) , &(nim->sto_xyz.m[0][1]) ,
+ &(nim->sto_xyz.m[0][2]) , &(nim->sto_xyz.m[0][3]) ,
+ &(nim->sto_xyz.m[1][0]) , &(nim->sto_xyz.m[1][1]) ,
+ &(nim->sto_xyz.m[1][2]) , &(nim->sto_xyz.m[1][3]) ,
+ &(nim->sto_xyz.m[2][0]) , &(nim->sto_xyz.m[2][1]) ,
+ &(nim->sto_xyz.m[2][2]) , &(nim->sto_xyz.m[2][3]) ,
+ &(nim->sto_xyz.m[3][0]) , &(nim->sto_xyz.m[3][1]) ,
+ &(nim->sto_xyz.m[3][2]) , &(nim->sto_xyz.m[3][3]) ) ;
+ }
+ else if( strcmp(lhs,"byteorder") == 0 ){
+ if( strcmp(rhs,"MSB_FIRST") == 0 ) nim->byteorder = MSB_FIRST ;
+ if( strcmp(rhs,"LSB_FIRST") == 0 ) nim->byteorder = LSB_FIRST ;
+ }
+ else QQNUM(image_offset,iname_offset) ;
+ else QNUM(datatype) ;
+ else QNUM(ndim) ;
+ else QNUM(nx) ;
+ else QNUM(ny) ;
+ else QNUM(nz) ;
+ else QNUM(nt) ;
+ else QNUM(nu) ;
+ else QNUM(nv) ;
+ else QNUM(nw) ;
+ else QNUM(dx) ;
+ else QNUM(dy) ;
+ else QNUM(dz) ;
+ else QNUM(dt) ;
+ else QNUM(du) ;
+ else QNUM(dv) ;
+ else QNUM(dw) ;
+ else QNUM(cal_min) ;
+ else QNUM(cal_max) ;
+ else QNUM(scl_slope) ;
+ else QNUM(scl_inter) ;
+ else QNUM(intent_code) ;
+ else QNUM(intent_p1) ;
+ else QNUM(intent_p2) ;
+ else QNUM(intent_p3) ;
+ else QSTR(intent_name,15) ;
+ else QNUM(toffset) ;
+ else QNUM(xyz_units) ;
+ else QNUM(time_units) ;
+ else QSTR(descrip,79) ;
+ else QSTR(aux_file,23) ;
+ else QNUM(qform_code) ;
+ else QNUM(quatern_b) ;
+ else QNUM(quatern_c) ;
+ else QNUM(quatern_d) ;
+ else QNUM(qoffset_x) ;
+ else QNUM(qoffset_y) ;
+ else QNUM(qoffset_z) ;
+ else QNUM(qfac) ;
+ else QNUM(sform_code) ;
+ else QNUM(freq_dim) ;
+ else QNUM(phase_dim) ;
+ else QNUM(slice_dim) ;
+ else QNUM(slice_code) ;
+ else QNUM(slice_start) ;
+ else QNUM(slice_end) ;
+ else QNUM(slice_duration) ;
+ else QNUM(num_ext) ;
+
+ } /* end of while loop */
+
+ if( bytes_read ) *bytes_read = spos+1; /* "process" last '\n' */
+
+ /* do miscellaneous checking and cleanup */
+
+ if( nim->ndim <= 0 ){ nifti_image_free(nim); return NULL; } /* bad! */
+
+ nifti_datatype_sizes( nim->datatype, &(nim->nbyper), &(nim->swapsize) );
+ if( nim->nbyper == 0 ){ nifti_image_free(nim); return NULL; } /* bad! */
+
+ nim->dim[0] = nim->ndim ;
+ nim->dim[1] = nim->nx ; nim->pixdim[1] = nim->dx ;
+ nim->dim[2] = nim->ny ; nim->pixdim[2] = nim->dy ;
+ nim->dim[3] = nim->nz ; nim->pixdim[3] = nim->dz ;
+ nim->dim[4] = nim->nt ; nim->pixdim[4] = nim->dt ;
+ nim->dim[5] = nim->nu ; nim->pixdim[5] = nim->du ;
+ nim->dim[6] = nim->nv ; nim->pixdim[6] = nim->dv ;
+ nim->dim[7] = nim->nw ; nim->pixdim[7] = nim->dw ;
+
+ nim->nvox = (size_t)nim->nx * nim->ny * nim->nz
+ * nim->nt * nim->nu * nim->nv * nim->nw ;
+
+ if( nim->qform_code > 0 )
+ nim->qto_xyz = nifti_quatern_to_mat44(
+ nim->quatern_b, nim->quatern_c, nim->quatern_d,
+ nim->qoffset_x, nim->qoffset_y, nim->qoffset_z,
+ nim->dx , nim->dy , nim->dz ,
+ nim->qfac ) ;
+ else
+ nim->qto_xyz = nifti_quatern_to_mat44(
+ 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ,
+ nim->dx , nim->dy , nim->dz , 0.0 ) ;
+
+
+ nim->qto_ijk = nifti_mat44_inverse( nim->qto_xyz ) ;
+
+ if( nim->sform_code > 0 )
+ nim->sto_ijk = nifti_mat44_inverse( nim->sto_xyz ) ;
+
+ return nim ;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*! validate the nifti_image
+
+ \return 1 if the structure seems valid, otherwise 0
+
+ \sa nifti_nim_has_valid_dims, nifti_hdr_looks_good
+*//*-------------------------------------------------------------------------*/
+int nifti_nim_is_valid(nifti_image * nim, int complain)
+{
+ int errs = 0;
+
+ if( !nim ){
+ REprintf("** is_valid_nim: nim is NULL\n");
+ return 0;
+ }
+
+ if( g_opts.debug > 2 ) REprintf("-d nim_is_valid check...\n");
+
+ /**- check that dim[] matches the individual values ndim, nx, ny, ... */
+ if( ! nifti_nim_has_valid_dims(nim,complain) ){
+ if( !complain ) return 0;
+ errs++;
+ }
+
+ /* might check nbyper, pixdim, q/sforms, swapsize, nifti_type, ... */
+
+ /**- be explicit in return of 0 or 1 */
+ if( errs > 0 ) return 0;
+ else return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+/*! validate nifti dimensions
+
+ \return 1 if valid, 0 if not
+
+ \sa nifti_nim_is_valid, nifti_hdr_looks_good
+
+ rely on dim[] as the master
+*//*-------------------------------------------------------------------------*/
+int nifti_nim_has_valid_dims(nifti_image * nim, int complain)
+{
+ size_t prod;
+ int c, errs = 0;
+
+ /**- start with dim[0]: failure here is considered terminal */
+ if( nim->dim[0] <= 0 || nim->dim[0] > 7 ){
+ errs++;
+ if( complain )
+ REprintf("** NVd: dim[0] (%d) out of range [1,7]\n",nim->dim[0]);
+ return 0;
+ }
+
+ /**- check whether ndim equals dim[0] */
+ if( nim->ndim != nim->dim[0] ){
+ errs++;
+ if( ! complain ) return 0;
+ REprintf("** NVd: ndim != dim[0] (%d,%d)\n",nim->ndim,nim->dim[0]);
+ }
+
+ /**- compare each dim[i] to the proper nx, ny, ... */
+ if( ( (nim->dim[0] >= 1) && (nim->dim[1] != nim->nx) ) ||
+ ( (nim->dim[0] >= 2) && (nim->dim[2] != nim->ny) ) ||
+ ( (nim->dim[0] >= 3) && (nim->dim[3] != nim->nz) ) ||
+ ( (nim->dim[0] >= 4) && (nim->dim[4] != nim->nt) ) ||
+ ( (nim->dim[0] >= 5) && (nim->dim[5] != nim->nu) ) ||
+ ( (nim->dim[0] >= 6) && (nim->dim[6] != nim->nv) ) ||
+ ( (nim->dim[0] >= 7) && (nim->dim[7] != nim->nw) ) ){
+ errs++;
+ if( !complain ) return 0;
+ REprintf("** NVd mismatch: dims = %d,%d,%d,%d,%d,%d,%d\n"
+ " nxyz... = %d,%d,%d,%d,%d,%d,%d\n",
+ nim->dim[1], nim->dim[2], nim->dim[3],
+ nim->dim[4], nim->dim[5], nim->dim[6], nim->dim[7],
+ nim->nx, nim->ny, nim->nz,
+ nim->nt, nim->nu, nim->nv, nim->nw );
+ }
+
+ if( g_opts.debug > 2 ){
+ REprintf("-d check dim[%d] =", nim->dim[0]);
+ for( c = 0; c < 7; c++ ) REprintf(" %d", nim->dim[c]);
+ REprintf("\n"); /*fputc('\n', stderr);*/
+ }
+
+ /**- check the dimensions, and that their product matches nvox */
+ prod = 1;
+ for( c = 1; c <= nim->dim[0]; c++ ){
+ if( nim->dim[c] > 0)
+ prod *= nim->dim[c];
+ else if( nim->dim[c] <= 0 ){
+ if( !complain ) return 0;
+ REprintf("** NVd: dim[%d] (=%d) <= 0\n",c, nim->dim[c]);
+ errs++;
+ }
+ }
+ if( prod != nim->nvox ){
+ if( ! complain ) return 0;
+ REprintf("** NVd: nvox does not match %d-dim product (%u, %u)\n",
+ nim->dim[0], (unsigned)nim->nvox, (unsigned)prod);
+ errs++;
+ }
+
+ /**- if debug, warn about any remaining dim that is neither 0, nor 1 */
+ /* (values in dims above dim[0] are undefined, as reminded by Cinly
+ Ooi and Alle Meije Wink) 16 Nov 2005 [rickr] */
+ if( g_opts.debug > 1 )
+ for( c = nim->dim[0]+1; c <= 7; c++ )
+ if( nim->dim[c] != 0 && nim->dim[c] != 1 )
+ REprintf("** NVd warning: dim[%d] = %d, but ndim = %d\n",
+ c, nim->dim[c], nim->dim[0]);
+
+ if( g_opts.debug > 2 )
+ REprintf("-d nim_has_valid_dims check, errs = %d\n", errs);
+
+ /**- return invalid or valid */
+ if( errs > 0 ) return 0;
+ else return 1;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*! read a nifti image, collapsed across dimensions according to dims[8] <pre>
+
+ This function may be used to read parts of a nifti dataset, such as
+ the time series for a single voxel, or perhaps a slice. It is similar
+ to nifti_image_load(), though the passed 'data' parameter is used for
+ returning the image, not nim->data.
+
+ \param nim given nifti_image struct, corresponding to the data file
+ \param dims given list of dimensions (see below)
+ \param data pointer to data pointer (if *data is NULL, data will be
+ allocated, otherwise not)
+
+ Here, dims is an array of 8 ints, similar to nim->dim[8]. While dims[0]
+ is unused at this point, the other indices specify which dimensions to
+ collapse (and at which index), and which not to collapse. If dims[i] is
+ set to -1, then that entire dimension will be read in, from index 0 to
+ index (nim->dim[i] - 1). If dims[i] >= 0, then only that index will be
+ read in (so dims[i] must also be < nim->dim[i]).
+
+ Example: given nim->dim[8] = { 4, 64, 64, 21, 80, 1, 1, 1 } (4-D dataset)
+
+ if dims[8] = { 0, 5, 4, 17, -1, -1, -1, -1 }
+ -> read time series for voxel i,j,k = 5,4,17
+
+ if dims[8] = { 0, -1, -1, -1, 17, -1, -1, -1 }
+ -> read single volume at time point 17
+
+ Example: given nim->dim[8] = { 6, 64, 64, 21, 80, 4, 3, 1 } (6-D dataset)
+
+ if dims[8] = { 0, 5, 4, 17, -1, 2, 1, 0 }
+ -> read time series for the voxel i,j,k = 5,4,17, and dim 5,6 = 2,1
+
+ if dims[8] = { 0, 5, 4, -1, -1, 0, 0, 0 }
+ -> read time series for slice at i,j = 5,4, and dim 5,6,7 = 0,0,0
+ (note that dims[7] is not relevant, but must be 0 or -1)
+
+ If *data is NULL, then *data will be set as a pointer to new memory,
+ allocated here for the resulting collapsed image data.
+
+ e.g. { int dims[8] = { 0, 5, 4, 17, -1, -1, -1, -1 };
+ void * data = NULL;
+ ret_val = nifti_read_collapsed_image(nim, dims, &data);
+ if( ret_val > 0 ){
+ process_time_series(data);
+ if( data != NULL ) free(data);
+ }
+ }
+
+ NOTE: If *data is not NULL, then it will be assumed that it points to
+ valid memory, sufficient to hold the results. This is done for
+ speed and possibly repeated calls to this function.
+
+ e.g. { int dims[8] = { 0, -1, -1, -1, -1, -1, -1, -1 };
+ void * data = NULL;
+ for( zslice = 0; zslice < nzslices; zslice++ ){
+ dims[3] = zslice;
+ ret_val = nifti_read_collapsed_image(nim, dims, &data);
+ if( ret_val > 0 ) process_slice(zslice, data);
+ }
+ if( data != NULL ) free(data);
+ }
+
+ \return
+ - the total number of bytes read, or < 0 on failure
+ - the read and byte-swapped data, in 'data' </pre>
+
+ \sa nifti_image_read, nifti_image_free, nifti_image_read_bricks
+ nifti_image_load
+*//*-------------------------------------------------------------------------*/
+int nifti_read_collapsed_image( nifti_image * nim, const int dims [8],
+ void ** data )
+{
+ znzFile fp;
+ int pivots[8], prods[8], nprods; /* sizes are bounded by dims[], so 8 */
+ int c, bytes;
+
+ /** - check pointers for sanity */
+ if( !nim || !dims || !data ){
+ REprintf("** nifti_RCI: bad params %p, %p, %p\n",
+ (void *)nim, (void *)dims, (void *)data);
+ return -1;
+ }
+
+ if( g_opts.debug > 2 ){
+ REprintf("-d read_collapsed_image:\n dims =");
+ for(c = 0; c < 8; c++) REprintf(" %3d", dims[c]);
+ REprintf("\n nim->dims =");
+ for(c = 0; c < 8; c++) REprintf(" %3d", nim->dim[c]);
+ REprintf("\n"); /*fputc('\n', stderr);*/
+ }
+
+ /** - verify that dim[] makes sense */
+ if( ! nifti_nim_is_valid(nim, g_opts.debug > 0) ){
+ REprintf("** invalid nim (file is '%s')\n", nim->fname );
+ return -1;
+ }
+
+ /** - verify that dims[] makes sense for this dataset */
+ for( c = 1; c <= nim->dim[0]; c++ ){
+ if( dims[c] >= nim->dim[c] ){
+ REprintf("** nifti_RCI: dims[%d] >= nim->dim[%d] (%d,%d)\n",
+ c, c, dims[c], nim->dim[c]);
+ return -1;
+ }
+ }
+
+ /** - prepare pivot list - pivots are fixed indices */
+ if( make_pivot_list(nim, dims, pivots, prods, &nprods) < 0 ) return -1;
+
+ bytes = rci_alloc_mem(data, prods, nprods, nim->nbyper);
+ if( bytes < 0 ) return -1;
+
+ /** - open the image file for reading at the appropriate offset */
+ fp = nifti_image_load_prep( nim );
+ if( ! fp ){ free(*data); *data = NULL; return -1; } /* failure */
+
+ /** - call the recursive reading function, passing nim, the pivot info,
+ location to store memory, and file pointer and position */
+ c = rci_read_data(nim, pivots,prods,nprods,dims,
+ (char *)*data, fp, znztell(fp));
+ znzclose(fp); /* in any case, close the file */
+ if( c < 0 ){ free(*data); *data = NULL; return -1; } /* failure */
+
+ if( g_opts.debug > 1 )
+ REprintf("+d read %d bytes of collapsed image from %s\n",
+ bytes, nim->fname);
+
+ return bytes;
+}
+
+
+/* local function to find strides per dimension. assumes 7D size and
+** stride array.
+*/
+static void
+compute_strides(int *strides,const int *size,int nbyper)
+{
+ int i;
+ strides[0] = nbyper;
+ for(i = 1; i < 7; i++)
+ {
+ strides[i] = size[i-1] * strides[i-1];
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+/*! read an arbitrary subregion from a nifti image
+
+ This function may be used to read a single arbitary subregion of any
+ rectangular size from a nifti dataset, such as a small 5x5x5 subregion
+ around the center of a 3D image.
+
+ \param nim given nifti_image struct, corresponding to the data file
+ \param start_index the index location of the first voxel that will be returned
+ \param region_size the size of the subregion to be returned
+ \param data pointer to data pointer (if *data is NULL, data will be
+ allocated, otherwise not)
+
+ Example: given nim->dim[8] = {3, 64, 64, 64, 1, 1, 1, 1 } (3-D dataset)
+
+ if start_index[7] = { 29, 29, 29, 0, 0, 0, 0 } and
+ region_size[7] = { 5, 5, 5, 1, 1, 1, 1 }
+ -> read 5x5x5 region starting with the first voxel location at (29,29,29)
+
+ NOTE: If *data is not NULL, then it will be assumed that it points to
+ valid memory, sufficient to hold the results. This is done for
+ speed and possibly repeated calls to this function.
+ \return
+ - the total number of bytes read, or < 0 on failure
+ - the read and byte-swapped data, in 'data' </pre>
+
+ \sa nifti_image_read, nifti_image_free, nifti_image_read_bricks
+ nifti_image_load, nifti_read_collapsed_image
+*//*-------------------------------------------------------------------------*/
+int nifti_read_subregion_image( nifti_image * nim,
+ int *start_index,
+ int *region_size,
+ void ** data )
+{
+ znzFile fp; /* file to read */
+ int i,j,k,l,m,n; /* indices for dims */
+ long int bytes = 0; /* total # bytes read */
+ int total_alloc_size; /* size of buffer allocation */
+ char *readptr; /* where in *data to read next */
+ int strides[7]; /* strides between dimensions */
+ int collapsed_dims[8]; /* for read_collapsed_image */
+ int *image_size; /* pointer to dimensions in header */
+ long int initial_offset;
+ long int offset; /* seek offset for reading current row */
+
+ /* probably ignored, but set to ndim for consistency*/
+ collapsed_dims[0] = nim->ndim;
+
+ /* build a dims array for collapsed image read */
+ for(i = 0; i < nim->ndim; i++)
+ {
+ /* if you take the whole extent in this dimension */
+ if(start_index[i] == 0 &&
+ region_size[i] == nim->dim[i+1])
+ {
+ collapsed_dims[i+1] = -1;
+ }
+ /* if you specify a single element in this dimension */
+ else if(region_size[i] == 1)
+ {
+ collapsed_dims[i+1] = start_index[i];
+ }
+ else
+ {
+ collapsed_dims[i+1] = -2; /* sentinel value */
+ }
+ }
+ /* fill out end of collapsed_dims */
+ for(i = nim->ndim ; i < 7; i++)
+ {
+ collapsed_dims[i+1] = -1;
+ }
+
+ /* check to see whether collapsed read is possible */
+ for(i = 1; i <= nim->ndim; i++)
+ {
+ if(collapsed_dims[i] == -2)
+ {
+ break;
+ }
+ }
+
+ /* if you get through all the dimensions without hitting
+ ** a subrange of size > 1, a collapsed read is possible
+ */
+ if(i > nim->ndim)
+ {
+ return nifti_read_collapsed_image(nim, collapsed_dims, data);
+ }
+
+ /* point past first element of dim, which holds nim->ndim */
+ image_size = &(nim->dim[1]);
+
+ /* check region sizes for sanity */
+ for(i = 0; i < nim->ndim; i++)
+ {
+ if(start_index[i] + region_size[i] > image_size[i])
+ {
+ if(g_opts.debug > 1)
+ {
+ REprintf("region doesn't fit within image size\n");
+ }
+ return -1;
+ }
+ }
+
+ /* get the file open */
+ fp = nifti_image_load_prep( nim );
+ /* the current offset is just past the nifti header, save
+ * location so that SEEK_SET can be used below
+ */
+ initial_offset = znztell(fp);
+ /* get strides*/
+ compute_strides(strides,image_size,nim->nbyper);
+
+ total_alloc_size = nim->nbyper; /* size of pixel */
+
+ /* find alloc size */
+ for(i = 0; i < nim->ndim; i++)
+ {
+ total_alloc_size *= region_size[i];
+ }
+ /* allocate buffer, if necessary */
+ if(*data == 0)
+ {
+ *data = (void *)malloc(total_alloc_size);
+ }
+
+ if(*data == 0)
+ {
+ if(g_opts.debug > 1)
+ {
+ REprintf("allocation of %d bytes failed\n",total_alloc_size);
+ return -1;
+ }
+ }
+
+ /* point to start of data buffer as char * */
+ readptr = *((char **)data);
+ {
+ /* can't assume that start_index and region_size have any more than
+ ** nim->ndim elements so make local copies, filled out to seven elements
+ */
+ int si[7], rs[7];
+ for(i = 0; i < nim->ndim; i++)
+ {
+ si[i] = start_index[i];
+ rs[i] = region_size[i];
+ }
+ for(i = nim->ndim; i < 7; i++)
+ {
+ si[i] = 0;
+ rs[i] = 1;
+ }
+ /* loop through subregion and read a row at a time */
+ for(i = si[6]; i < (si[6] + rs[6]); i++)
+ {
+ for(j = si[5]; j < (si[5] + rs[5]); j++)
+ {
+ for(k = si[4]; k < (si[4] + rs[4]); k++)
+ {
+ for(l = si[3]; l < (si[3] + rs[3]); l++)
+ {
+ for(m = si[2]; m < (si[2] + rs[2]); m++)
+ {
+ for(n = si[1]; n < (si[1] + rs[1]); n++)
+ {
+ int nread,read_amount;
+ offset = initial_offset +
+ (i * strides[6]) +
+ (j * strides[5]) +
+ (k * strides[4]) +
+ (l * strides[3]) +
+ (m * strides[2]) +
+ (n * strides[1]) +
+ (si[0] * strides[0]);
+ znzseek(fp, offset, SEEK_SET); /* seek to current row */
+ read_amount = rs[0] * nim->nbyper; /* read a row of the subregion*/
+ nread = (int)nifti_read_buffer(fp, readptr, read_amount, nim);
+ if(nread != read_amount)
+ {
+ if(g_opts.debug > 1)
+ {
+ REprintf("read of %d bytes failed\n",read_amount);
+ return -1;
+ }
+ }
+ bytes += nread;
+ readptr += read_amount;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return bytes;
+}
+
+
+/* read the data from the file pointed to by fp
+
+ - this a recursive function, so start with the base case
+ - data is now (char *) for easy incrementing
+
+ return 0 on success, < 0 on failure
+*/
+static int rci_read_data(nifti_image * nim, int * pivots, int * prods,
+ int nprods, const int dims[], char * data, znzFile fp, size_t base_offset)
+{
+ size_t sublen, offset, read_size;
+ int c;
+
+ /* bad check first - base_offset may not have been checked */
+ if( nprods <= 0 ){
+ REprintf("** rci_read_data, bad prods, %d\n", nprods);
+ return -1;
+ }
+
+ /* base case: actually read the data */
+ if( nprods == 1 ){
+ size_t nread, bytes;
+
+ /* make sure things look good here */
+ if( *pivots != 0 ){
+ REprintf("** rciRD: final pivot == %d!\n", *pivots);
+ return -1;
+ }
+
+ /* so just seek and read (prods[0] * nbyper) bytes from the file */
+ znzseek(fp, (long)base_offset, SEEK_SET);
+ bytes = (size_t)prods[0] * nim->nbyper;
+ nread = nifti_read_buffer(fp, data, bytes, nim);
+ if( nread != bytes ){
+ REprintf("** rciRD: read only %u of %u bytes from '%s'\n",
+ (unsigned)nread, (unsigned)bytes, nim->fname);
+ return -1;
+ } else if( g_opts.debug > 3 )
+ REprintf("+d successful read of %u bytes at offset %u\n",
+ (unsigned)bytes, (unsigned)base_offset);
+
+ return 0; /* done with base case - return success */
+ }
+
+ /* not the base case, so do a set of reduced reads */
+
+ /* compute size of sub-brick: all dimensions below pivot */
+ for( c = 1, sublen = 1; c < *pivots; c++ ) sublen *= nim->dim[c];
+
+ /* compute number of values to read, i.e. remaining prods */
+ for( c = 1, read_size = 1; c < nprods; c++ ) read_size *= prods[c];
+ read_size *= nim->nbyper; /* and multiply by bytes per voxel */
+
+ /* now repeatedly compute offsets, and recursively read */
+ for( c = 0; c < prods[0]; c++ ){
+ /* offset is (c * sub-block size (including pivot dim)) */
+ /* + (dims[] index into pivot sub-block) */
+ /* the unneeded multiplication is to make this more clear */
+ offset = (size_t)c * sublen * nim->dim[*pivots] +
+ (size_t)sublen * dims[*pivots];
+ offset *= nim->nbyper;
+
+ if( g_opts.debug > 3 )
+ REprintf("-d reading %u bytes, foff %u + %u, doff %u\n",
+ (unsigned)read_size, (unsigned)base_offset, (unsigned)offset,
+ (unsigned)(c*read_size));
+
+ /* now read the next level down, adding this offset */
+ if( rci_read_data(nim, pivots+1, prods+1, nprods-1, dims,
+ data + c * read_size, fp, base_offset + offset) < 0 )
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* allocate memory for all collapsed image data
+
+ If *data is already set, do not allocate, but still calculate
+ size for debug report.
+
+ return total size on success, and < 0 on failure
+*/
+static int rci_alloc_mem(void ** data, int prods[8], int nprods, int nbyper )
+{
+ int size, index;
+
+ if( nbyper < 0 || nprods < 1 || nprods > 8 ){
+ REprintf("** rci_am: bad params, %d, %d\n", nbyper, nprods);
+ return -1;
+ }
+
+ for( index = 0, size = 1; index < nprods; index++ )
+ size *= prods[index];
+
+ size *= nbyper;
+
+ if( ! *data ){ /* then allocate what is needed */
+ if( g_opts.debug > 1 )
+ REprintf("+d alloc %d (= %d x %d) bytes for collapsed image\n",
+ size, size/nbyper, nbyper);
+
+ *data = malloc(size); /* actually allocate the memory */
+ if( ! *data ){
+ REprintf("** rci_am: failed to alloc %d bytes for data\n", size);
+ return -1;
+ }
+ } else if( g_opts.debug > 1 )
+ REprintf("-d rci_am: *data already set, need %d (%d x %d) bytes\n",
+ size, size/nbyper, nbyper);
+
+ return size;
+}
+
+
+/* prepare a pivot list for reading
+
+ The pivot points are the indices into dims where the calling function
+ wants to collapse a dimension. The last pivot should always be zero
+ (note that we have space for that in the lists).
+*/
+static int make_pivot_list(nifti_image * nim, const int dims[], int pivots[],
+ int prods[], int * nprods )
+{
+ int len, index;
+
+ len = 0;
+ index = nim->dim[0];
+ while( index > 0 ){
+ prods[len] = 1;
+ while( index > 0 && (nim->dim[index] == 1 || dims[index] == -1) ){
+ prods[len] *= nim->dim[index];
+ index--;
+ }
+ pivots[len] = index;
+ len++;
+ index--; /* fine, let it drop out at -1 */
+ }
+
+ /* make sure to include 0 as a pivot (instead of just 1, if it is) */
+ if( pivots[len-1] != 0 ){
+ pivots[len] = 0;
+ prods[len] = 1;
+ len++;
+ }
+
+ *nprods = len;
+
+ if( g_opts.debug > 2 ){
+ REprintf("+d pivot list created, pivots :");
+ for(index = 0; index < len; index++) REprintf(" %d", pivots[index]);
+ REprintf(", prods :");
+ for(index = 0; index < len; index++) REprintf(" %d", prods[index]);
+ REprintf("\n"); /*fputc('\n',stderr);*/
+ }
+
+ return 0;
+}
+
+
+#undef ISEND
+#define ISEND(c) ( (c)==']' || (c)=='}' || (c)=='\0' )
+
+/*---------------------------------------------------------------------*/
+/*! Get an integer list in the range 0..(nvals-1), from the
+ character string str. If we call the output pointer fred,
+ then fred[0] = number of integers in the list (> 0), and
+ fred[i] = i-th integer in the list for i=1..fred[0].
+ If on return, fred == NULL or fred[0] == 0, then something is
+ wrong, and the caller must deal with that.
+
+ Syntax of input string:
+ - initial '{' or '[' is skipped, if present
+ - ends when '}' or ']' or end of string is found
+ - contains entries separated by commas
+ - entries have one of these forms:
+ - a single number
+ - a dollar sign '$', which means nvals-1
+ - a sequence of consecutive numbers in the form "a..b" or
+ "a-b", where "a" and "b" are single numbers (or '$')
+ - a sequence of evenly spaced numbers in the form
+ "a..b(c)" or "a-b(c)", where "c" encodes the step
+ - Example: "[2,7..4,3..9(2)]" decodes to the list
+ 2 7 6 5 4 3 5 7 9
+ - entries should be in the range 0..nvals-1
+
+ (borrowed, with permission, from thd_intlist.c)
+*//*-------------------------------------------------------------------*/
+int * nifti_get_intlist( int nvals , const char * str )
+{
+ int *subv = NULL ;
+ int ii , ipos , nout , slen ;
+ int ibot,itop,istep , nused ;
+ char *cpt ;
+
+ /* Meaningless input? */
+ if( nvals < 1 ) return NULL ;
+
+ /* No selection list? */
+ if( str == NULL || str[0] == '\0' ) return NULL ;
+
+ /* skip initial '[' or '{' */
+ subv = (int *)malloc( sizeof(int) * 2 ) ;
+ if( !subv ) {
+ REprintf("** nifti_get_intlist: failed alloc of 2 ints\n");
+ return NULL;
+ }
+ subv[0] = nout = 0 ;
+
+ ipos = 0 ;
+ if( str[ipos] == '[' || str[ipos] == '{' ) ipos++ ;
+
+ if( g_opts.debug > 1 )
+ REprintf("-d making int_list (vals = %d) from '%s'\n", nvals, str);
+
+ /**- for each sub-selector until end of input... */
+
+ slen = (int)strlen(str) ;
+ while( ipos < slen && !ISEND(str[ipos]) ){
+
+ while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */
+ if( ISEND(str[ipos]) ) break ; /* done */
+
+ /**- get starting value */
+
+ if( str[ipos] == '$' ){ /* special case */
+ ibot = nvals-1 ; ipos++ ;
+ } else { /* decode an integer */
+ ibot = strtol( str+ipos , &cpt , 10 ) ;
+ if( ibot < 0 ){
+ REprintf("** ERROR: list index %d is out of range 0..%d\n",
+ ibot,nvals-1) ;
+ free(subv) ; return NULL ;
+ }
+ if( ibot >= nvals ){
+ REprintf("** ERROR: list index %d is out of range 0..%d\n",
+ ibot,nvals-1) ;
+ free(subv) ; return NULL ;
+ }
+ nused = (cpt-(str+ipos)) ;
+ if( ibot == 0 && nused == 0 ){
+ REprintf("** ERROR: list syntax error '%s'\n",str+ipos) ;
+ free(subv) ; return NULL ;
+ }
+ ipos += nused ;
+ }
+
+ while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */
+
+ /**- if that's it for this sub-selector, add one value to list */
+
+ if( str[ipos] == ',' || ISEND(str[ipos]) ){
+ nout++ ;
+ subv = (int *)realloc( (char *)subv , sizeof(int) * (nout+1) ) ;
+ if( !subv ) {
+ REprintf("** nifti_get_intlist: failed realloc of %d ints\n",
+ nout+1);
+ return NULL;
+ }
+ subv[0] = nout ;
+ subv[nout] = ibot ;
+ if( ISEND(str[ipos]) ) break ; /* done */
+ ipos++ ; continue ; /* re-start loop at next sub-selector */
+ }
+
+ /**- otherwise, must have '..' or '-' as next inputs */
+
+ if( str[ipos] == '-' ){
+ ipos++ ;
+ } else if( str[ipos] == '.' && str[ipos+1] == '.' ){
+ ipos++ ; ipos++ ;
+ } else {
+ REprintf("** ERROR: index list syntax is bad: '%s'\n",
+ str+ipos) ;
+ free(subv) ; return NULL ;
+ }
+
+ /**- get ending value for loop now */
+
+ if( str[ipos] == '$' ){ /* special case */
+ itop = nvals-1 ; ipos++ ;
+ } else { /* decode an integer */
+ itop = strtol( str+ipos , &cpt , 10 ) ;
+ if( itop < 0 ){
+ REprintf("** ERROR: index %d is out of range 0..%d\n",
+ itop,nvals-1) ;
+ free(subv) ; return NULL ;
+ }
+ if( itop >= nvals ){
+ REprintf("** ERROR: index %d is out of range 0..%d\n",
+ itop,nvals-1) ;
+ free(subv) ; return NULL ;
+ }
+ nused = (cpt-(str+ipos)) ;
+ if( itop == 0 && nused == 0 ){
+ REprintf("** ERROR: index list syntax error '%s'\n",str+ipos) ;
+ free(subv) ; return NULL ;
+ }
+ ipos += nused ;
+ }
+
+ /**- set default loop step */
+
+ istep = (ibot <= itop) ? 1 : -1 ;
+
+ while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */
+
+ /**- check if we have a non-default loop step */
+
+ if( str[ipos] == '(' ){ /* decode an integer */
+ ipos++ ;
+ istep = strtol( str+ipos , &cpt , 10 ) ;
+ if( istep == 0 ){
+ REprintf("** ERROR: index loop step is 0!\n") ;
+ free(subv) ; return NULL ;
+ }
+ nused = (cpt-(str+ipos)) ;
+ ipos += nused ;
+ if( str[ipos] == ')' ) ipos++ ;
+ if( (ibot-itop)*istep > 0 ){
+ REprintf("** WARNING: index list '%d..%d(%d)' means nothing\n",
+ ibot,itop,istep ) ;
+ }
+ }
+
+ /**- add values to output */
+
+ for( ii=ibot ; (ii-itop)*istep <= 0 ; ii += istep ){
+ nout++ ;
+ subv = (int *)realloc( (char *)subv , sizeof(int) * (nout+1) ) ;
+ if( !subv ) {
+ REprintf("** nifti_get_intlist: failed realloc of %d ints\n",
+ nout+1);
+ return NULL;
+ }
+ subv[0] = nout ;
+ subv[nout] = ii ;
+ }
+
+ /**- check if we have a comma to skip over */
+
+ while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */
+ if( str[ipos] == ',' ) ipos++ ; /* skip commas */
+
+ } /* end of loop through selector string */
+
+ if( g_opts.debug > 1 ) {
+ REprintf("+d int_list (vals = %d): ", subv[0]);
+ for( ii = 1; ii <= subv[0]; ii++ ) REprintf("%d ", subv[ii]);
+ REprintf("\n"); /*fputc('\n',stderr);*/
+ }
+
+ if( subv[0] == 0 ){ free(subv); subv = NULL; }
+ return subv ;
+}
+
+/*---------------------------------------------------------------------*/
+/*! Given a NIFTI_TYPE string, such as "NIFTI_TYPE_INT16", return the
+ * corresponding integral type code. The type code is the macro
+ * value defined in nifti1.h.
+*//*-------------------------------------------------------------------*/
+int nifti_datatype_from_string( const char * name )
+{
+ int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele);
+ int c;
+
+ if( !name ) return DT_UNKNOWN;
+
+ for( c = tablen-1; c > 0; c-- )
+ if( !strcmp(name, nifti_type_list[c].name) )
+ break;
+
+ return nifti_type_list[c].type;
+}
+
+
+/*---------------------------------------------------------------------*/
+/*! Given a NIFTI_TYPE value, such as NIFTI_TYPE_INT16, return the
+ * corresponding macro label as a string. The dtype code is the
+ * macro value defined in nifti1.h.
+*//*-------------------------------------------------------------------*/
+const char * nifti_datatype_to_string( int dtype )
+{
+ int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele);
+ int c;
+
+ for( c = tablen-1; c > 0; c-- )
+ if( nifti_type_list[c].type == dtype )
+ break;
+
+ return nifti_type_list[c].name;
+}
+
+
+/*---------------------------------------------------------------------*/
+/*! Determine whether dtype is a valid NIFTI_TYPE.
+ *
+ * DT_UNKNOWN is considered invalid
+ *
+ * The only difference 'for_nifti' makes is that DT_BINARY
+ * should be invalid for a NIfTI dataset.
+*//*-------------------------------------------------------------------*/
+int nifti_datatype_is_valid( int dtype, int for_nifti )
+{
+ int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele);
+ int c;
+
+ /* special case */
+ if( for_nifti && dtype == DT_BINARY ) return 0;
+
+ for( c = tablen-1; c > 0; c-- )
+ if( nifti_type_list[c].type == dtype )
+ return 1;
+
+ return 0;
+}
+
+
+/*---------------------------------------------------------------------*/
+/*! Only as a test, verify that the new nifti_type_list table matches
+ * the the usage of nifti_datatype_sizes (which could be changed to
+ * use the table, if there were interest).
+ *
+ * return the number of errors (so 0 is success, as usual)
+*//*-------------------------------------------------------------------*/
+int nifti_test_datatype_sizes(int verb)
+{
+ int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele);
+ int nbyper, ssize;
+ int c, errs = 0;
+
+ for( c = 0; c < tablen; c++ )
+ {
+ nbyper = ssize = -1;
+ nifti_datatype_sizes(nifti_type_list[c].type, &nbyper, &ssize);
+ if( nbyper < 0 || ssize < 0 ||
+ nbyper != nifti_type_list[c].nbyper ||
+ ssize != nifti_type_list[c].swapsize )
+ {
+ if( verb || g_opts.debug > 2 )
+ REprintf( "** type mismatch: %s, %d, %d, %d : %d, %d\n",
+ nifti_type_list[c].name, nifti_type_list[c].type,
+ nifti_type_list[c].nbyper, nifti_type_list[c].swapsize,
+ nbyper, ssize);
+ errs++;
+ }
+ }
+
+ if( errs )
+ REprintf("** nifti_test_datatype_sizes: found %d errors\n",errs);
+ else if( verb || g_opts.debug > 1 )
+ REprintf("-- nifti_test_datatype_sizes: all OK\n");
+
+ return errs;
+}
+
+
+/*---------------------------------------------------------------------*/
+/*! Display the nifti_type_list table.
+ *
+ * if which == 1 : display DT_*
+ * if which == 2 : display NIFTI_TYPE*
+ * else : display all
+*//*-------------------------------------------------------------------*/
+int nifti_disp_type_list( int which )
+{
+ char * style;
+ int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele);
+ int lwhich, c;
+
+ if ( which == 1 ){ lwhich = 1; style = "DT_"; }
+ else if( which == 2 ){ lwhich = 2; style = "NIFTI_TYPE_"; }
+ else { lwhich = 3; style = "ALL"; }
+
+ Rprintf("nifti_type_list entries (%s) :\n"
+ " name type nbyper swapsize\n"
+ " --------------------- ---- ------ --------\n", style);
+
+ for( c = 0; c < tablen; c++ )
+ if( (lwhich & 1 && nifti_type_list[c].name[0] == 'D') ||
+ (lwhich & 2 && nifti_type_list[c].name[0] == 'N') )
+ Rprintf(" %-22s %5d %3d %5d\n",
+ nifti_type_list[c].name,
+ nifti_type_list[c].type,
+ nifti_type_list[c].nbyper,
+ nifti_type_list[c].swapsize);
+
+ return 0;
+}
+
+
diff --git a/src/nifti1_io.h b/src/nifti1_io.h
new file mode 100644
index 0000000..6c1ec59
--- /dev/null
+++ b/src/nifti1_io.h
@@ -0,0 +1,555 @@
+/** \file nifti1_io.h
+ \brief Data structures for using nifti1_io API.
+ - Written by Bob Cox, SSCC NIMH
+ - Revisions by Rick Reynolds, SSCC NIMH
+ */
+#ifndef _NIFTI_IO_HEADER_
+#define _NIFTI_IO_HEADER_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+
+#ifndef DONT_INCLUDE_ANALYZE_STRUCT
+#define DONT_INCLUDE_ANALYZE_STRUCT /*** not needed herein ***/
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#include "nifti1.h" /*** NIFTI-1 header specification ***/
+
+#include "znzlib.h"
+
+/*=================*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*=================*/
+
+/*****===================================================================*****/
+/***** File nifti1_io.h == Declarations for nifti1_io.c *****/
+/*****...................................................................*****/
+/***** This code is released to the public domain. *****/
+/*****...................................................................*****/
+/***** Author: Robert W Cox, SSCC/DIRP/NIMH/NIH/DHHS/USA/EARTH *****/
+/***** Date: August 2003 *****/
+/*****...................................................................*****/
+/***** Neither the National Institutes of Health (NIH), nor any of its *****/
+/***** employees imply any warranty of usefulness of this software for *****/
+/***** any purpose, and do not assume any liability for damages, *****/
+/***** incidental or otherwise, caused by any use of this document. *****/
+/*****===================================================================*****/
+
+/*
+ Modified by: Mark Jenkinson (FMRIB Centre, University of Oxford, UK)
+ Date: July/August 2004
+
+ Mainly adding low-level IO and changing things to allow gzipped files
+ to be read and written
+ Full backwards compatability should have been maintained
+
+ Modified by: Rick Reynolds (SSCC/DIRP/NIMH, National Institutes of Health)
+ Date: December 2004
+
+ Modified and added many routines for I/O.
+*/
+
+/********************** Some sample data structures **************************/
+
+typedef struct { /** 4x4 matrix struct **/
+ float m[4][4] ;
+} mat44 ;
+
+typedef struct { /** 3x3 matrix struct **/
+ float m[3][3] ;
+} mat33 ;
+
+/*...........................................................................*/
+
+/*! \enum analyze_75_orient_code
+ * \brief Old-style analyze75 orientation
+ * codes.
+ */
+typedef enum _analyze75_orient_code {
+ a75_transverse_unflipped = 0,
+ a75_coronal_unflipped = 1,
+ a75_sagittal_unflipped = 2,
+ a75_transverse_flipped = 3,
+ a75_coronal_flipped = 4,
+ a75_sagittal_flipped = 5,
+ a75_orient_unknown = 6
+} analyze_75_orient_code;
+
+/*! \struct nifti_image
+ \brief High level data structure for open nifti datasets in the
+ nifti1_io API. Note that this structure is not part of the
+ nifti1 format definition; it is used to implement one API
+ for reading/writing formats in the nifti1 format.
+ */
+typedef struct { /*!< Image storage struct **/
+
+ int ndim ; /*!< last dimension greater than 1 (1..7) */
+ int nx ; /*!< dimensions of grid array */
+ int ny ; /*!< dimensions of grid array */
+ int nz ; /*!< dimensions of grid array */
+ int nt ; /*!< dimensions of grid array */
+ int nu ; /*!< dimensions of grid array */
+ int nv ; /*!< dimensions of grid array */
+ int nw ; /*!< dimensions of grid array */
+ int dim[8] ; /*!< dim[0]=ndim, dim[1]=nx, etc. */
+ size_t nvox ; /*!< number of voxels = nx*ny*nz*...*nw */
+ int nbyper ; /*!< bytes per voxel, matches datatype */
+ int datatype ; /*!< type of data in voxels: DT_* code */
+
+ float dx ; /*!< grid spacings */
+ float dy ; /*!< grid spacings */
+ float dz ; /*!< grid spacings */
+ float dt ; /*!< grid spacings */
+ float du ; /*!< grid spacings */
+ float dv ; /*!< grid spacings */
+ float dw ; /*!< grid spacings */
+ float pixdim[8] ; /*!< pixdim[1]=dx, etc. */
+
+ float scl_slope ; /*!< scaling parameter - slope */
+ float scl_inter ; /*!< scaling parameter - intercept */
+
+ float cal_min ; /*!< calibration parameter, minimum */
+ float cal_max ; /*!< calibration parameter, maximum */
+
+ int qform_code ; /*!< codes for (x,y,z) space meaning */
+ int sform_code ; /*!< codes for (x,y,z) space meaning */
+
+ int freq_dim ; /*!< indexes (1,2,3, or 0) for MRI */
+ int phase_dim ; /*!< directions in dim[]/pixdim[] */
+ int slice_dim ; /*!< directions in dim[]/pixdim[] */
+
+ int slice_code ; /*!< code for slice timing pattern */
+ int slice_start ; /*!< index for start of slices */
+ int slice_end ; /*!< index for end of slices */
+ float slice_duration ; /*!< time between individual slices */
+
+ /*! quaternion transform parameters
+ [when writing a dataset, these are used for qform, NOT qto_xyz] */
+ float quatern_b , quatern_c , quatern_d ,
+ qoffset_x , qoffset_y , qoffset_z ,
+ qfac ;
+
+ mat44 qto_xyz ; /*!< qform: transform (i,j,k) to (x,y,z) */
+ mat44 qto_ijk ; /*!< qform: transform (x,y,z) to (i,j,k) */
+
+ mat44 sto_xyz ; /*!< sform: transform (i,j,k) to (x,y,z) */
+ mat44 sto_ijk ; /*!< sform: transform (x,y,z) to (i,j,k) */
+
+ float toffset ; /*!< time coordinate offset */
+
+ int xyz_units ; /*!< dx,dy,dz units: NIFTI_UNITS_* code */
+ int time_units ; /*!< dt units: NIFTI_UNITS_* code */
+
+ int nifti_type ; /*!< 0==ANALYZE, 1==NIFTI-1 (1 file),
+ 2==NIFTI-1 (2 files),
+ 3==NIFTI-ASCII (1 file) */
+ int intent_code ; /*!< statistic type (or something) */
+ float intent_p1 ; /*!< intent parameters */
+ float intent_p2 ; /*!< intent parameters */
+ float intent_p3 ; /*!< intent parameters */
+ char intent_name[16] ; /*!< optional description of intent data */
+
+ char descrip[80] ; /*!< optional text to describe dataset */
+ char aux_file[24] ; /*!< auxiliary filename */
+
+ char *fname ; /*!< header filename (.hdr or .nii) */
+ char *iname ; /*!< image filename (.img or .nii) */
+ int iname_offset ; /*!< offset into iname where data starts */
+ int swapsize ; /*!< swap unit in image data (might be 0) */
+ int byteorder ; /*!< byte order on disk (MSB_ or LSB_FIRST) */
+ void *data ; /*!< pointer to data: nbyper*nvox bytes */
+
+ int num_ext ; /*!< number of extensions in ext_list */
+ nifti1_extension * ext_list ; /*!< array of extension structs (with data) */
+ analyze_75_orient_code analyze75_orient; /*!< for old analyze files, orient */
+
+} nifti_image ;
+
+
+
+/* struct for return from nifti_image_read_bricks() */
+typedef struct {
+ int nbricks; /* the number of allocated pointers in 'bricks' */
+ size_t bsize; /* the length of each data block, in bytes */
+ void ** bricks; /* array of pointers to data blocks */
+} nifti_brick_list;
+
+
+/*****************************************************************************/
+/*------------------ NIfTI version of ANALYZE 7.5 structure -----------------*/
+
+/* (based on fsliolib/dbh.h, but updated for version 7.5) */
+
+typedef struct {
+ /* header info fields - describes the header overlap with NIfTI */
+ /* ------------------ */
+ int sizeof_hdr; /* 0 + 4 same */
+ char data_type[10]; /* 4 + 10 same */
+ char db_name[18]; /* 14 + 18 same */
+ int extents; /* 32 + 4 same */
+ short int session_error; /* 36 + 2 same */
+ char regular; /* 38 + 1 same */
+ char hkey_un0; /* 39 + 1 40 bytes */
+
+ /* image dimension fields - describes image sizes */
+ short int dim[8]; /* 0 + 16 same */
+ short int unused8; /* 16 + 2 intent_p1... */
+ short int unused9; /* 18 + 2 ... */
+ short int unused10; /* 20 + 2 intent_p2... */
+ short int unused11; /* 22 + 2 ... */
+ short int unused12; /* 24 + 2 intent_p3... */
+ short int unused13; /* 26 + 2 ... */
+ short int unused14; /* 28 + 2 intent_code */
+ short int datatype; /* 30 + 2 same */
+ short int bitpix; /* 32 + 2 same */
+ short int dim_un0; /* 34 + 2 slice_start */
+ float pixdim[8]; /* 36 + 32 same */
+
+ float vox_offset; /* 68 + 4 same */
+ float funused1; /* 72 + 4 scl_slope */
+ float funused2; /* 76 + 4 scl_inter */
+ float funused3; /* 80 + 4 slice_end, */
+ /* slice_code, */
+ /* xyzt_units */
+ float cal_max; /* 84 + 4 same */
+ float cal_min; /* 88 + 4 same */
+ float compressed; /* 92 + 4 slice_duration */
+ float verified; /* 96 + 4 toffset */
+ int glmax,glmin; /* 100 + 8 108 bytes */
+
+ /* data history fields - optional */
+ char descrip[80]; /* 0 + 80 same */
+ char aux_file[24]; /* 80 + 24 same */
+ char orient; /* 104 + 1 NO GOOD OVERLAP */
+ char originator[10]; /* 105 + 10 FROM HERE DOWN... */
+ char generated[10]; /* 115 + 10 */
+ char scannum[10]; /* 125 + 10 */
+ char patient_id[10]; /* 135 + 10 */
+ char exp_date[10]; /* 145 + 10 */
+ char exp_time[10]; /* 155 + 10 */
+ char hist_un0[3]; /* 165 + 3 */
+ int views; /* 168 + 4 */
+ int vols_added; /* 172 + 4 */
+ int start_field; /* 176 + 4 */
+ int field_skip; /* 180 + 4 */
+ int omax, omin; /* 184 + 8 */
+ int smax, smin; /* 192 + 8 200 bytes */
+} nifti_analyze75; /* total: 348 bytes */
+
+
+/*****************************************************************************/
+/*--------------- Prototypes of functions defined in this file --------------*/
+
+char *nifti_datatype_string ( int dt ) ;
+char *nifti_units_string ( int uu ) ;
+char *nifti_intent_string ( int ii ) ;
+char *nifti_xform_string ( int xx ) ;
+char *nifti_slice_string ( int ss ) ;
+char *nifti_orientation_string( int ii ) ;
+
+int nifti_is_inttype( int dt ) ;
+
+mat44 nifti_mat44_inverse( mat44 R ) ;
+
+mat33 nifti_mat33_inverse( mat33 R ) ;
+mat33 nifti_mat33_polar ( mat33 A ) ;
+float nifti_mat33_rownorm( mat33 A ) ;
+float nifti_mat33_colnorm( mat33 A ) ;
+float nifti_mat33_determ ( mat33 R ) ;
+mat33 nifti_mat33_mul ( mat33 A , mat33 B ) ;
+
+void nifti_swap_2bytes ( size_t n , void *ar ) ;
+void nifti_swap_4bytes ( size_t n , void *ar ) ;
+void nifti_swap_8bytes ( size_t n , void *ar ) ;
+void nifti_swap_16bytes( size_t n , void *ar ) ;
+void nifti_swap_Nbytes ( size_t n , int siz , void *ar ) ;
+
+int nifti_datatype_is_valid (int dtype, int for_nifti);
+int nifti_datatype_from_string(const char * name);
+const char * nifti_datatype_to_string (int dtype);
+
+int nifti_get_filesize( const char *pathname ) ;
+void swap_nifti_header ( struct nifti_1_header *h , int is_nifti ) ;
+void old_swap_nifti_header( struct nifti_1_header *h , int is_nifti );
+int nifti_swap_as_analyze( nifti_analyze75 *h );
+
+
+/* main read/write routines */
+
+nifti_image *nifti_image_read_bricks(const char *hname , int nbricks,
+ const int *blist, nifti_brick_list * NBL);
+int nifti_image_load_bricks(nifti_image *nim , int nbricks,
+ const int *blist, nifti_brick_list * NBL);
+void nifti_free_NBL( nifti_brick_list * NBL );
+
+nifti_image *nifti_image_read ( const char *hname , int read_data );
+nifti_image *nifti_image_read_NaN ( const char *hname , int read_data , int rmNaN);
+
+int nifti_image_load ( nifti_image *nim ) ;
+int nifti_image_load_NaN ( nifti_image *nim , int rmNaN) ;
+
+void nifti_image_unload ( nifti_image *nim ) ;
+void nifti_image_free ( nifti_image *nim ) ;
+
+int nifti_read_collapsed_image( nifti_image * nim, const int dims [8],
+ void ** data );
+
+int nifti_read_subregion_image( nifti_image * nim,
+ int *start_index, int *region_size,
+ void ** data );
+
+void nifti_image_write ( nifti_image * nim ) ;
+void nifti_image_write_bricks(nifti_image * nim,
+ const nifti_brick_list * NBL);
+void nifti_image_infodump( const nifti_image * nim ) ;
+
+void nifti_disp_lib_hist( void ) ; /* to display library history */
+void nifti_disp_lib_version( void ) ; /* to display library version */
+const char *nifti_lib_version( void );
+int nifti_disp_matrix_orient( const char * mesg, mat44 mat );
+int nifti_disp_type_list( int which );
+
+
+char * nifti_image_to_ascii ( const nifti_image * nim ) ;
+nifti_image *nifti_image_from_ascii( const char * str, int * bytes_read ) ;
+
+size_t nifti_get_volsize(const nifti_image *nim) ;
+
+/* basic file operations */
+int nifti_set_filenames(nifti_image * nim, const char * prefix, int check,
+ int set_byte_order);
+char * nifti_makehdrname (const char * prefix, int nifti_type, int check,
+ int comp);
+char * nifti_makeimgname (const char * prefix, int nifti_type, int check,
+ int comp);
+int is_nifti_file (const char *hname);
+char * nifti_find_file_extension(const char * name);
+int nifti_is_complete_filename(const char* fname);
+int nifti_validfilename(const char* fname);
+
+int disp_nifti_1_header(const char * info, const nifti_1_header * hp ) ;
+void nifti_set_debug_level( int level ) ;
+void nifti_set_skip_blank_ext( int skip ) ;
+void nifti_set_allow_upper_fext( int allow ) ;
+
+int valid_nifti_brick_list(nifti_image * nim , int nbricks,
+ const int * blist, int disp_error);
+
+/* znzFile operations */
+znzFile nifti_image_open(const char * hname, char * opts, nifti_image ** nim);
+znzFile nifti_image_write_hdr_img(nifti_image *nim, int write_data,
+ const char* opts);
+znzFile nifti_image_write_hdr_img2( nifti_image *nim , int write_opts ,
+ const char* opts, znzFile imgfile, const nifti_brick_list * NBL);
+size_t nifti_read_buffer_NaN(znzFile fp, void* datatptr, size_t ntot,
+ nifti_image *nim, int rmNaN);
+size_t nifti_read_buffer(znzFile fp, void* datatptr, size_t ntot,
+ nifti_image *nim);
+int nifti_write_all_data(znzFile fp, nifti_image * nim,
+ const nifti_brick_list * NBL);
+size_t nifti_write_buffer(znzFile fp, const void * buffer, size_t numbytes);
+nifti_image *nifti_read_ascii_image(znzFile fp, char *fname, int flen,
+ int read_data);
+znzFile nifti_write_ascii_image(nifti_image *nim, const nifti_brick_list * NBL,
+ const char * opts, int write_data, int leave_open);
+
+
+void nifti_datatype_sizes( int datatype , int *nbyper, int *swapsize ) ;
+
+void nifti_mat44_to_quatern( mat44 R ,
+ float *qb, float *qc, float *qd,
+ float *qx, float *qy, float *qz,
+ float *dx, float *dy, float *dz, float *qfac ) ;
+
+mat44 nifti_quatern_to_mat44( float qb, float qc, float qd,
+ float qx, float qy, float qz,
+ float dx, float dy, float dz, float qfac );
+
+mat44 nifti_make_orthog_mat44( float r11, float r12, float r13 ,
+ float r21, float r22, float r23 ,
+ float r31, float r32, float r33 ) ;
+
+int nifti_short_order(void) ; /* CPU byte order */
+
+
+/* Orientation codes that might be returned from nifti_mat44_to_orientation().*/
+
+#define NIFTI_L2R 1 /* Left to Right */
+#define NIFTI_R2L 2 /* Right to Left */
+#define NIFTI_P2A 3 /* Posterior to Anterior */
+#define NIFTI_A2P 4 /* Anterior to Posterior */
+#define NIFTI_I2S 5 /* Inferior to Superior */
+#define NIFTI_S2I 6 /* Superior to Inferior */
+
+void nifti_mat44_to_orientation( mat44 R , int *icod, int *jcod, int *kcod ) ;
+
+/*--------------------- Low level IO routines ------------------------------*/
+
+char * nifti_findhdrname (const char* fname);
+char * nifti_findimgname (const char* fname , int nifti_type);
+int nifti_is_gzfile (const char* fname);
+
+char * nifti_makebasename(const char* fname);
+
+
+/* other routines */
+struct nifti_1_header nifti_convert_nim2nhdr(const nifti_image* nim);
+nifti_1_header * nifti_make_new_header(const int arg_dims[], int arg_dtype);
+nifti_1_header * nifti_read_header(const char *hname, int *swapped, int check);
+nifti_image * nifti_copy_nim_info(const nifti_image * src);
+nifti_image * nifti_make_new_nim(const int dims[], int datatype,
+ int data_fill);
+nifti_image * nifti_simple_init_nim(void);
+nifti_image * nifti_convert_nhdr2nim(struct nifti_1_header nhdr,
+ const char * fname);
+
+int nifti_hdr_looks_good (const nifti_1_header * hdr);
+int nifti_is_valid_datatype (int dtype);
+int nifti_is_valid_ecode (int ecode);
+int nifti_nim_is_valid (nifti_image * nim, int complain);
+int nifti_nim_has_valid_dims (nifti_image * nim, int complain);
+int is_valid_nifti_type (int nifti_type);
+int nifti_test_datatype_sizes (int verb);
+int nifti_type_and_names_match (nifti_image * nim, int show_warn);
+int nifti_update_dims_from_array(nifti_image * nim);
+void nifti_set_iname_offset (nifti_image *nim);
+int nifti_set_type_from_names (nifti_image * nim);
+int nifti_add_extension(nifti_image * nim, const char * data, int len,
+ int ecode );
+int nifti_compiled_with_zlib (void);
+int nifti_copy_extensions (nifti_image *nim_dest,const nifti_image *nim_src);
+int nifti_free_extensions (nifti_image *nim);
+int * nifti_get_intlist (int nvals , const char *str);
+char * nifti_strdup (const char *str);
+int valid_nifti_extensions(const nifti_image *nim);
+
+
+/*-------------------- Some C convenience macros ----------------------------*/
+
+/* NIfTI-1.1 extension codes:
+ see http://nifti.nimh.nih.gov/nifti-1/documentation/faq#Q21 */
+
+#define NIFTI_ECODE_IGNORE 0 /* changed from UNKNOWN, 29 June 2005 */
+
+#define NIFTI_ECODE_DICOM 2 /* intended for raw DICOM attributes */
+
+#define NIFTI_ECODE_AFNI 4 /* Robert W Cox: rwcox at nih.gov
+ http://afni.nimh.nih.gov/afni */
+
+#define NIFTI_ECODE_COMMENT 6 /* plain ASCII text only */
+
+#define NIFTI_ECODE_XCEDE 8 /* David B Keator: dbkeator at uci.edu
+ http://www.nbirn.net/Resources
+ /Users/Applications/
+ /xcede/index.htm */
+
+#define NIFTI_ECODE_JIMDIMINFO 10 /* Mark A Horsfield:
+ mah5 at leicester.ac.uk
+ http://someplace/something */
+
+#define NIFTI_ECODE_WORKFLOW_FWDS 12 /* Kate Fissell: fissell at pitt.edu
+ http://kraepelin.wpic.pitt.edu
+ /~fissell/NIFTI_ECODE_WORKFLOW_FWDS
+ /NIFTI_ECODE_WORKFLOW_FWDS.html */
+
+#define NIFTI_ECODE_FREESURFER 14 /* http://surfer.nmr.mgh.harvard.edu */
+
+#define NIFTI_ECODE_PYPICKLE 16 /* embedded Python objects
+ http://niftilib.sourceforge.net
+ /pynifti */
+
+ /* LONI MiND codes: http://www.loni.ucla.edu/twiki/bin/view/Main/MiND */
+#define NIFTI_ECODE_MIND_IDENT 18 /* Vishal Patel: vishal.patel at ucla.edu*/
+#define NIFTI_ECODE_B_VALUE 20
+#define NIFTI_ECODE_SPHERICAL_DIRECTION 22
+#define NIFTI_ECODE_DT_COMPONENT 24
+#define NIFTI_ECODE_SHC_DEGREEORDER 26 /* end LONI MiND codes */
+
+#define NIFTI_ECODE_VOXBO 28 /* Dan Kimberg: www.voxbo.org */
+
+#define NIFTI_ECODE_CARET 30 /* John Harwell: john at brainvis.wustl.edu
+ http://brainvis.wustl.edu/wiki
+ /index.php/Caret:Documentation
+ :CaretNiftiExtension */
+
+#define NIFTI_MAX_ECODE 30 /******* maximum extension code *******/
+
+/* nifti_type file codes */
+#define NIFTI_FTYPE_ANALYZE 0
+#define NIFTI_FTYPE_NIFTI1_1 1
+#define NIFTI_FTYPE_NIFTI1_2 2
+#define NIFTI_FTYPE_ASCII 3
+#define NIFTI_MAX_FTYPE 3 /* this should match the maximum code */
+
+/*------------------------------------------------------------------------*/
+/*-- the rest of these apply only to nifti1_io.c, check for _NIFTI1_IO_C_ */
+/* Feb 9, 2005 [rickr] */
+#ifdef _NIFTI1_IO_C_
+
+typedef struct {
+ int debug; /*!< debug level for status reports */
+ int skip_blank_ext; /*!< skip extender if no extensions */
+ int allow_upper_fext; /*!< allow uppercase file extensions */
+} nifti_global_options;
+
+typedef struct {
+ int type; /* should match the NIFTI_TYPE_ #define */
+ int nbyper; /* bytes per value, matches nifti_image */
+ int swapsize; /* bytes per swap piece, matches nifti_image */
+ char * name; /* text string to match #define */
+} nifti_type_ele;
+
+#undef LNI_FERR /* local nifti file error, to be compact and repetative */
+#define LNI_FERR(func,msg,file) \
+ REprintf("** ERROR (%s): %s '%s'\n",func,msg,file)
+
+#undef swap_2
+#undef swap_4
+#define swap_2(s) nifti_swap_2bytes(1,&(s)) /* s: 2-byte short; swap in place */
+#define swap_4(v) nifti_swap_4bytes(1,&(v)) /* v: 4-byte value; swap in place */
+
+ /***** isfinite() is a C99 macro, which is
+ present in many C implementations already *****/
+
+#undef IS_GOOD_FLOAT
+#undef FIXED_FLOAT
+
+#ifdef isfinite /* use isfinite() to check floats/doubles for goodness */
+# define IS_GOOD_FLOAT(x) isfinite(x) /* check if x is a "good" float */
+# define FIXED_FLOAT(x) (isfinite(x) ? (x) : 0) /* fixed if bad */
+#else
+# define IS_GOOD_FLOAT(x) 1 /* don't check it */
+# define FIXED_FLOAT(x) (x) /* don't fix it */
+#endif
+
+#undef ASSIF /* assign v to *p, if possible */
+#define ASSIF(p,v) if( (p)!=NULL ) *(p) = (v)
+
+#undef MSB_FIRST
+#undef LSB_FIRST
+#undef REVERSE_ORDER
+#define LSB_FIRST 1
+#define MSB_FIRST 2
+#define REVERSE_ORDER(x) (3-(x)) /* convert MSB_FIRST <--> LSB_FIRST */
+
+#define LNI_MAX_NIA_EXT_LEN 100000 /* consider a longer extension invalid */
+
+#endif /* _NIFTI1_IO_C_ section */
+/*------------------------------------------------------------------------*/
+
+/*=================*/
+#ifdef __cplusplus
+}
+#endif
+/*=================*/
+
+#endif /* _NIFTI_IO_HEADER_ */
diff --git a/src/znzlib.c b/src/znzlib.c
new file mode 100644
index 0000000..4f7c2c4
--- /dev/null
+++ b/src/znzlib.c
@@ -0,0 +1,327 @@
+/** \file znzlib.c
+ \brief Low level i/o interface to compressed and noncompressed files.
+ Written by Mark Jenkinson, FMRIB
+
+This library provides an interface to both compressed (gzip/zlib) and
+uncompressed (normal) file IO. The functions are written to have the
+same interface as the standard file IO functions.
+
+To use this library instead of normal file IO, the following changes
+are required:
+ - replace all instances of FILE* with znzFile
+ - change the name of all function calls, replacing the initial character
+ f with the znz (e.g. fseek becomes znzseek)
+ one exception is rewind() -> znzrewind()
+ - add a third parameter to all calls to znzopen (previously fopen)
+ that specifies whether to use compression (1) or not (0)
+ - use znz_isnull rather than any (pointer == NULL) comparisons in the code
+ for znzfile types (normally done after a return from znzopen)
+
+NB: seeks for writable files with compression are quite restricted
+
+ */
+/* changes by Oliver Granert:
+- change HAVE_ZLIB to HAVE_LIBZ to fit autoconf tests
+*/
+#include "znzlib.h"
+#include <R.h>
+
+/*
+znzlib.c (zipped or non-zipped library)
+
+***** This code is released to the public domain. *****
+
+***** Author: Mark Jenkinson, FMRIB Centre, University of Oxford *****
+***** Date: September 2004 *****
+
+***** Neither the FMRIB Centre, the University of Oxford, nor any of *****
+***** its employees imply any warranty of usefulness of this software *****
+***** for any purpose, and do not assume any liability for damages, *****
+***** incidental or otherwise, caused by any use of this document. *****
+
+*/
+
+
+/* Note extra argument (use_compression) where
+ use_compression==0 is no compression
+ use_compression!=0 uses zlib (gzip) compression
+*/
+
+znzFile znzopen(const char *path, const char *mode, int use_compression)
+{
+ znzFile file;
+ file = (znzFile) calloc(1,sizeof(struct znzptr));
+ if( file == NULL ){
+ REprintf(/*fprintf(stderr,*/"** ERROR: znzopen failed to alloc znzptr\n");
+ return NULL;
+ }
+
+ file->nzfptr = NULL;
+
+#ifdef HAVE_LIBZ
+ file->zfptr = NULL;
+
+ if (use_compression) {
+ file->withz = 1;
+ if((file->zfptr = gzopen(path,mode)) == NULL) {
+ free(file);
+ file = NULL;
+ }
+ } else {
+#endif
+
+ file->withz = 0;
+ if((file->nzfptr = fopen(path,mode)) == NULL) {
+ free(file);
+ file = NULL;
+ }
+
+#ifdef HAVE_LIBZ
+ }
+#endif
+
+ return file;
+}
+
+
+znzFile znzdopen(int fd, const char *mode, int use_compression)
+{
+ znzFile file;
+ file = (znzFile) calloc(1,sizeof(struct znzptr));
+ if( file == NULL ){
+ REprintf(/*fprintf(stderr,*/"** ERROR: znzdopen failed to alloc znzptr\n");
+ return NULL;
+ }
+#ifdef HAVE_LIBZ
+ if (use_compression) {
+ file->withz = 1;
+ file->zfptr = gzdopen(fd,mode);
+ file->nzfptr = NULL;
+ } else {
+#endif
+ file->withz = 0;
+#ifdef HAVE_FDOPEN
+ file->nzfptr = fdopen(fd,mode);
+#endif
+#ifdef HAVE_LIBZ
+ file->zfptr = NULL;
+ };
+#endif
+ return file;
+}
+
+
+int Xznzclose(znzFile * file)
+{
+ int retval = 0;
+ if (*file!=NULL) {
+#ifdef HAVE_LIBZ
+ if ((*file)->zfptr!=NULL) { retval = gzclose((*file)->zfptr); }
+#endif
+ if ((*file)->nzfptr!=NULL) { retval = fclose((*file)->nzfptr); }
+
+ free(*file);
+ *file = NULL;
+ }
+ return retval;
+}
+
+
+/* we already assume ints are 4 bytes */
+#undef ZNZ_MAX_BLOCK_SIZE
+#define ZNZ_MAX_BLOCK_SIZE (1<<30)
+
+size_t znzread(void* buf, size_t size, size_t nmemb, znzFile file)
+{
+#ifdef HAVE_LIBZ
+ size_t remain = size*nmemb;
+ char * cbuf = (char *)buf;
+ unsigned n2read;
+ int nread;
+#endif
+ if (file==NULL) { return 0; }
+#ifdef HAVE_LIBZ
+ if (file->zfptr!=NULL) {
+ /* gzread/write take unsigned int length, so maybe read in int pieces
+ (noted by M Hanke, example given by M Adler) 6 July 2010 [rickr] */
+ while( remain > 0 ) {
+ n2read = (remain < ZNZ_MAX_BLOCK_SIZE) ? remain : ZNZ_MAX_BLOCK_SIZE;
+ nread = gzread(file->zfptr, (void *)cbuf, n2read);
+ if( nread < 0 ) return nread; /* returns -1 on error */
+
+ remain -= nread;
+ cbuf += nread;
+
+ /* require reading n2read bytes, so we don't get stuck */
+ if( nread < (int)n2read ) break; /* return will be short */
+ }
+
+ /* warn of a short read that will seem complete */
+ if( remain > 0 && remain < size )
+ REprintf(/*fprintf(stderr,*/"** znzread: read short by %u bytes\n",(unsigned)remain);
+
+ return nmemb - remain/size; /* return number of members processed */
+ }
+#endif
+ return fread(buf,size,nmemb,file->nzfptr);
+}
+
+size_t znzwrite(const void* buf, size_t size, size_t nmemb, znzFile file)
+{
+#ifdef HAVE_LIBZ
+ size_t remain = size*nmemb;
+ char * cbuf = (char *)buf;
+ unsigned n2write;
+ int nwritten;
+#endif
+ if (file==NULL) { return 0; }
+#ifdef HAVE_LIBZ
+ if (file->zfptr!=NULL) {
+ while( remain > 0 ) {
+ n2write = (remain < ZNZ_MAX_BLOCK_SIZE) ? remain : ZNZ_MAX_BLOCK_SIZE;
+ nwritten = gzwrite(file->zfptr, (void *)cbuf, n2write);
+
+ /* gzread returns 0 on error, but in case that ever changes... */
+ if( nwritten < 0 ) return nwritten;
+
+ remain -= nwritten;
+ cbuf += nwritten;
+
+ /* require writing n2write bytes, so we don't get stuck */
+ if( nwritten < (int)n2write ) break;
+ }
+
+ /* warn of a short write that will seem complete */
+ if( remain > 0 && remain < size )
+ REprintf(/*fprintf(stderr,*/"** znzwrite: write short by %u bytes\n",(unsigned)remain);
+
+ return nmemb - remain/size; /* return number of members processed */
+ }
+#endif
+ return fwrite(buf,size,nmemb,file->nzfptr);
+}
+
+long znzseek(znzFile file, long offset, int whence)
+{
+ if (file==NULL) { return 0; }
+#ifdef HAVE_LIBZ
+ if (file->zfptr!=NULL) return (long) gzseek(file->zfptr,offset,whence);
+#endif
+ return fseek(file->nzfptr,offset,whence);
+}
+
+int znzrewind(znzFile stream)
+{
+ if (stream==NULL) { return 0; }
+#ifdef HAVE_LIBZ
+ /* On some systems, gzrewind() fails for uncompressed files.
+ Use gzseek(), instead. 10, May 2005 [rickr]
+
+ if (stream->zfptr!=NULL) return gzrewind(stream->zfptr);
+ */
+
+ if (stream->zfptr!=NULL) return (int)gzseek(stream->zfptr, 0L, SEEK_SET);
+#endif
+ rewind(stream->nzfptr);
+ return 0;
+}
+
+long znztell(znzFile file)
+{
+ if (file==NULL) { return 0; }
+#ifdef HAVE_LIBZ
+ if (file->zfptr!=NULL) return (long) gztell(file->zfptr);
+#endif
+ return ftell(file->nzfptr);
+}
+
+int znzputs(const char * str, znzFile file)
+{
+ if (file==NULL) { return 0; }
+#ifdef HAVE_LIBZ
+ if (file->zfptr!=NULL) return gzputs(file->zfptr,str);
+#endif
+ return fputs(str,file->nzfptr);
+}
+
+
+char * znzgets(char* str, int size, znzFile file)
+{
+ if (file==NULL) { return NULL; }
+#ifdef HAVE_LIBZ
+ if (file->zfptr!=NULL) return gzgets(file->zfptr,str,size);
+#endif
+ return fgets(str,size,file->nzfptr);
+}
+
+
+int znzflush(znzFile file)
+{
+ if (file==NULL) { return 0; }
+#ifdef HAVE_LIBZ
+ if (file->zfptr!=NULL) return gzflush(file->zfptr,Z_SYNC_FLUSH);
+#endif
+ return fflush(file->nzfptr);
+}
+
+
+int znzeof(znzFile file)
+{
+ if (file==NULL) { return 0; }
+#ifdef HAVE_LIBZ
+ if (file->zfptr!=NULL) return gzeof(file->zfptr);
+#endif
+ return feof(file->nzfptr);
+}
+
+
+int znzputc(int c, znzFile file)
+{
+ if (file==NULL) { return 0; }
+#ifdef HAVE_LIBZ
+ if (file->zfptr!=NULL) return gzputc(file->zfptr,c);
+#endif
+ return fputc(c,file->nzfptr);
+}
+
+
+int znzgetc(znzFile file)
+{
+ if (file==NULL) { return 0; }
+#ifdef HAVE_LIBZ
+ if (file->zfptr!=NULL) return gzgetc(file->zfptr);
+#endif
+ return fgetc(file->nzfptr);
+}
+
+#if !defined (WIN32)
+int znzprintf(znzFile stream, const char *format, ...)
+{
+ int retval=0;
+ char *tmpstr;
+ va_list va;
+ if (stream==NULL) { return 0; }
+ va_start(va, format);
+#ifdef HAVE_LIBZ
+ if (stream->zfptr!=NULL) {
+ int size; /* local to HAVE_LIBZ block */
+ size = strlen(format) + 1000000; /* overkill I hope */
+ tmpstr = (char *)calloc(1, size);
+ if( tmpstr == NULL ){
+ REprintf(/*fprintf(stderr,*/"** ERROR: znzprintf failed to alloc %d bytes\n", size);
+ return retval;
+ }
+ vsprintf(tmpstr,format,va);
+ retval=gzprintf(stream->zfptr,"%s",tmpstr);
+ free(tmpstr);
+ } else
+#endif
+ {
+ retval=vfprintf(stream->nzfptr,format,va);
+ }
+ va_end(va);
+ return retval;
+}
+
+#endif
+
diff --git a/src/znzlib.h b/src/znzlib.h
new file mode 100644
index 0000000..06cbf12
--- /dev/null
+++ b/src/znzlib.h
@@ -0,0 +1,129 @@
+#ifndef _ZNZLIB_H_
+#define _ZNZLIB_H_
+
+/*
+znzlib.h (zipped or non-zipped library)
+
+***** This code is released to the public domain. *****
+
+***** Author: Mark Jenkinson, FMRIB Centre, University of Oxford *****
+***** Date: September 2004 *****
+
+***** Neither the FMRIB Centre, the University of Oxford, nor any of *****
+***** its employees imply any warranty of usefulness of this software *****
+***** for any purpose, and do not assume any liability for damages, *****
+***** incidental or otherwise, caused by any use of this document. *****
+
+*/
+
+/*
+
+This library provides an interface to both compressed (gzip/zlib) and
+uncompressed (normal) file IO. The functions are written to have the
+same interface as the standard file IO functions.
+
+To use this library instead of normal file IO, the following changes
+are required:
+ - replace all instances of FILE* with znzFile
+ - change the name of all function calls, replacing the initial character
+ f with the znz (e.g. fseek becomes znzseek)
+ - add a third parameter to all calls to znzopen (previously fopen)
+ that specifies whether to use compression (1) or not (0)
+ - use znz_isnull rather than any (pointer == NULL) comparisons in the code
+
+NB: seeks for writable files with compression are quite restricted
+
+*/
+/* changes by Oliver Granert:
+- change HAVE_ZLIB to HAVE_LIBZ to fit autoconf tests
+*/
+
+/*=================*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*=================*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* include optional check for HAVE_FDOPEN here, from deleted config.h:
+
+ uncomment the following line if fdopen() exists for your compiler and
+ compiler options
+*/
+/* #define HAVE_FDOPEN */
+
+
+#ifdef HAVE_LIBZ
+#if defined(ITKZLIB)
+#include "itk_zlib.h"
+#else
+#include "zlib.h"
+#endif
+#endif
+
+
+struct znzptr {
+ int withz;
+ FILE* nzfptr;
+#ifdef HAVE_LIBZ
+ gzFile zfptr;
+#endif
+} ;
+
+/* the type for all file pointers */
+typedef struct znzptr * znzFile;
+
+
+/* int znz_isnull(znzFile f); */
+/* int znzclose(znzFile f); */
+#define znz_isnull(f) ((f) == NULL)
+#define znzclose(f) Xznzclose(&(f))
+
+/* Note extra argument (use_compression) where
+ use_compression==0 is no compression
+ use_compression!=0 uses zlib (gzip) compression
+*/
+
+znzFile znzopen(const char *path, const char *mode, int use_compression);
+
+znzFile znzdopen(int fd, const char *mode, int use_compression);
+
+int Xznzclose(znzFile * file);
+
+size_t znzread(void* buf, size_t size, size_t nmemb, znzFile file);
+
+size_t znzwrite(const void* buf, size_t size, size_t nmemb, znzFile file);
+
+long znzseek(znzFile file, long offset, int whence);
+
+int znzrewind(znzFile stream);
+
+long znztell(znzFile file);
+
+int znzputs(const char *str, znzFile file);
+
+char * znzgets(char* str, int size, znzFile file);
+
+int znzputc(int c, znzFile file);
+
+int znzgetc(znzFile file);
+
+#if !defined(WIN32)
+int znzprintf(znzFile stream, const char *format, ...);
+#endif
+
+/*=================*/
+#ifdef __cplusplus
+}
+#endif
+/*=================*/
+
+#endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-cran-rniftilib.git
More information about the debian-med-commit
mailing list