diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5c38f5013096b547ac3fa32bf5d16be6a45d6f04..109c251cdbcc8642c6c66bc22d51ae10a3d0d48a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,24 +1,31 @@
 ##################################################    Project     ##################################################
 cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
-project               (nifti VERSION 1.0 LANGUAGES CXX)
+project               (nifti VERSION 1.0 LANGUAGES C)
 list                  (APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
 set_property          (GLOBAL PROPERTY USE_FOLDERS ON)
 set                   (CMAKE_CXX_STANDARD 17)
+set                   (CMAKE_CXX_VISIBILITY_PRESET hidden)
+set                   (CMAKE_VISIBILITY_INLINES_HIDDEN 1)
 
 include               (set_max_warning_level)
 set_max_warning_level ()
 
 ##################################################    Options     ##################################################
+option(BUILD_SHARED_LIBS "Build shared (dynamic) libraries." ON)
 option(BUILD_TESTS "Build tests." OFF)
 
 ##################################################    Sources     ##################################################
-file(GLOB_RECURSE PROJECT_HEADERS include/*.h include/*.i include/*.hpp include/*.ipp)
+file(GLOB_RECURSE PROJECT_HEADERS include/*.h include/*.hpp)
+file(GLOB_RECURSE PROJECT_SOURCES source/*.c source/*.cpp)
 file(GLOB_RECURSE PROJECT_CMAKE_UTILS cmake/*.cmake)
 file(GLOB_RECURSE PROJECT_MISC *.md *.txt)
+set (PROJECT_EXPORT_HPP include/${PROJECT_NAME}/export.hpp)
 set (PROJECT_FILES 
   ${PROJECT_HEADERS} 
+  ${PROJECT_SOURCES} 
   ${PROJECT_CMAKE_UTILS} 
-  ${PROJECT_MISC})
+  ${PROJECT_MISC} 
+  ${PROJECT_EXPORT_HPP})
 
 include            (assign_source_group)
 assign_source_group(${PROJECT_FILES})
@@ -29,7 +36,7 @@ include(import_library)
 find_package  (ZLIB REQUIRED)
 import_library(ZLIB_INCLUDE_DIRS ZLIB_LIBRARIES)
 
-##################################################  Definitions   ##################################################
+##################################################   Definitions  ##################################################
 if    (ZLIB_FOUND)
   list(APPEND PROJECT_COMPILE_DEFINITIONS -DHAVE_ZLIB)
 endif ()
@@ -38,25 +45,31 @@ if    (UNIX)
   list(APPEND PROJECT_COMPILE_DEFINITIONS -DHAVE_FDOPEN -DUSE_STAT)
 endif ()
 
+
 ##################################################    Targets     ##################################################
-add_library(${PROJECT_NAME} INTERFACE)
-target_include_directories(${PROJECT_NAME} INTERFACE 
+add_library(${PROJECT_NAME} ${PROJECT_FILES})
+target_include_directories(${PROJECT_NAME} PUBLIC 
   $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
   $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
-  $<INSTALL_INTERFACE:include>)
-target_include_directories(${PROJECT_NAME} INTERFACE ${PROJECT_INCLUDE_DIRS})
-target_link_libraries     (${PROJECT_NAME} INTERFACE ${PROJECT_LIBRARIES})
-target_compile_definitions(${PROJECT_NAME} INTERFACE ${PROJECT_COMPILE_DEFINITIONS})
+  $<INSTALL_INTERFACE:include> PRIVATE source)
+target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_INCLUDE_DIRS})
+target_link_libraries     (${PROJECT_NAME} PUBLIC ${PROJECT_LIBRARIES})
+target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_COMPILE_DEFINITIONS})
+set_target_properties     (${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)
+
+if(NOT BUILD_SHARED_LIBS)
+  string               (TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPER)
+  set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS -D${PROJECT_NAME_UPPER}_STATIC)
+endif()
 
-# Hack for header-only project to appear in the IDEs.
-add_library(${PROJECT_NAME}_ STATIC ${PROJECT_FILES})
-target_include_directories(${PROJECT_NAME}_ PUBLIC 
-  ${CMAKE_CURRENT_SOURCE_DIR}/include 
-  ${CMAKE_CURRENT_BINARY_DIR})     
-target_include_directories(${PROJECT_NAME}_ PUBLIC ${PROJECT_INCLUDE_DIRS})
-target_link_libraries     (${PROJECT_NAME}_ PUBLIC ${PROJECT_LIBRARIES})
-target_compile_definitions(${PROJECT_NAME}_ PUBLIC ${PROJECT_COMPILE_DEFINITIONS})
-set_target_properties     (${PROJECT_NAME}_ PROPERTIES LINKER_LANGUAGE CXX)
+##################################################    Postbuild   ##################################################
+include               (GenerateExportHeader)
+string                (TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPER)
+generate_export_header(${PROJECT_NAME} 
+  EXPORT_FILE_NAME     ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME}/export.hpp
+  EXPORT_MACRO_NAME    ${PROJECT_NAME_UPPER}_EXPORT
+  STATIC_DEFINE        ${PROJECT_NAME_UPPER}_STATIC
+)
 
 ##################################################    Testing     ##################################################
 if(BUILD_TESTS)
@@ -79,7 +92,10 @@ if(BUILD_TESTS)
 endif()
 
 ##################################################  Installation  ##################################################
-install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-config)
+install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-config
+  ARCHIVE DESTINATION lib
+  LIBRARY DESTINATION lib
+  RUNTIME DESTINATION bin)
 install(DIRECTORY include/ DESTINATION include)
 install(EXPORT  ${PROJECT_NAME}-config DESTINATION cmake)
 export (TARGETS ${PROJECT_NAME}        FILE        ${PROJECT_NAME}-config.cmake)
diff --git a/include/nifti/nifti1_io.h b/include/nifti/nifti1_io.h
index 25547f14d07cb90b84de0ad6b86a5159287a80c4..99db9d9da7dbea1a9fe5defaccd5146362f06f7f 100644
--- a/include/nifti/nifti1_io.h
+++ b/include/nifti/nifti1_io.h
@@ -553,5 +553,3 @@ typedef struct {
 /*=================*/
 
 #endif /* _NIFTI_IO_HEADER_ */
-
-#include "nifti1_io.i"
\ No newline at end of file
diff --git a/include/nifti/nifti2.h b/include/nifti/nifti2.h
deleted file mode 100644
index 58e30629e940afe50faa4ab94d1c03740dbdba06..0000000000000000000000000000000000000000
--- a/include/nifti/nifti2.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/** \file nifti2.h
-    \brief Header structure for NIFTI-2 format.
- */
-
-#ifndef __NIFTI2_HEADER
-#define __NIFTI2_HEADER
-
-/*---------------------------------------------------------------------------*/
-/* Changes to the header from NIFTI-1 to NIFTI-2 are intended to allow for
-   larger and more accurate fields.  The changes are as follows:
-
-      - short dim[8]         -> int64_t dim[8]
-      - float intent_p1,2,3  -> double intent_p1,2,3    (3 fields)
-      - float pixdim[8]      -> double pixdim[8]
-      - float vox_offset     -> int64_t vox_offset
-      - float scl_slope      -> double scl_slope
-      - float scl_inter      -> double scl_inter
-      - float cal_max        -> double cal_max
-      - float cal_min        -> double cal_min
-      - float slice_duration -> double slice_duration
-      - float toffset        -> double toffset
-      - short slice_start    -> int64_t slice_start
-      - short slice_end      -> int64_t slice_end
-      - char slice_code      -> int32_t slice_code
-      - char xyzt_units      -> int32_t xyzt_units
-      - short intent_code    -> int32_t intent_code
-      - short qform_code     -> int32_t qform_code
-      - short sform_code     -> int32_t sform_code
-      - float quatern_b,c,d  -> double quatern_b,c,d    (3 fields)
-      - float srow_x,y,z[4]  -> double srow_x,y,z[4]    (3 fields)
-      - char magic[4]        -> char magic[8]
-      - char unused_str[15]  -> padding added at the end of the header   
-
-      - previously unused fields have been removed:
-           data_type, db_name, extents, session_error, regular, glmax, glmin
-
-      - the field order has been changed, notably with magic after sizeof_hdr
-
-                                                          2 Jan, 2014 [rickr]
------------------------------------------------------------------------------*/
-
-#include <stdint.h>
-
-/*=================*/
-#ifdef  __cplusplus
-extern "C" {
-#endif
-/*=================*/
-
-/*! \struct nifti_2_header
-    \brief Data structure defining the fields in the nifti2 header.
-           This binary header should be found at the beginning of a valid
-           NIFTI-2 header file.
- */
-
-/* hopefully cross-platform solution to byte padding added by some compilers */
-#pragma pack(push)
-#pragma pack(1)
-
-                           /*****************************/ /***********************/ /************/
-struct nifti_2_header {    /* NIFTI-2 usage             */ /* NIFTI-1 usage       */ /*  offset  */
-                           /*****************************/ /***********************/ /************/
-   int32_t sizeof_hdr;     /*!< MUST be 540             */ /* MUST be 348         */ /*   0 */
-   char    magic[8];       /*!< MUST be valid signature */ /* char magic[4]       */ /*   4 */
-   int16_t datatype;       /*!< Defines data type!      */ /* short datatype      */ /*  12 */
-   int16_t bitpix;         /*!< Number bits/voxel       */ /* short bitpix        */ /*  14 */
-   int64_t dim[8];         /*!< Data array dimensions   */ /* short dim[8]        */ /*  16 */
-   double  intent_p1;      /*!< 1st intent parameter    */ /* float intent_p1     */ /*  80 */
-   double  intent_p2;      /*!< 2nd intent parameter    */ /* float intent_p2     */ /*  88 */
-   double  intent_p3;      /*!< 3rd intent parameter    */ /* float intent_p3     */ /*  96 */
-   double  pixdim[8];      /*!< Grid spacings           */ /* float pixdim[8]     */ /* 104 */
-   int64_t vox_offset;     /*!< Offset into .nii file   */ /* float vox_offset    */ /* 168 */
-   double  scl_slope;      /*!< Data scaling: slope     */ /* float scl_slope     */ /* 176 */
-   double  scl_inter;      /*!< Data scaling: offset    */ /* float scl_inter     */ /* 184 */
-   double  cal_max;        /*!< Max display intensity   */ /* float cal_max       */ /* 192 */
-   double  cal_min;        /*!< Min display intensity   */ /* float cal_min       */ /* 200 */
-   double  slice_duration; /*!< Time for 1 slice        */ /* float slice_duration*/ /* 208 */
-   double  toffset;        /*!< Time axis shift         */ /* float toffset       */ /* 216 */
-   int64_t slice_start;    /*!< First slice index       */ /* short slice_start   */ /* 224 */
-   int64_t slice_end;      /*!< Last slice index        */ /* short slice_end     */ /* 232 */
-   char    descrip[80];    /*!< any text you like       */ /* char descrip[80]    */ /* 240 */
-   char    aux_file[24];   /*!< auxiliary filename      */ /* char aux_file[24]   */ /* 320 */
-   int32_t qform_code;     /*!< NIFTI_XFORM_* code      */ /* short qform_code    */ /* 344 */
-   int32_t sform_code;     /*!< NIFTI_XFORM_* code      */ /* short sform_code    */ /* 348 */
-   double  quatern_b;      /*!< Quaternion b param      */ /* float quatern_b     */ /* 352 */
-   double  quatern_c;      /*!< Quaternion c param      */ /* float quatern_c     */ /* 360 */
-   double  quatern_d;      /*!< Quaternion d param      */ /* float quatern_d     */ /* 368 */
-   double  qoffset_x;      /*!< Quaternion x shift      */ /* float qoffset_x     */ /* 376 */
-   double  qoffset_y;      /*!< Quaternion y shift      */ /* float qoffset_y     */ /* 384 */
-   double  qoffset_z;      /*!< Quaternion z shift      */ /* float qoffset_z     */ /* 392 */
-   double  srow_x[4];      /*!< 1st row affine transform*/ /* float srow_x[4]     */ /* 400 */
-   double  srow_y[4];      /*!< 2nd row affine transform*/ /* float srow_y[4]     */ /* 432 */
-   double  srow_z[4];      /*!< 3rd row affine transform*/ /* float srow_z[4]     */ /* 464 */
-   int32_t slice_code;     /*!< Slice timing order      */ /* char slice_code     */ /* 496 */
-   int32_t xyzt_units;     /*!< Units of pixdim[1..4]   */ /* char xyzt_units     */ /* 500 */
-   int32_t intent_code;    /*!< NIFTI_INTENT_* code     */ /* short intent_code   */ /* 504 */
-   char    intent_name[16];/*!< name or meaning of data */ /* char intent_name[16]*/ /* 508 */
-   char    dim_info;       /*!< MRI slice ordering      */ /* char dim_info       */ /* 524 */
-   char    unused_str[15]; /*!< unused, filled with \0  */                           /* 525 */
-};                                                                 /****** total bytes: 540 */
-typedef struct nifti_2_header nifti_2_header; 
-
-/* restore packing behavior */
-#pragma pack(pop)
-
-/* base swap test on the suggested version check, rather than dim[0]
-   swap4(348)==1543569408, swap4(540)==469893120 */
-#define NIFTI2_NEEDS_SWAP(h) \
-   ((h).sizeof_hdr == 1543569408 || (h).sizeof_hdr == 469893120)
-
-/*=================*/
-#ifdef  __cplusplus
-}
-#endif
-/*=================*/
-
-#endif /* __NIFTI2_HEADER */
diff --git a/include/nifti/nifti2_io.h b/include/nifti/nifti2_io.h
deleted file mode 100644
index 02342699e34e9a16d324ee3e3591d496596b3504..0000000000000000000000000000000000000000
--- a/include/nifti/nifti2_io.h
+++ /dev/null
@@ -1,736 +0,0 @@
-/** \file nifti2_io.h
-    \brief Data structures for using nifti2_io API.
-           - Written by Bob Cox, SSCC NIMH
-           - Revisions by Rick Reynolds, SSCC NIMH
- */
-#ifndef _NIFTI2_IO_HEADER_
-#define _NIFTI2_IO_HEADER_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <limits.h>
-#include <ctype.h>
-
-#ifndef DONT_INCLUDE_ANALYZE_STRUCT
-#define DONT_INCLUDE_ANALYZE_STRUCT  /*** not needed herein ***/
-#endif
-#include "nifti1.h"                  /*** NIFTI-1 header specification ***/
-#include "nifti2.h"                  /*** NIFTI-2 header specification ***/
-
-#include "znzlib.h"
-
-/*=================*/
-#ifdef  __cplusplus
-extern "C" {
-#endif
-/*=================*/
-
-/*****===================================================================*****/
-/*****         File nifti2_io.h == Declarations for nifti2_io.c          *****/
-/*****...................................................................*****/
-/*****            This code is a modification of nifti1_io.h.            *****/
-/*****...................................................................*****/
-/*****            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, particularly involving
-      extensions and nifti_brick_list.
-
-   ......................................................................
-   Modified by: Rick Reynolds (SSCC/DIRP/NIMH, National Institutes of Health)
-   Date: August 2013
-
-      Converted to be based on nifti_2_header.
-
-      ** NOT BACKWARD COMPATABLE **
-
-      These routines will read/write both NIFTI-1 and NIFTI-2 image files,
-      but modification to the _calling_ routies is necessary, since:
-
-        a. the main nifti_image type has changed (to nifti2_image)
-        b. some image field types have been altered (to have larger size)
-        c. some routines have been changed to apply to multiple NIFTI types
-*/
-
-/********************** Some sample data structures **************************/
-
-typedef struct {                   /** 4x4 matrix struct **/
-  float m[4][4] ;
-} mat44 ;
-
-typedef struct {                   /** 3x3 matrix struct **/
-  float m[3][3] ;
-} mat33 ;
-
-typedef struct {                   /** 4x4 matrix struct (double) **/
-  double m[4][4] ;
-} nifti_dmat44 ;
-
-typedef struct {                   /** 3x3 matrix struct (double) **/
-  double m[3][3] ;
-} nifti_dmat33 ;
-
-/*...........................................................................*/
-
-/*! \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
-           nifti2_io API.  Note that this structure is not part of the
-           nifti2 format definition; it is used to implement one API
-           for reading/writing datasets in the nifti1 or nifti2 formats.
-
-    Field types changed for NIFTI-2 (note: ALL floats to doubles):
-        nx, ny, ..., nw, dim, nvox,
-        dx, dy, ..., dw, pixdim,
-        scl_slope, scl_inter, cal_min, cal_max,
-        slice_start, slice_end, slice_duration,
-        quatern_b,c,d, qoffset_x,y,z, qfac,
-        qto_xyz,ijk, sto_xyz,ijk,
-        toffset, intent_p1,2,3, iname_offset
- */
-typedef struct {                /*!< Image storage struct **/
-
-  int64_t ndim ;                /*!< last dimension greater than 1 (1..7) */
-  int64_t nx ;                  /*!< dimensions of grid array             */
-  int64_t ny ;                  /*!< dimensions of grid array             */
-  int64_t nz ;                  /*!< dimensions of grid array             */
-  int64_t nt ;                  /*!< dimensions of grid array             */
-  int64_t nu ;                  /*!< dimensions of grid array             */
-  int64_t nv ;                  /*!< dimensions of grid array             */
-  int64_t nw ;                  /*!< dimensions of grid array             */
-  int64_t dim[8] ;              /*!< dim[0]=ndim, dim[1]=nx, etc.         */
-  int64_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    */
-
-  double dx ;                   /*!< grid spacings      */
-  double dy ;                   /*!< grid spacings      */
-  double dz ;                   /*!< grid spacings      */
-  double dt ;                   /*!< grid spacings      */
-  double du ;                   /*!< grid spacings      */
-  double dv ;                   /*!< grid spacings      */
-  double dw ;                   /*!< grid spacings      */
-  double pixdim[8] ;            /*!< pixdim[1]=dx, etc. */
-
-  double scl_slope ;            /*!< scaling parameter - slope        */
-  double scl_inter ;            /*!< scaling parameter - intercept    */
-
-  double cal_min ;              /*!< calibration parameter, minimum   */
-  double 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    */
-  int64_t slice_start ;         /*!< index for start of slices        */
-  int64_t slice_end   ;         /*!< index for end of slices          */
-  double  slice_duration ;      /*!< time between individual slices   */
-
-  /*! quaternion transform parameters
-    [when writing a dataset, these are used for qform, NOT qto_xyz]   */
-  double quatern_b , quatern_c , quatern_d ,
-         qoffset_x , qoffset_y , qoffset_z ,
-         qfac      ;
-
-  nifti_dmat44 qto_xyz ;        /*!< qform: transform (i,j,k) to (x,y,z) */
-  nifti_dmat44 qto_ijk ;        /*!< qform: transform (x,y,z) to (i,j,k) */
-
-  nifti_dmat44 sto_xyz ;        /*!< sform: transform (i,j,k) to (x,y,z) */
-  nifti_dmat44 sto_ijk ;        /*!< sform: transform (x,y,z) to (i,j,k) */
-
-  double 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 ;              /*!< see NIFTI_FTYPE_* codes, below:
-                                        0==ANALYZE,
-                                        1==NIFTI-1     (1 file),
-                                        2==NIFTI-1     (2 files),
-                                        3==NIFTI-ASCII (1 file)
-                                        4==NIFTI-2     (1 file),
-                                        5==NIFTI-2     (2 files) */
-
-  int    intent_code ;          /*!< statistic type (or something)       */
-  double intent_p1 ;            /*!< intent parameters                   */
-  double intent_p2 ;            /*!< intent parameters                   */
-  double 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)         */
-  int64_t 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 ;
-
-/* allow clarity */
-typedef nifti_image nifti2_image;
-
-typedef 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.         */
-  int64_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 */
-
-} nifti1_image ;
-
-/* struct for return from nifti_image_read_bricks() */
-typedef struct {
-  int64_t   nbricks;    /* the number of allocated pointers in 'bricks' */
-  int64_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 const * nifti_datatype_string   ( int dt ) ;
-char const *nifti_units_string      ( int uu ) ;
-char const *nifti_intent_string     ( int ii ) ;
-char const *nifti_xform_string      ( int xx ) ;
-char const *nifti_slice_string      ( int ss ) ;
-char const *nifti_orientation_string( int ii ) ;
-
-int   nifti_is_inttype( int dt ) ;
-
-mat44        nifti_mat44_inverse ( mat44 R ) ;
-nifti_dmat44 nifti_dmat44_inverse( nifti_dmat44 R ) ;
-int          nifti_mat44_to_dmat44(mat44 * fm, nifti_dmat44 * dm);
-int          nifti_dmat44_to_mat44(nifti_dmat44 * dm, mat44 * fm);
-
-nifti_dmat33 nifti_dmat33_inverse( nifti_dmat33 R ) ;
-nifti_dmat33 nifti_dmat33_polar  ( nifti_dmat33 A ) ;
-double       nifti_dmat33_rownorm( nifti_dmat33 A ) ;
-double       nifti_dmat33_colnorm( nifti_dmat33 A ) ;
-double       nifti_dmat33_determ ( nifti_dmat33 R ) ;
-nifti_dmat33 nifti_dmat33_mul    ( nifti_dmat33 A , nifti_dmat33 B ) ;
-
-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 ( int64_t n , void *ar ) ;
-void  nifti_swap_4bytes ( int64_t n , void *ar ) ;
-void  nifti_swap_8bytes ( int64_t n , void *ar ) ;
-void  nifti_swap_16bytes( int64_t n , void *ar ) ;
-void  nifti_swap_Nbytes ( int64_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_header_version          (const char * buf, int nbytes);
-
-int64_t nifti_get_filesize( const char *pathname ) ;
-void  swap_nifti_header ( void * h , int ni_ver ) ;
-void  old_swap_nifti_header( struct nifti_1_header *h , int is_nifti );
-void  nifti_swap_as_analyze( nifti_analyze75 *h );
-void  nifti_swap_as_nifti1( nifti_1_header *h );
-void  nifti_swap_as_nifti2( nifti_2_header *h );
-
-
-/* main read/write routines */
-
-nifti_image *nifti_image_read_bricks(const char *hname , int64_t nbricks,
-                               const int64_t *blist, nifti_brick_list * NBL);
-int          nifti_image_load_bricks(nifti_image *nim , int64_t nbricks,
-                               const int64_t *blist, nifti_brick_list * NBL);
-void         nifti_free_NBL( nifti_brick_list * NBL );
-
-nifti_image *nifti_image_read    ( const char *hname , int read_data);
-int          nifti_image_load    ( nifti_image *nim);
-void         nifti_image_unload  ( nifti_image *nim);
-void         nifti_image_free    ( nifti_image *nim);
-
-int64_t      nifti_read_collapsed_image( nifti_image * nim,
-                                         const int64_t dims[8], void ** data);
-
-int64_t      nifti_read_subregion_image(nifti_image *nim, int64_t *start_index,
-                                        int64_t *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( int ver ) ;  /* to display library history */
-void         nifti_disp_lib_version( void ) ;  /* to display library version */
-int          nifti_disp_matrix_orient( const char * mesg, nifti_dmat44 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 ) ;
-
-int64_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 ) ;
-int    disp_nifti_2_header( const char * info, const nifti_2_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    nifti_get_alter_cifti( void );
-void   nifti_set_alter_cifti( int alter_cifti );
-
-int    nifti_alter_cifti_dims(nifti_image * nim);
-
-
-int    valid_nifti_brick_list(nifti_image * nim , int64_t nbricks,
-                              const int64_t * 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);
-int64_t nifti_read_buffer(znzFile fp, void* datatptr, int64_t ntot,
-                         nifti_image *nim);
-int     nifti_write_all_data(znzFile fp, nifti_image * nim,
-                             const nifti_brick_list * NBL);
-int64_t  nifti_write_buffer(znzFile fp, const void * buffer, int64_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_dmat44_to_quatern(nifti_dmat44 R ,
-                             double *qb, double *qc, double *qd,
-                             double *qx, double *qy, double *qz,
-                             double *dx, double *dy, double *dz, double *qfac);
-
-nifti_dmat44 nifti_quatern_to_dmat44( double qb, double qc, double qd,
-                             double qx, double qy, double qz,
-                             double dx, double dy, double dz, double qfac );
-
-nifti_dmat44 nifti_make_orthog_dmat44( double r11, double r12, double r13 ,
-                                 double r21, double r22, double r23 ,
-                                 double r31, double r32, double r33  ) ;
-
-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 ) ;
-void nifti_dmat44_to_orientation( nifti_dmat44 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 */
-int   nifti_convert_nim2n1hdr(const nifti_image* nim, nifti_1_header * hdr);
-int   nifti_convert_nim2n2hdr(const nifti_image* nim, nifti_2_header * hdr);
-nifti_1_header * nifti_make_new_n1_header(const int64_t arg_dims[], int dtype);
-nifti_2_header * nifti_make_new_n2_header(const int64_t arg_dims[], int dtype);
-void           * nifti_read_header(const char *hname, int *nver,    int check);
-nifti_1_header * nifti_read_n1_hdr(const char *hname, int *swapped, int check);
-nifti_2_header * nifti_read_n2_hdr(const char *hname, int *swapped, int check);
-nifti_image    * nifti_copy_nim_info(const nifti_image * src);
-nifti_image    * nifti_make_new_nim(const int64_t dims[], int datatype,
-                                    int data_fill);
-
-
-nifti_image    * nifti_simple_init_nim(void);
-nifti_image    * nifti_convert_n1hdr2nim(nifti_1_header nhdr,const char *fname);
-nifti_image    * nifti_convert_n2hdr2nim(nifti_2_header nhdr,const char *fname);
-
-int    nifti_looks_like_cifti(nifti_image * nim);
-
-int    nifti_hdr1_looks_good       (const nifti_1_header * hdr);
-int    nifti_hdr2_looks_good       (const nifti_2_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);
-int64_t * nifti_get_int64list(int64_t nvals , const char *str);
-int     * nifti_get_intlist  (int nvals , const char *str);
-char * nifti_strdup          (const char *str);
-int    valid_nifti_extensions(const nifti_image *nim);
-int    nifti_valid_header_size(int ni_ver, int whine);
-
-
-/*-------------------- 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@nih.gov
-                                           https://afni.nimh.nih.gov/afni     */
-
-#define NIFTI_ECODE_COMMENT          6  /* plain ASCII text only              */
-
-#define NIFTI_ECODE_XCEDE            8  /* David B Keator: dbkeator@uci.edu
-                                           http://www.nbirn.net/Resources
-                                                /Users/Applications/
-                                                /xcede/index.htm              */
-
-#define NIFTI_ECODE_JIMDIMINFO      10  /* Mark A Horsfield:
-                                           mah5@leicester.ac.uk
-                                           http://someplace/something         */
-
-#define NIFTI_ECODE_WORKFLOW_FWDS   12  /* Kate Fissell: fissell@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@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@brainvis.wustl.edu
-                                           http://brainvis.wustl.edu/wiki
-                                             /index.php/Caret:Documentation
-                                             :CaretNiftiExtension             */
-
-#define NIFTI_ECODE_CIFTI           32  /* CIFTI-2_Main_FINAL_1March2014.pdf */
-
-#define NIFTI_ECODE_VARIABLE_FRAME_TIMING 34
-
-/* 36 is currently unassigned, waiting on NIFTI_ECODE_AGILENT_PROCPAR */
-
-#define NIFTI_ECODE_EVAL            38  /* Munster University Hospital */
-
-/* http://www.mathworks.com/matlabcentral/fileexchange/42997-dicom-to-nifti-converter */
-#define NIFTI_ECODE_MATLAB          40  /* MATLAB extension */
-
-
-#define NIFTI_MAX_ECODE             40  /******* maximum extension code *******/
-
-/* nifti_type file codes */
-#define NIFTI_FTYPE_ANALYZE   0         /* old ANALYZE */
-#define NIFTI_FTYPE_NIFTI1_1  1         /* NIFTI-1     */
-#define NIFTI_FTYPE_NIFTI1_2  2
-#define NIFTI_FTYPE_ASCII     3
-#define NIFTI_FTYPE_NIFTI2_1  4         /* NIFTI-2     */
-#define NIFTI_FTYPE_NIFTI2_2  5
-#define NIFTI_MAX_FTYPE       5         /* this should match the maximum code */
-
-/*------------------------------------------------------------------------*/
-/*-- the rest of these apply only to nifti2_io.c, check for _NIFTI2_IO_C_ */
-
-#ifdef _NIFTI2_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 */
-    int alter_cifti;         /*!< convert CIFTI dimensions        */
-} 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 const * const 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)                                      \
-            fprintf(stderr,"** 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 */
-
-#undef NIFTI_IS_16_BIT_INT
-#define NIFTI_IS_16_BIT_INT(x) ((x) <= 32767 && (x) >= -32768)
-
-#endif  /* _NIFTI2_IO_C_ section */
-/*------------------------------------------------------------------------*/
-
-/*=================*/
-#ifdef  __cplusplus
-}
-#endif
-/*=================*/
-
-#endif /* _NIFTI2_IO_HEADER_ */
-
-#include "nifti2_io.i"
\ No newline at end of file
diff --git a/include/nifti/nifti2_io.i b/include/nifti/nifti2_io.i
deleted file mode 100644
index 9ba9cc4e8c010b91c940f6cc764cf191a5b274a5..0000000000000000000000000000000000000000
--- a/include/nifti/nifti2_io.i
+++ /dev/null
@@ -1,9479 +0,0 @@
-#define _NIFTI2_IO_C_
-
-/*****===================================================================*****/
-/*****     Sample functions to deal with NIFTI-1,2 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".
- */
-
-/*! global history and version strings, for printing */
-static char const * const gni1_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_ZLIB 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.44 19 Jul 2013 [rickr]: ITK compatibility updates from H Johnson\n",
-  "----------------------------------------------------------------------\n"
-};
-
-/* rcr - todo
-
-   - nifti_tool -copy_sform SFORM_DSET.nii -infile ORIG.nii -prefix PP
-                -copy_orient SFORM_DSET.nii -infile ORIG.nii -prefix PP
-
-   - check converting nim 2 n2hdr
-   - update for n2 (and/or split from n1)
-      - is_nifti_file (maybe use nifti_header_version), nifti_hdr_looks_good
-   - extensions
-   - nifti_make_new_n1_header: check that dims are small enough (<2^15)
-   - nifti_convert_nim2nhdr: rename to nim2n1hdr and write nim2n2hdr
-     (maybe have nifti_convert_nim2nhdr wrap current version)
-   - nifti_set_iname_offset: n2 update via nifti_type
-   - track use of nifti_type
-   - nifti_image_write_hdr_img2: write nifti_2_header
- */
-
-static char const * const gni2_history[] =
-{
-  "----------------------------------------------------------------------\n"
-  "history (of nifti-2 library changes):\n"
-  "\n",
-  "2.00 02 Jan, 2014 [rickr]\n"
-  "     Richard Reynolds of the National Institutes of Health, SSCC/DIRP/NIMH\n"
-  "   - initial version - change types to 64-bit based on new nifti_image\n",
-  "2.01 04 Apr, 2014 [rickr]\n"
-  "   - added functionality for both nifti-1 and -2 headers\n"
-  "     (read/display/swap/convert2nim/make_new_n?_hdr)\n"
-  "   - still needs much nifti-2 functionality\n",
-  "2.02 11 May, 2015 [rickr]\n"
-  "   - added to repository 28 Apr, 2015\n"
-  "   - nifti_read_header() now returns found header struct\n"
-  "2.03 23 Jul, 2015 [rickr]\n"
-  "   - possibly alter dimensions on CIFTI read\n"
-  "   - return N-1 headers in unknown version cases\n",
-  "2.04 05 Aug, 2015 [rickr]\n"
-  "   - have writing try NIFTI-2 if NIFTI-1 seesm insufficient\n"
-};
-
-static const char gni_version[]
-        = "nifti-2 library version 2.04 (5 August, 2015)";
-
-/*! global nifti options structure - init with defaults */
-/*  see 'option accessor functions'                     */
-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 */
-        0, /* alter_cifti       - alter CIFTI dims to use nx,t,u,v*/
-};
-
-char nifti1_magic[4] = { 'n', '+', '1', '\0' };
-char nifti2_magic[8] = { 'n', '+', '2', '\0', '\r', '\n', '\032', '\n' };
-
-/*! global nifti types structure list (per type, ordered oldest to newest) */
-static const 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, int64_t 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,
-                                              int64_t 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);
-static void compute_strides(int64_t *strides,const int64_t *size,int nbyper);
-
-/* NBL routines */
-static int  nifti_load_NBL_bricks(nifti_image * nim , int64_t * slist,
-                       int64_t * sindex, nifti_brick_list * NBL, znzFile fp );
-static int  nifti_alloc_NBL_mem(  nifti_image * nim, int64_t nbricks,
-                                  nifti_brick_list * nbl);
-static int  nifti_copynsort(int64_t nbricks, const int64_t *blist,
-                            int64_t **slist, int64_t **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, int64_t *prods,
-                          int nprods, const int64_t dims[], char *data,
-                          znzFile fp, int64_t base_offset);
-static int rci_alloc_mem(void **data, int64_t prods[8], int nprods, int nbyper);
-static int  make_pivot_list(nifti_image * nim, const int64_t dims[],
-                            int pivots[], int64_t 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, size_t 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);
-
-/* consider for export */
-static int  nifti_ext_type_index(nifti_image * nim, int ecode);
-
-/* 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( int ver )
-{
-   int c, len;
-
-   switch ( ver ) {
-      default: {
-         fprintf(stderr,"** disp_lib_list: bad ver %d\n", ver);
-         break;
-      }
-
-      case 0:
-      case 2: {
-         len = sizeof(gni2_history)/sizeof(char *);
-         for( c = 0; c < len; c++ )
-             fputs(gni2_history[c], stdout);
-         break;
-      }
-      case 1: {
-         len = sizeof(gni1_history)/sizeof(char *);
-         for( c = 0; c < len; c++ )
-             fputs(gni1_history[c], stdout);
-         break;
-      }
-   }
-}
-
-/*----------------------------------------------------------------------*/
-/*! display the nifti library version (via stdout)
-*//*--------------------------------------------------------------------*/
-void nifti_disp_lib_version( void )
-{
-   printf("%s, compiled %s\n", gni_version, __DATE__);
-}
-
-
-/*----------------------------------------------------------------------*/
-/*! 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, int64_t nbricks,
-                                 const int64_t * blist, nifti_brick_list * NBL)
-{
-   nifti_image * nim;
-
-   if( !hname || !NBL ){
-      fprintf(stderr,"** nifti_image_read_bricks: bad params (%p,%p)\n",
-              hname, (void *)NBL);
-      return NULL;
-   }
-
-   if( blist && nbricks <= 0 ){
-      fprintf(stderr,"** nifti_image_read_bricks: bad nbricks, %lld\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 ,
-                                               int64_t nbricks )
-{
-   int64_t ndim;
-
-   if( g_opts.debug > 2 ){
-      fprintf(stderr,"+d updating image dimensions for %lld bricks in list\n",
-              nbricks);
-      fprintf(stderr,"   ndim = %lld\n",nim->ndim);
-      fprintf(stderr,"   nx,ny,nz,nt,nu,nv,nw: (%lld,%lld,%lld,%lld,%lld,%lld,%lld)\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 ){
-      fprintf(stderr,"+d ndim = %lld -> %lld\n",nim->ndim, ndim);
-      fprintf(stderr," --> (%lld,%lld,%lld,%lld,%lld,%lld,%lld)\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;
-   int64_t ndim;
-
-   if( !nim ){
-      fprintf(stderr,"** update_dims: missing nim\n");
-      return 1;
-   }
-
-   if( g_opts.debug > 2 ){
-      fprintf(stderr,"+d updating image dimensions given nim->dim:");
-      for( c = 0; c < 8; c++ ) fprintf(stderr," %lld", nim->dim[c]);
-      fputc('\n',stderr);
-   }
-
-   /* verify dim[0] first */
-   if(nim->dim[0] < 1 || nim->dim[0] > 7){
-      fprintf(stderr,"** invalid dim[0], dim[] = ");
-      for( c = 0; c < 8; c++ ) fprintf(stderr," %lld", nim->dim[c]);
-      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 ){
-      fprintf(stderr,"+d ndim = %lld -> %lld\n",nim->ndim, ndim);
-      fprintf(stderr," --> (%lld,%lld,%lld,%lld,%lld,%lld,%lld)\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 , int64_t nbricks,
-                             const int64_t * blist, nifti_brick_list * NBL )
-{
-   int64_t * slist = NULL, * sindex = NULL;
-   int       rv;
-   znzFile   fp;
-
-   /* we can have blist == NULL */
-   if( !nim || !NBL ){
-      fprintf(stderr,"** nifti_image_load_bricks, bad params (%p,%p)\n",
-              (void *)nim, (void *)NBL);
-      return -1;
-   }
-
-   if( blist && nbricks <= 0 ){
-      if( g_opts.debug > 1 )
-         fprintf(stderr,"-d load_bricks: received blist with nbricks = %lld,"
-                        "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 )
-         fprintf(stderr,"** 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 , int64_t * slist,
-                        int64_t * sindex, nifti_brick_list * NBL, znzFile fp )
-{
-   int64_t oposn, fposn;      /* orig and current file positions */
-   int64_t rv, test;
-   int64_t c;
-   int64_t prev, isrc, idest; /* previous/current sub-brick, and new index */
-
-   test = znztell(fp);  /* store current file position */
-   if( test < 0 ){
-      fprintf(stderr,"** 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 ){
-            fprintf(stderr,"** load bricks: cannot read brick %lld from '%s'\n",
-                    c, nim->iname ? nim->iname : nim->fname);
-            return -1;
-         }
-      }
-      if( g_opts.debug > 1 )
-         fprintf(stderr,"+d read %lld default %lld-byte bricks from file %s\n",
-                 NBL->nbricks, NBL->bsize,
-                 nim->iname ? nim->iname:nim->fname );
-      return 0;
-   }
-
-   if( !sindex ){
-      fprintf(stderr,"** 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;
-             /* rcr - znz functions need to handle 64-bit cases, */
-             /* see setting _FILE_OFFSET_BITS                    */
-             if( znzseek(fp, fposn, SEEK_SET) < 0 ){
-                fprintf(stderr,"** failed to locate brick %lld 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 ){
-             fprintf(stderr,"** failed to read brick %lld from file '%s'\n",
-                     isrc, nim->iname ? nim->iname : nim->fname);
-             if( g_opts.debug > 1 )
-                fprintf(stderr,"   (read %lld of %lld bytes)\n", rv, 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, int64_t nbricks,
-                               nifti_brick_list * nbl)
-{
-   int64_t 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  = nim->nx * nim->ny * nim->nz * nim->nbyper; /* bytes */
-   nbl->bricks = (void **)malloc(nbl->nbricks * sizeof(void *));
-
-   if( ! nbl->bricks ){
-      fprintf(stderr,"** NANM: failed to alloc %lld void ptrs\n",nbricks);
-      return -1;
-   }
-
-   for( c = 0; c < nbl->nbricks; c++ ){
-      nbl->bricks[c] = (void *)malloc(nbl->bsize);
-      if( ! nbl->bricks[c] ){
-         fprintf(stderr,"** NANM: failed to alloc %lld bytes for brick %lld\n",
-                 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 )
-      fprintf(stderr,"+d NANM: alloc'd %lld bricks of %lld bytes for NBL\n",
-              nbl->nbricks, 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(int64_t nbricks, const int64_t *blist,
-                           int64_t ** slist, int64_t ** sindex)
-{
-   int64_t * stmp, * itmp;   /* for ease of typing/reading */
-   int64_t   c1, c2, spos, tmp;
-
-   *slist  = (int64_t *)malloc(nbricks * sizeof(int64_t));
-   *sindex = (int64_t *)malloc(nbricks * sizeof(int64_t));
-
-   if( !*slist || !*sindex ){
-      fprintf(stderr,"** NCS: failed to alloc %lld ints for sorting\n",nbricks);
-      if(*slist)  free(*slist);   /* maybe one succeeded */
-      if(*sindex) free(*sindex);
-      return -1;
-   }
-
-   /* init the lists */
-   for( c1 = 0; c1 < nbricks; c1++ ) {
-      (*slist)[c1] = blist[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 ){
-      fprintf(stderr,  "+d sorted indexing list:\n");
-      fprintf(stderr,  "  orig   : ");
-      for( c1 = 0; c1 < nbricks; c1++ ) fprintf(stderr,"  %lld",blist[c1]);
-      fprintf(stderr,"\n  new    : ");
-      for( c1 = 0; c1 < nbricks; c1++ ) fprintf(stderr,"  %lld",stmp[c1]);
-      fprintf(stderr,"\n  indices: ");
-      for( c1 = 0; c1 < nbricks; c1++ ) fprintf(stderr,"  %lld",itmp[c1]);
-      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]) ){
-          fprintf(stderr,"** sorting screw-up, way to go, rick!\n");
-          free(stmp); free(itmp); *slist = NULL; *sindex = NULL;
-          return -1;
-       }
-   }
-
-   if( g_opts.debug > 2 ) fprintf(stderr,"-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 , int64_t nbricks,
-                           const int64_t * blist, int disp_error)
-{
-   int64_t c, nsubs;
-
-   if( !nim ){
-      if( disp_error || g_opts.debug > 0 )
-         fprintf(stderr,"** valid_nifti_brick_list: missing nifti image\n");
-      return 0;
-   }
-
-   if( nbricks <= 0 || !blist ){
-      if( disp_error || g_opts.debug > 1 )
-         fprintf(stderr,"** valid_nifti_brick_list: no brick list to check\n");
-      return 0;
-   }
-
-   if( nim->dim[0] < 3 ){
-      if( disp_error || g_opts.debug > 1 )
-        fprintf(stderr,"** cannot read explict brick list from %lld-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 ){
-      fprintf(stderr,"** VNBL warning: bad dim list (%lld,%lld,%lld,%lld)\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 )
-            fprintf(stderr,
-               "** volume index %lld (#%lld) is out of range [0,%lld]\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)
-{
-   int64_t volbytes = 0;     /* bytes per volume */
-   int64_t nvols = 0;
-   int     ind, errs = 0;
-
-
-   if( !nim || !NBL ) {
-      if( g_opts.debug > 0 )
-         fprintf(stderr,"** 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 = (int64_t)nim->nbyper;
-      for( ind = 1; ind <= nim->ndim && ind < 4; ind++ )
-         volbytes *= 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 )
-         fprintf(stderr,"** NBL/nim mismatch, volbytes = %lld, %lld\n",
-                 NBL->bsize, volbytes);
-      errs++;
-   }
-
-   if( nvols != NBL->nbricks ) {
-      if( g_opts.debug > 1 )
-         fprintf(stderr,"** NBL/nim mismatch, nvols = %lld, %lld\n",
-                 NBL->nbricks, nvols);
-      errs++;
-   }
-
-   if( errs ) return 0;
-   else if ( g_opts.debug > 2 )
-      fprintf(stderr,"-- nim/NBL agree: nvols = %lld, nbytes = %lld\n",
-              nvols, 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, nifti_dmat44 mat )
-{
-   int i, j, k;
-
-   if ( mesg ) fputs( mesg, stderr );  /* use stdout? */
-
-   nifti_dmat44_to_orientation( mat, &i,&j,&k );
-   if ( i <= 0 || j <= 0 || k <= 0 ) return -1;
-
-   /* so we have good codes */
-   fprintf(stderr, "  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      fprintf(stderr,"** nifti_strdup: failed to alloc %lld bytes\n",
-                    (int64_t)(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 const * 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 const *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 const *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 const *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 const *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 const *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 ;
-}
-
-
-/*-----------------------------------------------------------------*/
-/*! copy between float and double mat44 types 10 Jul, 2015 [rickr] */
-
-int nifti_mat44_to_dmat44(mat44 * fm, nifti_dmat44 * dm)
-{
-   int i, j;
-   if( !dm || !fm ) return 1;
-   for( i=0; i<4; i++ )
-      for( j=0; j<4; j++ )
-         dm->m[i][j] = (double)fm->m[i][j];
-   return 0;
-}
-
-int nifti_dmat44_to_mat44(nifti_dmat44 * dm, mat44 * fm)
-{
-   int i, j;
-   if( !dm || !fm ) return 1;
-   for( i=0; i<4; i++ )
-      for( j=0; j<4; j++ )
-         fm->m[i][j] = (float)dm->m[i][j];
-   return 0;
-}
-
-
-/*---------------------------------------------------------------------------*/
-/*! Given the quaternion parameters (etc.), compute a transformation matrix
-    of doubles.
-
-   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
-
-*//*-------------------------------------------------------------------------*/
-nifti_dmat44 nifti_quatern_to_dmat44( double qb, double qc, double qd,
-                                double qx, double qy, double qz,
-                                double dx, double dy, double dz, double qfac )
-{
-   nifti_dmat44 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 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.0f ; R.m[3][3]= 1.0f ;
-
-   /* 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] = (float)( (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] = (float)( (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] = (float)( (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_dmat44 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_dmat44, nifti_make_orthog_dmat44,
-       nifti_dmat44_to_orientation
-*//*-------------------------------------------------------------------------*/
-void nifti_dmat44_to_quatern(nifti_dmat44 R ,
-                             double *qb, double *qc, double *qd,
-                             double *qx, double *qy, double *qz,
-                             double *dx, double *dy, double *dz, double *qfac )
-{
-   double r11,r12,r13 , r21,r22,r23 , r31,r32,r33 ;
-   double xd,yd,zd , a,b,c,d ;
-   nifti_dmat33 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_dmat33_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 ;
-}
-
-/*---------------------------------------------------------------------------*/
-/*! 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,(float)xd) ; ASSIF(dy,(float)yd) ; ASSIF(dz,(float)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] = (float)r11 ; Q.m[0][1] = (float)r12 ; Q.m[0][2] = (float)r13 ; /* load Q */
-   Q.m[1][0] = (float)r21 ; Q.m[1][1] = (float)r22 ; Q.m[1][2] = (float)r23 ;
-   Q.m[2][0] = (float)r31 ; Q.m[2][1] = (float)r32 ; Q.m[2][2] = (float)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.0f) ;
-   } else {                  /* improper ==> flip 3rd column */
-     ASSIF(qfac,-1.0f) ;
-     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,(float)b) ; ASSIF(qc,(float)c) ; ASSIF(qd,(float)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>
-*//*-------------------------------------------------------------------------*/
-nifti_dmat44 nifti_dmat44_inverse( nifti_dmat44 R )
-{
-   double r11,r12,r13,r21,r22,r23,r31,r32,r33,v1,v2,v3 , deti ;
-   nifti_dmat44 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 ;
-}
-
-/*---------------------------------------------------------------------------*/
-/*! 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] = (float)( deti*( r22*r33-r32*r23) ) ;
-   Q.m[0][1] = (float)( deti*(-r12*r33+r32*r13) ) ;
-   Q.m[0][2] = (float)( deti*( r12*r23-r22*r13) ) ;
-   Q.m[0][3] = (float)( deti*(-r12*r23*v3+r12*v2*r33+r22*r13*v3
-                     -r22*v1*r33-r32*r13*v2+r32*v1*r23) ) ;
-
-   Q.m[1][0] = (float)( deti*(-r21*r33+r31*r23) ) ;
-   Q.m[1][1] = (float)( deti*( r11*r33-r31*r13) ) ;
-   Q.m[1][2] = (float)( deti*(-r11*r23+r21*r13) ) ;
-   Q.m[1][3] = (float)( deti*( r11*r23*v3-r11*v2*r33-r21*r13*v3
-                     +r21*v1*r33+r31*r13*v2-r31*v1*r23) ) ;
-
-   Q.m[2][0] = (float)( deti*( r21*r32-r31*r22) ) ;
-   Q.m[2][1] = (float)( deti*(-r11*r32+r31*r12) ) ;
-   Q.m[2][2] = (float)( deti*( r11*r22-r21*r12) ) ;
-   Q.m[2][3] = (float)( 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 nifti_dmat44 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_dmat44, nifti_dmat44_to_quatern,
-       nifti_dmat44_to_orientation
-*//*-------------------------------------------------------------------------*/
-nifti_dmat44 nifti_make_orthog_dmat44( double r11, double r12, double r13 ,
-                               double r21, double r22, double r23 ,
-                               double r31, double r32, double r33  )
-{
-   nifti_dmat44 R ;
-   nifti_dmat33 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_dmat33_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.0f ; return R ;
-}
-
-/*---------------------------------------------------------------------------*/
-/*! 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] *= (float)val ; Q.m[0][1] *= (float)val ; Q.m[0][2] *= (float)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] *= (float)val ; Q.m[1][1] *= (float)val ; Q.m[1][2] *= (float)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] *= (float)val ; Q.m[2][1] *= (float)val ; Q.m[2][2] *= (float)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.0f ; return R ;
-}
-
-/*----------------------------------------------------------------------*/
-/*! compute the inverse of a 3x3 matrix
-*//*--------------------------------------------------------------------*/
-nifti_dmat33 nifti_dmat33_inverse( nifti_dmat33 R ) /* inverse of 3x3 matrix */
-{
-   double r11,r12,r13,r21,r22,r23,r31,r32,r33 , deti ;
-   nifti_dmat33 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 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] = (float)( deti*( r22*r33-r32*r23) ) ;
-   Q.m[0][1] = (float)( deti*(-r12*r33+r32*r13) ) ;
-   Q.m[0][2] = (float)( deti*( r12*r23-r22*r13) ) ;
-
-   Q.m[1][0] = (float)( deti*(-r21*r33+r31*r23) ) ;
-   Q.m[1][1] = (float)( deti*( r11*r33-r31*r13) ) ;
-   Q.m[1][2] = (float)( deti*(-r11*r23+r21*r13) ) ;
-
-   Q.m[2][0] = (float)( deti*( r21*r32-r31*r22) ) ;
-   Q.m[2][1] = (float)( deti*(-r11*r32+r31*r12) ) ;
-   Q.m[2][2] = (float)( deti*( r11*r22-r21*r12) ) ;
-
-   return Q ;
-}
-
-/*----------------------------------------------------------------------*/
-/*! compute the determinant of a 3x3 matrix
-*//*--------------------------------------------------------------------*/
-double nifti_dmat33_determ( nifti_dmat33 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 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 (float)(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
-*//*--------------------------------------------------------------------*/
-double nifti_dmat33_rownorm( nifti_dmat33 A )  /* max row norm of 3x3 matrix */
-{
-   double 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 row norm of a 3x3 matrix
-*//*--------------------------------------------------------------------*/
-float nifti_mat33_rownorm( mat33 A )  /* max row norm of 3x3 matrix */
-{
-   float r1,r2,r3 ;
-
-   r1 = (float)( fabs(A.m[0][0])+fabs(A.m[0][1])+fabs(A.m[0][2]) ) ;
-   r2 = (float)( fabs(A.m[1][0])+fabs(A.m[1][1])+fabs(A.m[1][2]) ) ;
-   r3 = (float)( 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
-*//*--------------------------------------------------------------------*/
-double nifti_dmat33_colnorm( nifti_dmat33 A )/* max column norm of 3x3 matrix */
-{
-   double 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 ;
-}
-
-/*----------------------------------------------------------------------*/
-/*! 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 = (float)( fabs(A.m[0][0])+fabs(A.m[1][0])+fabs(A.m[2][0]) ) ;
-   r2 = (float)( fabs(A.m[0][1])+fabs(A.m[1][1])+fabs(A.m[2][1]) ) ;
-   r3 = (float)( 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
-*//*--------------------------------------------------------------------*/
-nifti_dmat33 nifti_dmat33_mul( nifti_dmat33 A , nifti_dmat33 B )
-/* multiply 2 3x3 matrices */
-{
-   nifti_dmat33 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 ;
-}
-
-/*----------------------------------------------------------------------*/
-/*! 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.
-*//*-------------------------------------------------------------------------*/
-nifti_dmat33 nifti_dmat33_polar( nifti_dmat33 A )
-{
-   nifti_dmat33 X , Y , Z ;
-   double alp,bet,gam,gmi , dif=1.0 ;
-   int k=0 ;
-
-   X = A ;
-
-   /* force matrix to be nonsingular */
-
-   gam = nifti_dmat33_determ(X) ;
-   while( gam == 0.0 ){        /* perturb matrix */
-     gam = 0.00001 * ( 0.001 + nifti_dmat33_rownorm(X) );
-     X.m[0][0] += gam ; X.m[1][1] += gam ; X.m[2][2] += gam ;
-     gam = nifti_dmat33_determ(X) ;
-   }
-
-   while(1){
-     Y = nifti_dmat33_inverse(X) ;
-     if( dif > 0.3 ){     /* far from convergence */
-       alp = sqrt( nifti_dmat33_rownorm(X) * nifti_dmat33_colnorm(X) );
-       bet = sqrt( nifti_dmat33_rownorm(Y) * nifti_dmat33_colnorm(Y) );
-       gam = sqrt( bet / alp );
-       gmi = 1.0 / gam;
-     } else {
-       gam = gmi = 1.0f ;  /* 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 ;
-}
-
-/*---------------------------------------------------------------------------*/
-/*! 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.0f ;
-   int k=0 ;
-
-   X = A ;
-
-   /* force matrix to be nonsingular */
-
-   gam = nifti_mat33_determ(X) ;
-   while( gam == 0.0 ){        /* perturb matrix */
-     gam = (float)( 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 = (float)( sqrt( nifti_mat33_rownorm(X) * nifti_mat33_colnorm(X) ) ) ;
-       bet = (float)( sqrt( nifti_mat33_rownorm(Y) * nifti_mat33_colnorm(Y) ) ) ;
-       gam = (float)( sqrt( bet / alp ) ) ;
-       gmi = (float)( 1.0 / gam ) ;
-     } else {
-       gam = gmi = 1.0f ;  /* close to convergence */
-     }
-     Z.m[0][0] = (float)( 0.5 * ( gam*X.m[0][0] + gmi*Y.m[0][0] ) ) ;
-     Z.m[0][1] = (float)( 0.5 * ( gam*X.m[0][1] + gmi*Y.m[1][0] ) ) ;
-     Z.m[0][2] = (float)( 0.5 * ( gam*X.m[0][2] + gmi*Y.m[2][0] ) ) ;
-     Z.m[1][0] = (float)( 0.5 * ( gam*X.m[1][0] + gmi*Y.m[0][1] ) ) ;
-     Z.m[1][1] = (float)( 0.5 * ( gam*X.m[1][1] + gmi*Y.m[1][1] ) ) ;
-     Z.m[1][2] = (float)( 0.5 * ( gam*X.m[1][2] + gmi*Y.m[2][1] ) ) ;
-     Z.m[2][0] = (float)( 0.5 * ( gam*X.m[2][0] + gmi*Y.m[0][2] ) ) ;
-     Z.m[2][1] = (float)( 0.5 * ( gam*X.m[2][1] + gmi*Y.m[1][2] ) ) ;
-     Z.m[2][2] = (float)( 0.5 * ( gam*X.m[2][2] + gmi*Y.m[2][2] ) ) ;
-
-     dif = (float)( 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_dmat44_to_orientation( nifti_dmat44 R ,
-                                  int *icod, int *jcod, int *kcod )
-{
-   double xi,xj,xk , yi,yj,yk , zi,zj,zk , val,detQ,detP ;
-   nifti_dmat33 P , Q , M ;
-   int i,j,k=0,p,q,r , ibest,jbest,kbest,pbest,qbest,rbest ;
-   double 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 (i,j,k) to (x,y,z) axes */
-
-   detQ = nifti_dmat33_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_dmat33_determ(P) ;          /* sign of permutation */
-           if( detP * detQ <= 0.0 ) continue ;  /* doesn't match sign of Q */
-           M = nifti_dmat33_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 ;
-}
-
-/*---------------------------------------------------------------------------*/
-/*! 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 = (float)sqrt( xi*xi + yi*yi + zi*zi ) ;
-   if( val == 0.0 ) return ;                 /* stupid input */
-   xi /= val ; yi /= val ; zi /= val ;
-
-   /* normalize j axis */
-
-   val = (float)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 = (float)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 = (float)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 = (float)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 = (float)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.0f ; 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.0f ;
-       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@onerussian.com>
- *
-*//*--------------------------------------------------------------------*/
-void nifti_swap_2bytes( int64_t n , void *ar )    /* 2 bytes at a time */
-{
-   register int64_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( int64_t n , void *ar )    /* 4 bytes at a time */
-{
-   register int64_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( int64_t n , void *ar )    /* 8 bytes at a time */
-{
-   register int64_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( int64_t n , void *ar )    /* 16 bytes at a time */
-{
-   register int64_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( int64_t n , int siz , void *ar )
-{
-   register int64_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( int64_t n , int siz , void *ar )  /* subsuming case */
-{
-   switch( siz ){
-     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 , siz, ar ) ; */
-        fprintf(stderr,"** NIfTI: cannot swap in %d byte blocks\n", siz);
-        break ;
-   }
-   return ;
-}
-
-
-/*-------------------------------------------------------------------------*/
-/*! Byte swap NIFTI file header, depending on the version.
-*//*---------------------------------------------------------------------- */
-void swap_nifti_header( void * hdr , int ni_ver )
-{
-   if     ( ni_ver == 0 ) nifti_swap_as_analyze((nifti_analyze75 *)hdr);
-   else if( ni_ver == 1 ) nifti_swap_as_nifti1((nifti_1_header *)hdr);
-   else if( ni_ver == 2 ) nifti_swap_as_nifti2((nifti_2_header *)hdr);
-   else if( ni_ver >= 0 && ni_ver <= 9 ) {
-      fprintf(stderr,"** swap_nifti_header: not ready for version %d\n",ni_ver);
-   } else {
-      fprintf(stderr,"** swap_nifti_header: illegal version %d\n", ni_ver);
-   }
-}
-
-
-/*-------------------------------------------------------------------------*/
-/*! Byte swap NIFTI-2 file header.
-*//*---------------------------------------------------------------------- */
-void nifti_swap_as_nifti2( nifti_2_header * h )
-{
-   if ( ! h ) {
-     fprintf(stderr,"** nifti_swap_as_nifti2: NULL pointer\n");
-     return;
-   }
-
-   nifti_swap_4bytes(1, &h->sizeof_hdr);
-
-   nifti_swap_2bytes(1, &h->datatype);
-   nifti_swap_2bytes(1, &h->bitpix);
-
-   nifti_swap_8bytes(8, h->dim);
-   nifti_swap_8bytes(1, &h->intent_p1);
-   nifti_swap_8bytes(1, &h->intent_p2);
-   nifti_swap_8bytes(1, &h->intent_p3);
-   nifti_swap_8bytes(8, h->pixdim);
-
-   nifti_swap_8bytes(1, &h->vox_offset);
-   nifti_swap_8bytes(1, &h->scl_slope);
-   nifti_swap_8bytes(1, &h->scl_inter);
-   nifti_swap_8bytes(1, &h->cal_max);
-   nifti_swap_8bytes(1, &h->cal_min);
-   nifti_swap_8bytes(1, &h->slice_duration);
-   nifti_swap_8bytes(1, &h->toffset);
-   nifti_swap_8bytes(1, &h->slice_start);
-   nifti_swap_8bytes(1, &h->slice_end);
-
-   nifti_swap_4bytes(1, &h->qform_code);
-   nifti_swap_4bytes(1, &h->sform_code);
-
-   nifti_swap_8bytes(1, &h->quatern_b);
-   nifti_swap_8bytes(1, &h->quatern_c);
-   nifti_swap_8bytes(1, &h->quatern_d);
-   nifti_swap_8bytes(1, &h->qoffset_x);
-   nifti_swap_8bytes(1, &h->qoffset_y);
-   nifti_swap_8bytes(1, &h->qoffset_z);
-
-   nifti_swap_8bytes(4, h->srow_x);
-   nifti_swap_8bytes(4, h->srow_y);
-   nifti_swap_8bytes(4, h->srow_z);
-
-   nifti_swap_4bytes(1, &h->slice_code);
-   nifti_swap_4bytes(1, &h->xyzt_units);
-   nifti_swap_4bytes(1, &h->intent_code);
-}
-
-/*-------------------------------------------------------------------------*/
-/*! Byte swap NIFTI-1 file header in various places and ways.
- *  return 0 on success
-*//*---------------------------------------------------------------------- */
-void nifti_swap_as_nifti1( nifti_1_header * h )
-{
-   if ( ! h ) {
-     fprintf(stderr,"** nifti_swap_as_nifti1: NULL pointer\n");
-     return;
-   }
-
-   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);
-}
-
-/*-------------------------------------------------------------------------*/
-/*! Byte swap as an ANALYZE 7.5 header
- *
- *  return non-zero on failure
-*//*---------------------------------------------------------------------- */
-void nifti_swap_as_analyze( nifti_analyze75 * h )
-{
-   if ( ! h ) {
-     fprintf(stderr,"** nifti_swap_as_analyze: NULL pointer\n");
-     return;
-   }
-
-   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);
-}
-
-/*-------------------------------------------------------------------------*/
-/*! 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( 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]
-*//*-------------------------------------------------------------------------*/
-int64_t 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 buf.st_size ;
-}
-
-#else  /*---------- non-Unix version of the above, less efficient -----------*/
-
-int64_t nifti_get_filesize( const char *pathname )
-{
-   znzFile fp ; int64_t 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.
-*//*--------------------------------------------------------------------*/
-int64_t nifti_get_volsize(const nifti_image *nim)
-{
-   return (int64_t)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)
-{
-   const char * ext;
-
-   /* check input file(s) for sanity */
-   if( fname == NULL || *fname == '\0' ){
-      if ( g_opts.debug > 1 )
-         fprintf(stderr,"-- 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 )
-         fprintf(stderr,"-- no nifti valid extension for filename '%s'\n", fname);
-       return 0;
-   }
-
-   if ( ext && ext == fname ) {   /* then no filename prefix */
-      if ( g_opts.debug > 0 )
-         fprintf(stderr,"-- 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)
-{
-   const char * ext;
-
-   /* check input file(s) for sanity */
-   if( fname == NULL || *fname == '\0' ){
-      if ( g_opts.debug > 1 )
-         fprintf(stderr,"-- 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 )
-         fprintf(stderr,"-- 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 substring within the original
-            function input parameter name, or NULL if not found.
-    \caution Note that if the input parameter is is immutabale
-             (i.e. a const char *) then this function performs an
-             implicit casting away of the mutability constraint and
-             the return parameter will appear as a mutable
-             even though it is part of the immuttable string.
-*//*--------------------------------------------------------------------*/
-char * nifti_find_file_extension( const char * name )
-{
-   const char * ext;
-   char 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 = 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) ) {
-         fprintf(stderr,"** mixed case extension '%s' is not valid\n", ext);
-         return NULL;
-      }
-      else return (char *)ext; /* Cast away the constness of the input parameter */
-   }
-
-#ifdef HAVE_ZLIB
-   if ( len < 7 ) return NULL;
-
-   ext = 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) ) {
-         fprintf(stderr,"** mixed case extension '%s' is not valid\n", ext);
-         return NULL;
-      }
-      else return (char *)ext; /* Cast away the constness of the input parameter */
-   }
-
-#endif
-
-   if( g_opts.debug > 1 )
-      fprintf(stderr,"** 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_ZLIB
-  { /* 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_ZLIB set
-*//*--------------------------------------------------------------------*/
-int nifti_compiled_with_zlib(void)
-{
-#ifdef HAVE_ZLIB
-    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;
-   const char *ext;
-
-   basename=nifti_strdup(fname);
-
-   ext = nifti_find_file_extension(basename);
-   if ( ext )
-   {
-     basename[strlen(basename)-strlen(ext)] = '\0';  /* clear out extension */
-   }
-
-   return basename;  /* in either case */
-}
-
-/*----------------------------------------------------------------------*/
-/* option accessor functions                                            */
-/*----------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------*/
-/*! 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;
-}
-
-/*----------------------------------------------------------------------*/
-/*! get nifti's global alter_cifti flag              22 Jul 2015 [rickr]
-*//*--------------------------------------------------------------------*/
-int nifti_get_alter_cifti( void )
-{
-    return g_opts.alter_cifti;
-}
-
-/*----------------------------------------------------------------------*/
-/*! set nifti's global alter_cifti flag              22 Jul 2015 [rickr]
-
-    explicitly set to 0 or 1
-*//*--------------------------------------------------------------------*/
-void nifti_set_alter_cifti( int alter_cifti )
-{
-    g_opts.alter_cifti = alter_cifti ? 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;
-   const char *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 ){
-      fprintf(stderr,"** 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_ZLIB
-   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_ZLIB
-   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";
-   const 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 ){
-      fprintf(stderr,"** 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_ZLIB  /* 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_ZLIB  /* 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;
-   const char * 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 ){ fprintf(stderr,"** 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(&(iname[strlen(iname)-strlen(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_ZLIB  /* 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) ){
-      fprintf(stderr,"** failure: header file '%s' already exists\n",iname);
-      free(iname);
-      return NULL;
-   }
-
-   if(g_opts.debug > 2) fprintf(stderr,"+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;
-   const char * 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 ){ fprintf(stderr,"** 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(&(iname[strlen(iname)-strlen(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_ZLIB  /* 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) ){
-      fprintf(stderr,"** failure: image file '%s' already exists\n",iname);
-      free(iname);
-      return NULL;
-   }
-
-   if( g_opts.debug > 2 ) fprintf(stderr,"+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 ){
-      fprintf(stderr,"** nifti_set_filenames, bad params %p, %p\n",
-              (void *)nim,prefix);
-      return -1;
-   }
-
-   if( g_opts.debug > 1 )
-      fprintf(stderr,"+d modifying output filenames using prefix %s\n", prefix);
-
-   /* set and test output filenames */
-   if( nim->fname ) free(nim->fname);
-   if( nim->iname ) free(nim->iname);
-   nim->iname = NULL;
-   nim->fname = nifti_makehdrname(prefix, nim->nifti_type, check, comp);
-   if( nim->fname )
-      nim->iname = nifti_makeimgname(prefix, nim->nifti_type, check, comp);
-   if( !nim->fname || !nim->iname ) return -1; /* failure */
-
-   if( set_byte_order ) nim->byteorder = nifti_short_order() ;
-
-   if( nifti_set_type_from_names(nim) < 0 )
-      return -1;
-
-   if( g_opts.debug > 2 )
-      fprintf(stderr,"+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";
-   const char * ext_h;  /* header  filename extension */
-   const char * ext_i;  /* image filename extension */
-   int  errs = 0;          /* error counter */
-
-   /* sanity checks */
-   if( !nim ){
-      if( show_warn ) fprintf(stderr,"** %s: missing nifti_image\n", func);
-      return -1;
-   }
-   if( !nim->fname ){
-      if( show_warn ) fprintf(stderr,"** %s: missing header filename\n", func);
-      errs++;
-   }
-   if( !nim->iname ){
-      if( show_warn ) fprintf(stderr,"** %s: missing image filename\n", func);
-      errs++;
-   }
-   if( !is_valid_nifti_type(nim->nifti_type) ){
-      if( show_warn )
-         fprintf(stderr,"** %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 )
-         fprintf(stderr,"-d missing NIFTI extension in header filename, %s\n",
-                 nim->fname);
-      errs++;
-   }
-   if( !ext_i ){
-      if( show_warn )
-         fprintf(stderr,"-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 )
-            fprintf(stderr,
-            "-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 )
-            fprintf(stderr,
-            "-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 )
-            fprintf(stderr,
-            "-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 )
-            fprintf(stderr,"-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 )
-            fprintf(stderr,"-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] = "";
-   size_t c,len;
-   /* if equal, don't need to check case (store to avoid multiple calls) */
-   const int 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((int) 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, size_t maxlen)
-{
-   char   caps[8] = "";
-   size_t c,len;
-   /* if equal, don't need to check case (store to avoid multiple calls) */
-   const int  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((int) 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)
-{
-   size_t c;
-   int    hasupper = 0;
-
-   if( !str || !*str ) return 0;
-
-   for(c = 0; c < strlen(str); c++ ) {
-     if( islower((int) str[c]) ) return 0;
-     if( !hasupper && isupper((int) str[c]) ) hasupper = 1;
-   }
-
-   return hasupper;
-}
-
-/* return 1 if there are both uppercase and lowercase characters */
-static int is_mixedcase(const char * str)
-{
-   size_t c;
-   int    hasupper = 0, haslower = 0;
-
-   if( !str || !*str ) return 0;
-
-   for(c = 0; c < strlen(str); c++ ) {
-     if( !haslower && islower((int) str[c]) ) haslower = 1;
-     if( !hasupper && isupper((int) str[c]) ) hasupper = 1;
-
-      if( haslower && hasupper ) return 1;
-   }
-
-   return 0;
-}
-
-/* convert any lowercase chars to uppercase */
-static int make_uppercase(char * str)
-{
-   size_t c;
-
-   if( !str || !*str ) return 0;
-
-   for(c = 0; c < strlen(str); c++ )
-     if( islower((int) str[c]) ) str[c] = toupper((int) str[c]);
-
-   return 0;
-}
-
-/* convert any uppercase chars to lowercase */
-static int make_lowercase(char * str)
-{
-   size_t c;
-   if( !str || !*str ) return 0;
-
-   for(c = 0; c < strlen(str); c++ )
-     if( isupper((int) str[c]) ) str[c] = tolower((int) 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 ){ fprintf(stderr,"** NSTFN: no nifti_image\n");  return -1; }
-
-   if( !nim->fname || !nim->iname ){
-      fprintf(stderr,"** 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 )
-     ) {
-      fprintf(stderr,"** NSTFN: invalid filename(s) fname='%s', iname='%s'\n",
-              nim->fname, nim->iname);
-      return -1;
-   }
-
-   if( g_opts.debug > 2 )
-      fprintf(stderr,"-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 ) fprintf(stderr," -> %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! */
-
-   fprintf(stderr,"** 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 )
-{
-   nifti_1_header nhdr ;
-   znzFile fp ;
-   int ii ;
-   char *tmpname;
-
-/* rcr - update to check for nifti-1 or -2 */
-
-   /* bad input name? */
-
-   if( !nifti_validfilename(hname) ) return -1 ;
-
-   /* open file */
-
-   tmpname = nifti_findhdrname(hname);
-   if( tmpname == NULL ){
-      if( g_opts.debug > 0 )
-         fprintf(stderr,"** 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, FILE * fp )
-{
-   int c;
-
-   if ( !data || nbytes < 1 || !fp ) return -1;
-
-   fputs("0x", fp);
-   for ( c = 0; c < nbytes; c++ )
-      fprintf(fp, " %02x", 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;
-
-   fputs( "-------------------------------------------------------\n", stdout );
-   if ( info )  fputs( info, stdout );
-   if ( !hp  ){ fputs(" ** no nifti_1_header to display!\n",stdout); return 1; }
-
-   fprintf(stdout," nifti_1_header :\n"
-           "    sizeof_hdr     = %d\n"
-           "    data_type[10]  = ", hp->sizeof_hdr);
-   print_hex_vals(hp->data_type, 10, stdout);
-   fprintf(stdout, "\n"
-           "    db_name[18]    = ");
-   print_hex_vals(hp->db_name, 18, stdout);
-   fprintf(stdout, "\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 );
-   fprintf(stdout, "    dim[8]         =");
-   for ( c = 0; c < 8; c++ ) fprintf(stdout," %d", hp->dim[c]);
-   fprintf(stdout, "\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++ ) fprintf(stdout," %f", hp->pixdim[c]);
-   fprintf(stdout, "\n                    ");
-   for ( c = 4; c < 8; c++ ) fprintf(stdout," %f", hp->pixdim[c]);
-   fprintf(stdout, "\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);
-   fprintf(stdout,
-           "    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);
-   fputs( "-------------------------------------------------------\n", stdout );
-   fflush(stdout);
-
-   return 0;
-}
-
-
-/*----------------------------------------------------------------------*/
-/*! display the contents of the nifti_2_header (send to stdout)
-
-   \param info if non-NULL, print this character string
-   \param hp   pointer to nifti_2_header
-*//*--------------------------------------------------------------------*/
-int disp_nifti_2_header( const char * info, const nifti_2_header * hp )
-{
-   FILE * fp = stdout;
-   int    c;
-
-   fputs( "-------------------------------------------------------\n", fp );
-   if ( info )  fputs( info, fp );
-   if ( !hp  ){ fputs(" ** no nifti_2_header to display!\n",fp); return 1; }
-
-   /* print fields one by one, makes changing order and copying easier */
-
-   fprintf(fp," nifti_2_header :\n");
-   fprintf(fp,"    sizeof_hdr     = %d\n", hp->sizeof_hdr);
-   fprintf(fp,"    magic[8]       = '%-.4s' + ", hp->magic);
-   print_hex_vals(hp->magic+4, 4, fp); fputc('\n', fp);
-
-   fprintf(fp,"    datatype       = %d (%s)\n",
-           hp->datatype, nifti_datatype_to_string(hp->datatype));
-   fprintf(fp,"    bitpix         = %d\n", hp->bitpix);
-   fprintf(fp, "    dim[8]         =");
-   for ( c = 0; c < 8; c++ ) fprintf(fp," %lld", hp->dim[c]);
-   fputc('\n', fp);
-
-   fprintf(fp, "    intent_p1      = %lf\n", hp->intent_p1);
-   fprintf(fp, "    intent_p2      = %lf\n", hp->intent_p2);
-   fprintf(fp, "    intent_p3      = %lf\n", hp->intent_p3);
-   fprintf(fp, "    pixdim[8]      =");
-   for ( c = 0; c < 8; c++ ) fprintf(fp," %lf", hp->pixdim[c]);
-   fputc('\n', fp);
-
-   fprintf(fp, "    vox_offset     = %lld\n", hp->vox_offset);
-
-   fprintf(fp, "    scl_slope      = %lf\n", hp->scl_slope);
-   fprintf(fp, "    scl_inter      = %lf\n", hp->scl_inter);
-   fprintf(fp, "    cal_max        = %lf\n", hp->cal_max);
-   fprintf(fp, "    cal_min        = %lf\n", hp->cal_min);
-   fprintf(fp, "    slice_duration = %lf\n", hp->slice_duration);
-   fprintf(fp, "    toffset        = %lf\n", hp->toffset);
-
-   fprintf(fp, "    slice_start    = %lld\n", hp->slice_start);
-   fprintf(fp, "    slice_end      = %lld\n", hp->slice_end);
-
-   fprintf(fp, "    descrip        = '%.80s'\n", hp->descrip);
-   fprintf(fp, "    aux_file       = '%.24s'\n", hp->aux_file);
-
-   fprintf(fp, "    qform_code     = %d\n", hp->qform_code);
-   fprintf(fp, "    sform_code     = %d\n", hp->sform_code);
-
-   fprintf(fp, "    quatern_b      = %lf\n", hp->quatern_b);
-   fprintf(fp, "    quatern_c      = %lf\n", hp->quatern_c);
-   fprintf(fp, "    quatern_d      = %lf\n", hp->quatern_d);
-   fprintf(fp, "    qoffset_x      = %lf\n", hp->qoffset_x);
-   fprintf(fp, "    qoffset_y      = %lf\n", hp->qoffset_y);
-   fprintf(fp, "    qoffset_z      = %lf\n", hp->qoffset_z);
-   fprintf(fp, "    srow_x[4]      = %lf, %lf, %lf, %lf\n",
-           hp->srow_x[0], hp->srow_x[1], hp->srow_x[2], hp->srow_x[3]);
-   fprintf(fp, "    srow_y[4]      = %lf, %lf, %lf, %lf\n",
-           hp->srow_y[0], hp->srow_y[1], hp->srow_y[2], hp->srow_y[3]);
-   fprintf(fp, "    srow_z[4]      = %lf, %lf, %lf, %lf\n",
-           hp->srow_z[0], hp->srow_z[1], hp->srow_z[2], hp->srow_z[3]);
-
-   fprintf(fp, "    slice_code     = %d\n", hp->slice_code);
-   fprintf(fp, "    xyzt_units     = %d\n", hp->xyzt_units);
-   fprintf(fp, "    intent_code    = %d\n", hp->intent_code);
-
-   fprintf(fp, "    intent_name    = '%-.16s'\n", hp->intent_name);
-   fprintf(fp, "    dim_info       = 0x%02x\n",(unsigned char)hp->dim_info);
-   fprintf(fp, "    unused_str     = 0x ");
-   for ( c = 0; c < 15; c++ ) fprintf(fp," %02x", hp->unused_str[c]);
-   fputc('\n', fp);
-
-   fputs( "-------------------------------------------------------\n", fp );
-   fflush(fp);
-
-   return 0;
-}
-
-
-#undef  ERREX
-#define ERREX(msg)                                                        \
- do{ fprintf(stderr,"** ERROR: nifti_convert_n1hdr2nim: %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_n1hdr2nim(nifti_1_header nhdr, const char * fname)
-{
-   int   ii , doswap , ioff ;
-   int   ni_ver , 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 ){
-      free(nim);
-      if( doswap == -1 ) ERREX("bad dim[0]") ;
-      ERREX("bad sizeof_hdr") ;  /* else */
-   }
-
-   /**- determine if this is a NIFTI-1 compliant header */
-
-   ni_ver = NIFTI_VERSION(nhdr) ;
-   /*
-    * before swapping header, record the Analyze75 orient code
-    */
-   if(ni_ver == 0)
-     {
-     /**- 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 , ni_ver ) ;
-   }
-
-   if ( g_opts.debug > 2 ) disp_nifti_1_header("-d nhdr2nim : ", &nhdr);
-
-   if( nhdr.datatype == DT_BINARY || nhdr.datatype == DT_UNKNOWN  )
-   {
-     free(nim);
-     ERREX("bad datatype") ;
-   }
-
-   if( nhdr.dim[1] <= 0 )
-   {
-     free(nim);
-     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.0f ;
-   }
-
-  is_onefile = (ni_ver > 0) && NIFTI_ONEFILE(nhdr) ;
-
-  if( ni_ver ) 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( !ni_ver || 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.0f;
-    nim->qto_xyz.m[1][0]=nim->qto_xyz.m[1][2]=nim->qto_xyz.m[1][3] = 0.0f;
-    nim->qto_xyz.m[2][0]=nim->qto_xyz.m[2][1]=nim->qto_xyz.m[2][3] = 0.0f;
-
-    /* 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.0f;
-    nim->qto_xyz.m[3][3]= 1.0f ;
-
-    nim->qform_code = NIFTI_XFORM_UNKNOWN ;
-
-    if( g_opts.debug > 1 ) fprintf(stderr,"-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.0f : 1.0f ;  /* left-handedness? */
-
-    nim->qto_xyz = nifti_quatern_to_dmat44(
-                      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_dmat44_inverse( nim->qto_xyz ) ;
-
-  /**- load sto_xyz affine transformation, if present */
-
-  if( !ni_ver || 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 ) fprintf(stderr,"-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.0f;
-    nim->sto_xyz.m[3][3]= 1.0f ;
-
-    nim->sto_ijk = nifti_dmat44_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( ni_ver ){
-    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 = ni_ver && 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{ fprintf(stderr,"** ERROR: nifti_convert_n2hdr2nim: %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_n2hdr2nim(nifti_2_header nhdr, const char * fname)
-{
-   int          ii, doswap, ni_ver, 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 = NIFTI2_NEEDS_SWAP(nhdr); /* swap data flag */
-
-   /**- determine if this is a NIFTI-2 compliant header */
-
-   ni_ver = NIFTI_VERSION(nhdr) ;
-   if(ni_ver != 2) {
-      free(nim);
-      fprintf(stderr,"** convert NIFTI-2 hdr2nim: bad version %d\n", ni_ver);
-      return NULL;
-   }
-
-   if( doswap ) {
-      if ( g_opts.debug > 3 ) disp_nifti_2_header("-d n2 pre-swap: ", &nhdr);
-      swap_nifti_header( &nhdr , ni_ver ) ;
-   } else if ( g_opts.debug > 3 ) fprintf(stderr,"-- n2hdr2nim: no swap\n");
-
-   if ( g_opts.debug > 2 ) disp_nifti_2_header("-d n2hdr2nim : ", &nhdr);
-
-   if( nhdr.datatype == DT_BINARY || nhdr.datatype == DT_UNKNOWN  )
-   {
-     free(nim);
-     ERREX("bad datatype") ;
-   }
-
-   if( nhdr.dim[1] <= 0 )
-   {
-     free(nim);
-     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 ;
-
-   /**- 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 = (ni_ver > 0) && NIFTI_ONEFILE(nhdr) ;
-
-   nim->nifti_type = (is_onefile) ? NIFTI_FTYPE_NIFTI1_1 : NIFTI_FTYPE_NIFTI1_2;
-
-   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( !ni_ver || 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.0f;
-    nim->qto_xyz.m[1][0]=nim->qto_xyz.m[1][2]=nim->qto_xyz.m[1][3] = 0.0f;
-    nim->qto_xyz.m[2][0]=nim->qto_xyz.m[2][1]=nim->qto_xyz.m[2][3] = 0.0f;
-
-    /* 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.0f;
-    nim->qto_xyz.m[3][3]= 1.0f ;
-
-    nim->qform_code = NIFTI_XFORM_UNKNOWN ;
-
-    if( g_opts.debug > 1 ) fprintf(stderr,"-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_dmat44(
-                      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_dmat44_inverse( nim->qto_xyz ) ;
-
-  /**- load sto_xyz affine transformation, if present */
-
-  if( !ni_ver || 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 ) fprintf(stderr,"-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.0f;
-    nim->sto_xyz.m[3][3]= 1.0f ;
-
-    nim->sto_ijk = nifti_dmat44_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( ni_ver ){
-    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)) */
-
-   nim->iname_offset = nhdr.vox_offset;
-   if( is_onefile && nhdr.vox_offset < (int64_t)sizeof(nhdr) )
-      nim->iname_offset = (int64_t)sizeof(nhdr);
-
-   /**- 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{ fprintf(stderr,"** 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_n1_hdr(const char * hname, int *swapped, int check)
-{
-   nifti_1_header   nhdr, * hptr;
-   znzFile          fp;
-   int              bytes, lswap;
-   char           * hfile;
-   char             fname[] = { "nifti_read_n1_hdr" };
-
-   /* 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 )
-      fprintf(stderr,"-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);
-         fprintf(stderr,"  - 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) fprintf(stderr,"-- 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_hdr1_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 ){
-      fprintf(stderr,"** 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;
-}
-
-
-/*----------------------------------------------------------------------*/
-/*! return an allocated and filled nifti_2_header struct
-
-    Read the binary header from disk, and swap bytes if necessary.
-
-    \return an allocated nifti_2_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_2_header
-
-    \warning ASCII header type is not supported
-
-    \sa nifti_read_header, nifti_read_n1_hdr,
-        nifti_image_read, nifti_image_read_bricks
-*//*--------------------------------------------------------------------*/
-nifti_2_header * nifti_read_n2_hdr(const char * hname, int * swapped,
-                                    int check)
-{
-   nifti_2_header   nhdr, * hptr;
-   znzFile          fp;
-   int              bytes, lswap;
-   char           * hfile;
-   char             fname[] = { "nifti_read_n2_hdr" };
-
-   /* 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 )
-      fprintf(stderr,"-d %s: found N2 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 N2 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 for NIFTI-2",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 N2 file", hname);
-         fprintf(stderr,"  - read %d of %d bytes\n",bytes, (int)sizeof(nhdr));
-      }
-      return NULL;
-   }
-
-   /* now just decide on byte swapping */
-   lswap = NIFTI2_NEEDS_SWAP(nhdr);
-   if( lswap ) {
-      if ( g_opts.debug > 3 ) disp_nifti_2_header("-d n2hdr pre-swap: ", &nhdr);
-      swap_nifti_header( &nhdr , 2 );  /* use explicit version */
-   }
-
-   if ( g_opts.debug > 2 ) disp_nifti_2_header("-d nhdr post-swap: ", &nhdr);
-
-   if ( check && ! nifti_hdr2_looks_good(&nhdr) ){
-      LNI_FERR(fname,"nifti_2_header looks bad for file", hname);
-      return NULL;
-   }
-
-   /* all looks good, so allocate memory for and return the header */
-   hptr = (nifti_2_header *)malloc(sizeof(nifti_2_header));
-   if( ! hptr ){
-      fprintf(stderr,"** nifti2_read_hdr: failed to alloc nifti_2_header\n");
-      return NULL;
-   }
-
-   if( swapped ) *swapped = lswap;  /* only if they care <sniff!> */
-
-   memcpy(hptr, &nhdr, sizeof(nifti_2_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_hdr1_looks_good(const nifti_1_header * hdr)
-{
-   int ni_ver, 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 )
-         fprintf(stderr,"** 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 )
-            fprintf(stderr,"** bad nhdr field: dim[%d] = %d\n",c,hdr->dim[c]);
-         errs++;
-      }
-
-   ni_ver = NIFTI_VERSION(*hdr);      /* determine header type */
-
-   if( ni_ver > 0 ){      /* NIFTI */
-
-      if( ! nifti_datatype_is_valid(hdr->datatype, 1) ){
-         if( g_opts.debug > 0 )
-            fprintf(stderr,"** 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 */
-         fprintf(stderr,
-            "-- nhdr magic field implies ANALYZE: magic = '%.4s'\n",hdr->magic);
-
-      if( ! nifti_datatype_is_valid(hdr->datatype, 0) ){
-         if( g_opts.debug > 0 )
-           fprintf(stderr,"** bad ANALYZE datatype in hdr, %d\n",hdr->datatype);
-         errs++;
-      }
-   }
-
-   if( errs ) return 0;  /* problems */
-
-   if( g_opts.debug > 2 ) fprintf(stderr,"-d nifti header looks good\n");
-
-   return 1;   /* looks good */
-}
-
-
-/*----------------------------------------------------------------------*/
-/*! check that sizeof() returns the proper size
- *
- *  if ni_ver is valid (1 or 2 right now), check those sizes
- *  if ni_ver == 0, check all known sizes
- *  else whine and fail
-*//*--------------------------------------------------------------------*/
-int nifti_valid_header_size(int ni_ver, int whine)
-{
-   int size, errs=0, checks=0;
-
-   if ( !ni_ver || (ni_ver == 1) ) {
-      size = 348;
-      checks++;
-      if( sizeof(nifti_1_header) != size ) {
-         if( whine )
-            fprintf(stderr,
-               "** warning: sizeof(nifti_1_header) = %d, expected %d\n",
-               (int)sizeof(nifti_1_header), size);
-         errs++;
-      }
-   }
-
-   if ( !ni_ver || (ni_ver == 2) ) {
-      size = 540;
-      checks++;
-      if( sizeof(nifti_2_header) != size ) {
-         if( whine )
-            fprintf(stderr,
-               "** warning: sizeof(nifti_2_header) = %d, expected %d\n",
-               (int)sizeof(nifti_2_header), size);
-         errs++;
-      }
-   }
-
-   if ( ! checks ) {
-      fprintf(stderr,"** nifti_valid_header_size: bad ni_ver = %d\n",ni_ver);
-      return 0;
-   }
-
-   return errs ? 0 : 1;  /* though !errs seems more fun */
-}
-
-
-/*----------------------------------------------------------------------*/
-/*! decide if this nifti_2_header structure looks reasonable
- * swapping should have already happened
-
-   Check sizeof() and sizeof_hdr.
-   Check dim[0], dim[i], and datatype.
-   Check magic string for "n+2".
-
-   \return 1 if the header seems valid, 0 otherwise
-
-   \sa nifti_nim_is_valid, valid_nifti_extensions
-*//*--------------------------------------------------------------------*/
-int nifti_hdr2_looks_good(const nifti_2_header * hdr)
-{
-   int     ni_ver, c, errs = 0;
-   int64_t d0;
-
-   if( !hdr ) { fprintf(stderr,"** n2hdr: hdr is NULL\n"); return 0; }
-
-   /* for now, just warn if the header sizes are not right */
-   if( g_opts.debug > 0 ) (void)nifti_valid_header_size(0, 1);
-
-   if( hdr->sizeof_hdr != sizeof(nifti_2_header) ) {
-      if( g_opts.debug > 0 )
-         fprintf(stderr,"** bad n2hdr: sizeof_hdr = %d\n", hdr->sizeof_hdr);
-      errs++;
-   }
-
-   /* check the valid dimension sizes (maybe dim[0] is bad) */
-   d0 = hdr->dim[0];
-   if( d0 < 0 || d0 > 7 ) {
-      if( g_opts.debug > 0 ) fprintf(stderr,"** bad n2hdr: dim0 = %lld\n", d0);
-      errs++;
-   } else { /* only check dims if d0 is okay */
-      for( c = 1; c <= d0; c++ )
-         if( hdr->dim[c] <= 0 ){
-           if( g_opts.debug > 0 )
-             fprintf(stderr,"** bad nhdr field: dim[%d] = %lld\n",c,hdr->dim[c]);
-           errs++;
-         }
-   }
-
-   ni_ver = NIFTI_VERSION(*hdr);  /* note version */
-
-   if( ! nifti_datatype_is_valid(hdr->datatype, ni_ver) ){
-      if( g_opts.debug > 0 )
-         fprintf(stderr,"** bad %s NIFTI datatype in hdr, %d\n",
-                 ni_ver ? "NIFTI" : "ANALYZE", hdr->datatype);
-      errs++;
-   }
-
-   /* NIFTI_VERSION must return 2, or else sizes will not match */
-   if( ni_ver != 2 || memcmp((hdr->magic+4), nifti2_magic+4, 4) ) {
-      if( g_opts.debug > 0 ) {
-         fprintf(stderr, "-- header magic not NIFTI-2, magic = '%.4s' + ",
-                         hdr->magic);
-         print_hex_vals(hdr->magic+4, 4, stderr); fputc('\n', stderr);
-      }
-      errs++;
-   }
-
-   if( errs ) return 0;  /* problems */
-
-   if( g_opts.debug > 2 ) fprintf(stderr,"-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 ){
-         fprintf(stderr,"** NIFTI: bad swapped d0 = %d, unswapped = ", d0);
-         nifti_swap_2bytes(1, &d0);        /* swap? */
-         fprintf(stderr,"%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 ){
-      fprintf(stderr,"** NIFTI: bad swapped hsize = %d, unswapped = ", hsize);
-      nifti_swap_4bytes(1, &hsize);        /* swap? */
-      fprintf(stderr,"%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_read_header
- ***************************************************************/
-/*! \brief Read and return a nifti header, along with the found type
-
-        - 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 nver : 
-    \return A void pointer, which should be cast based on the returned nver.
-            It points to an allocated header struct.
-*/
-void * nifti_read_header( const char *hname, int *nver, int check )
-{
-   nifti_1_header  n1hdr;
-   nifti_2_header  n2hdr;
-   znzFile         fp;
-   void          * hresult = NULL;
-   int64_t         remain, h1size=0, h2size=0;
-   char            fname[] = { "nifti_read_header" };
-   char           *hfile=NULL, *posn;
-   int             ii, ni_ver;
-
-   if( g_opts.debug > 2 ){
-      fprintf(stderr,"-d reading header from '%s'",hname);
-      fprintf(stderr,", HAVE_ZLIB = %d\n", nifti_compiled_with_zlib());
-   }
-
-   /**- 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 > 2 )
-      fprintf(stderr,"-d %s: found header filename '%s'\n",fname,hfile);
-
-   h1size = sizeof(nifti_1_header);
-   h2size = sizeof(nifti_2_header);
-
-   /**- open file, separate reading of header, extensions and data */
-   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;
-   }
-
-   /**- next read into nifti_1_header and determine nifti type */
-   ii = (int)znzread(&n1hdr, 1, h1size, fp);
-
-   if( ii < (int)h1size ){      /* failure? */
-      if( g_opts.debug > 0 ){
-         LNI_FERR(fname,"bad binary header read for file", hfile);
-         fprintf(stderr,"  - read %d of %d bytes\n",ii, (int)h1size);
-      }
-      znzclose(fp) ;
-      free(hfile);
-      return NULL;
-   }
-
-   /* find out what type of header we have */
-   ni_ver = nifti_header_version((char *)&n1hdr, h1size);
-   if( g_opts.debug > 2 )
-      fprintf(stderr,"-- %s: NIFTI version = %d", fname, ni_ver);
-
-   /* maybe set return NIFTI version */
-   if( nver ) *nver = ni_ver;
-
-   /* if NIFTI-2, copy and finish reading header */
-   if ( ni_ver == 2 ) {
-      if( g_opts.debug > 2 )
-         fprintf(stderr,"-- %s: copying and filling NIFTI-2 header...", fname);
-      memcpy(&n2hdr, &n1hdr, h1size);   /* copy first part */
-      remain = h2size - h1size;
-      posn = (char *)&n2hdr + h1size;
-      ii = (int)znzread(posn, 1, remain, fp); /* read remaining part */
-      if( ii < (int)remain) {
-         LNI_FERR(fname,"short NIFTI-2 header read for file", hfile);
-         znzclose(fp);  free(hfile);  return NULL;
-      }
-   }
-
-   /* clean up */
-   znzclose(fp);
-   free(hfile);
-
-   /* allocate header space and return */
-   if( ni_ver == 0 || ni_ver == 1 ) {
-      hresult = malloc(h1size);
-      if( ! hresult ) {
-         LNI_FERR(fname,"failed to alloc NIFTI-1 header for file", hname);
-         return NULL;
-      }
-      memcpy(hresult, (void *)&n1hdr, h1size);
-
-      if ( check && ! nifti_hdr1_looks_good(hresult) ){
-         LNI_FERR(fname,"nifti_1_header looks bad for file", hname);
-         return hresult;
-      }
-   } else if ( ni_ver == 2 ) {
-      hresult = malloc(h2size);
-      if( ! hresult ) {
-         LNI_FERR(fname,"failed to alloc NIFTI-2 header for file", hname);
-         return NULL;
-      }
-      memcpy(hresult, &n2hdr, h2size);
-
-      if ( check && ! nifti_hdr2_looks_good(hresult) ){
-         LNI_FERR(fname,"nifti_2_header looks bad for file", hname);
-         return hresult;
-      }
-   } else {
-      if( g_opts.debug > 0 )
-         fprintf(stderr, "** %s: bad nifti header version %d\n", hname, ni_ver);
-
-      /* return a nifti-1 header anyway */
-      hresult = malloc(h1size);
-      if( ! hresult ) {
-         LNI_FERR(fname,"failed to alloc NIFTI-?? header for file", hname);
-         return NULL;
-      }
-      memcpy(hresult, (void *)&n1hdr, h1size);
-   }
-
-   if( g_opts.debug > 1 )
-      fprintf(stderr,"-- returning NIFTI-%d header in %s\n", ni_ver, hname);
-
-   return hresult;
-}
-
-
-/***************************************************************
- * 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 )
-{
-   nifti_1_header  n1hdr;
-   nifti_2_header  n2hdr;
-   nifti_image    *nim;
-   znzFile         fp;
-   int             rv, ii, ni_ver, onefile=0;
-   int64_t         filesize, remain, h1size=0, h2size=0;
-   char            fname[] = { "nifti_image_read" };
-   char           *hfile=NULL, *posn;
-
-   if( g_opts.debug > 1 ){
-      fprintf(stderr,"-d image_read from '%s', read_data = %d",hname,read_data);
-      fprintf(stderr,", HAVE_ZLIB = %d\n", nifti_compiled_with_zlib());
-   }
-
-   /**- 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 )
-      fprintf(stderr,"-d %s: found header filename '%s'\n",fname,hfile);
-
-   if( nifti_is_gzfile(hfile) ) filesize = -1;  /* unknown */
-   else                         filesize = nifti_get_filesize(hfile);
-
-   /**- open file, separate reading of header, extensions and data */
-   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;
-   }
-
-   /**- first try to read dataset as ASCII (and return if so) */
-   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 );
-
-   h1size = sizeof(nifti_1_header);
-   h2size = sizeof(nifti_2_header);
-
-   /**- next read into nifti_1_header and determine nifti type */
-   ii = (int)znzread(&n1hdr, 1, h1size, fp);
-
-   if( ii < (int)h1size ){      /* failure? */
-      if( g_opts.debug > 0 ){
-         LNI_FERR(fname,"bad binary header read for file", hfile);
-         fprintf(stderr,"  - read %d of %d bytes\n",ii, (int)h1size);
-      }
-      znzclose(fp) ;
-      free(hfile);
-      return NULL;
-   }
-
-   /* find out what type of header we have */
-   ni_ver = nifti_header_version((char *)&n1hdr, h1size);
-   if( g_opts.debug > 2 )
-      fprintf(stderr,"-- %s: NIFTI version = %d", fname, ni_ver);
-
-   if( ni_ver == 0 || ni_ver == 1 ) {
-      nim = nifti_convert_n1hdr2nim(n1hdr,hfile);
-      onefile = NIFTI_ONEFILE(n1hdr);
-   } else if ( ni_ver == 2 ) {
-      /* fill nifti-2 header and convert */
-      if( g_opts.debug > 2 )
-         fprintf(stderr,"-- %s: copying and filling NIFTI-2 header...", fname);
-      memcpy(&n2hdr, &n1hdr, h1size);   /* copy first part */
-      remain = h2size - h1size;
-      posn = (char *)&n2hdr + h1size;
-      ii = (int)znzread(posn, 1, remain, fp); /* read remaining part */
-      if( ii < (int)remain) {
-         LNI_FERR(fname,"short NIFTI-2 header read for file", hfile);
-         znzclose(fp);  free(hfile);  return NULL;
-      }
-      nim = nifti_convert_n2hdr2nim(n2hdr,hfile);
-      onefile = NIFTI_ONEFILE(n2hdr);
-   } else {
-      if( g_opts.debug > 0 )
-         fprintf(stderr,"** %s: bad nifti im header version %d\n",fname,ni_ver);
-      znzclose(fp);  free(hfile);  return NULL;
-   }
-
-   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 ){
-      fprintf(stderr,"+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 ( onefile )     remain = nim->iname_offset;
-   else               remain = filesize;
-
-   if ( ni_ver <= 1 ) remain -= h1size;
-   else               remain -= h2size;
-
-   (void)nifti_read_extensions(nim, fp, remain);
-
-   znzclose( fp ) ;                                      /* close the file */
-   free(hfile);
-
-   if ( g_opts.alter_cifti && nifti_looks_like_cifti(nim) )
-      nifti_alter_cifti_dims(nim);
-
-   /**- read the data if desired, then bug out */
-   if( read_data ){
-      if( nifti_image_load( nim ) < 0 ){
-         nifti_image_free(nim);          /* take ball, go home. */
-         return NULL;
-      }
-   }
-   else nim->data = NULL ;
-
-   return nim ;
-}
-
-
-/*----------------------------------------------------------------------
- # return the index of the first occurrence of the given ecode, else -1
- *----------------------------------------------------------------------*/
-static int nifti_ext_type_index(nifti_image * nim, int ecode)
-{
-   int ind;
-
-   if ( !nim || ecode < 0 ) return -1;
-
-   for( ind = 0; ind < nim->num_ext; ind++ )
-      if( nim->ext_list[ind].ecode == ecode )
-         return ind;
-
-   return -1;
-}
-
-/*----------------------------------------------------------------------
- *! does this dataset look like CIFTI?
- *
- * check dimensions and extension ecodes for CIFTI
- *
- * should have  - nx=ny=nz=nt=1, nu,nv>1, nw optional
- *              - CIFTI extension
- *----------------------------------------------------------------------*/
-int nifti_looks_like_cifti(nifti_image * nim)
-{
-   if( ! nim ) return 0;
-
-   if( nifti_ext_type_index(nim, NIFTI_ECODE_CIFTI) < 0 ) return 0;
-
-   if( nim->nx > 1 || nim->ny > 1 || nim->nz > 1 || nim->nt > 1 ) return 0;
-
-   if( nim->nu > 1 || nim->nv > 1 ) return 1;  /* looks like it */
-
-   return 0;
-}
-
-/*----------------------------------------------------------------------
- *! alter the dims[] from CIFTI style
- *
- * convert nu -> nx, nv -> nt/nu, nw -> nv
- *----------------------------------------------------------------------*/
-int nifti_alter_cifti_dims(nifti_image * nim)
-{
-   if( ! nifti_looks_like_cifti(nim) ) return 0;
-
-   /* the main effect, move position axis to x ... */
-   if( nim->nu > 1 || nim->dim[5] ) {
-      nim->nx = nim->nu;
-      nim->nu = 1;
-
-      nim->dim[1] = nim->dim[5];
-      nim->dim[5] = 1;
-   }
-
-   return 0;
-}
-
-
-/*----------------------------------------------------------------------
- * 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 )
-      fprintf(stderr,"-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 ){
-      fprintf(stderr,"** %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, (int64_t)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 )
-         fprintf(stderr,"-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, int64_t remain )
-{
-   nifti1_extender    extdr;      /* defines extension existence  */
-   nifti1_extension   extn;       /* single extension to process  */
-   nifti1_extension * Elist;      /* list of processed extensions */
-   int64_t            posn, count;
-
-   /* rcr n2 - add and use nifti2_extension type? */
-
-   if( !nim || znz_isnull(fp) ) {
-      if( g_opts.debug > 0 )
-         fprintf(stderr,"** nifti_read_extensions: bad inputs (%p,%p)\n",
-                 (void *)nim, (void *)fp);
-      return -1;
-   }
-
-   posn = znztell(fp);
-
-   if( g_opts.debug > 2 )
-      fprintf(stderr,"-d nre: posn=%lld, offset=%lld, type=%d, remain=%lld\n",
-              posn, nim->iname_offset, nim->nifti_type, remain);
-
-   if( remain < 16 ){
-      if( g_opts.debug > 2 ){
-         if( g_opts.skip_blank_ext )
-            fprintf(stderr,"-d no extender in '%s' is okay, as "
-                           "skip_blank_ext is set\n",nim->fname);
-         else
-            fprintf(stderr,"-d remain=%lld, no space for extensions\n",remain);
-      }
-      return 0;
-   }
-
-   count = znzread( extdr.extension, 1, 4, fp ); /* get extender */
-
-   if( count < 4 ){
-      if( g_opts.debug > 1 )
-         fprintf(stderr,"-d file '%s' is too short for an extender\n",
-                 nim->fname);
-      return 0;
-   }
-
-   if( extdr.extension[0] != 1 ){
-      if( g_opts.debug > 2 )
-         fprintf(stderr,"-d extender[0] (%d) shows no extensions for '%s'\n",
-                 extdr.extension[0], nim->fname);
-      return 0;
-   }
-
-   remain -= 4;
-   if( g_opts.debug > 2 )
-      fprintf(stderr,"-d found valid 4-byte extender, remain = %lld\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, (int)count+1) < 0 ){
-         if( g_opts.debug > 0 )
-            fprintf(stderr,"** failed adding ext %lld to list\n", count);
-         return -1;
-      }
-
-      /* we have a new extension */
-      if( g_opts.debug > 1 ){
-         fprintf(stderr,"+d found extension #%lld, code = 0x%x, size = %d\n",
-                 count, extn.ecode, extn.esize);
-         if( extn.ecode == NIFTI_ECODE_AFNI && g_opts.debug > 2 ) /* ~XML */
-            fprintf(stderr,"   AFNI extension: %.*s\n",
-                    extn.esize-8,extn.edata);
-         else if( extn.ecode == NIFTI_ECODE_COMMENT && g_opts.debug > 2 )
-            fprintf(stderr,"   COMMENT extension: %.*s\n",        /* TEXT */
-                    extn.esize-8,extn.edata);
-      }
-      remain -= extn.esize;
-      count++;
-   }
-
-   if( g_opts.debug > 2 ) fprintf(stderr,"+d found %lld extension(s)\n", count);
-
-   /* rcr n2 - allow int64_t num ext? */
-   nim->num_ext = (int)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@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 ){
-      fprintf(stderr,"** 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 )
-      fprintf(stderr,"+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 ){
-      fprintf(stderr,"** fill_ext: bad params (%p,%p,%d)\n",
-              (void *)ext, data, len);
-      return -1;
-   } else if( ! nifti_is_valid_ecode(ecode) ){
-      fprintf(stderr,"** fill_ext: invalid ecode %d\n", ecode);
-      /* should not be fatal    29 Apr 2015 [rickr] */
-   }
-
-   /* 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 ){
-      fprintf(stderr,"** 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 )
-      fprintf(stderr,"+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 )
-         fprintf(stderr,"-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 )
-         fprintf(stderr,"-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 )
-         fprintf(stderr,"-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 )
-      fprintf(stderr,"-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 */
-         fprintf(stderr,"** 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 ){
-      fprintf(stderr,"** 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 )
-         fprintf(stderr,"-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 )
-      fprintf(stderr,"+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 ) fprintf(stderr,"-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 )
-            fprintf(stderr,"-d ext %d, invalid code %d\n", c, ext->ecode);
-         /* should not be fatal    29 Apr 2015 [rickr] */
-      }
-
-      if( ext->esize <= 0 ){
-         if( g_opts.debug > 1 )
-            fprintf(stderr,"-d ext %d, bad size = %d\n", c, ext->esize);
-         errs++;
-      } else if( ext->esize & 0xf ){
-         if( g_opts.debug > 1 )
-            fprintf(stderr,"-d ext %d, size %d not multiple of 16\n",
-                    c, ext->esize);
-         errs++;
-      }
-
-      if( ext->edata == NULL ){
-         if( g_opts.debug > 1 ) fprintf(stderr,"-d ext %d, missing data\n", c);
-         errs++;
-      }
-
-      ext++;
-   }
-
-   if( errs > 0 ){
-      if( g_opts.debug > 0 )
-         fprintf(stderr,"-d had %d extension errors, none will be written\n",
-                 errs);
-      return 0;
-   }
-
-   /* if we're here, we're good */
-   return 1;
-}
-
-/*----------------------------------------------------------------------*/
-/*! determine NIFTI version from buffer (check sizeof_hdr and magic)
-  
-       \return -1 on error, else NIFTI version
- *//*--------------------------------------------------------------------*/
-int nifti_header_version(const char * buf, int nbytes){
-   nifti_1_header *n1p = (nifti_1_header *)buf;
-   nifti_2_header *n2p = (nifti_2_header *)buf;
-   char            fname[] = { "nifti_header_version" };
-   int             sizeof_hdr, sver, nver;
-
-   if( !buf ) {
-      if(g_opts.debug > 0) 
-         fprintf(stderr,"** %s: have NULL buffer pointer", fname);
-      return -1;
-   }
-
-   if( nbytes < sizeof(nifti_1_header) ) {
-      if(g_opts.debug > 0) 
-         fprintf(stderr,"** %s: nbytes=%d, too small for test", fname, nbytes);
-      return -1;
-   }
-
-   /* try to determine the version based on sizeof_hdr */
-   sver = -1;
-   sizeof_hdr = n1p->sizeof_hdr;
-   if     ( sizeof_hdr == (int)sizeof(nifti_1_header) ) sver = 1;
-   else if( sizeof_hdr == (int)sizeof(nifti_2_header) ) sver = 2;
-   else { /* try swapping */
-      nifti_swap_4bytes(1, &sizeof_hdr);
-      if     ( sizeof_hdr == (int)sizeof(nifti_1_header) ) sver = 1;
-      else if( sizeof_hdr == (int)sizeof(nifti_2_header) ) sver = 2;
-   }
-
-   /* and check magic field */
-   if      ( sver == 1 ) nver = NIFTI_VERSION(*n1p);
-   else if ( sver == 2 ) nver = NIFTI_VERSION(*n2p);
-   else                  nver = -1;
-
-   /* now compare and return */
-
-   if( g_opts.debug > 2 )
-      fprintf(stderr,"-- %s: size ver = %d, ni ver = %d\n", fname, sver, nver);
-
-   if( sver == 1 ) {
-      nver = NIFTI_VERSION(*n1p);
-      if( nver == 0 ) return 0;        /* ANALYZE */
-      if( nver == 1 ) return 1;        /* NIFTI-1 */
-      if( g_opts.debug > 1 )
-         fprintf(stderr,"** %s: bad NIFTI-1 magic= %.4s", fname, n1p->magic);
-      return -1;
-   } else if ( sver == 2 ) {
-      nver = NIFTI_VERSION(*n2p);
-      if( nver == 2 ) return 2;        /* NIFTI-2 */
-      if( g_opts.debug > 1 )
-         fprintf(stderr,"** %s: bad NIFTI-2 magic4= %.4s", fname, n2p->magic);
-      return -1;
-   }
-
-   /* failure */
-
-   if( g_opts.debug > 0 )
-      fprintf(stderr,"** %s: bad sizeof_hdr = %d\n", fname, n1p->sizeof_hdr);
-
-   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 )
-         fprintf(stderr,"-d invalid extension code %d\n",code);
-      /* should not be fatal    29 Apr 2015 [rickr] */
-   }
-
-   if( size < 16 ){
-      if( g_opts.debug > 2 )
-         fprintf(stderr,"-d ext size %d, no extension\n",size);
-      return 0;
-   }
-
-   if( size > rem ){
-      if( g_opts.debug > 2 )
-         fprintf(stderr,"-d ext size %d, space %d, no extension\n", size, rem);
-      return 0;
-   }
-
-   if( size & 0xf ){
-      if( g_opts.debug > 2 )
-         fprintf(stderr,"-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 )
-         fprintf(stderr,"-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 */
-   int64_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 ) fprintf(stderr,"** ERROR: N_image_load: no nifti image\n");
-         else fprintf(stderr,"** ERROR: N_image_load: bad params (%p,%d,%lld)\n",
-                      nim->iname, nim->nbyper, 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 )
-         fprintf(stderr,"** 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 ){
-      fprintf(stderr,"** could not seek to offset %lld in file '%s'\n",
-              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( nifti_image *nim )
-{
-   /* set up data space, open data file and seek, then call nifti_read_buffer */
-   int64_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 )
-         fprintf(stderr,"** 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 )
-           fprintf(stderr,"** 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(fp,nim->data,ntot,nim);
-   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 ;
-}
-
-
-/* 30 Nov 2004 [rickr]
-#undef  ERREX
-#define ERREX(msg)                                               \
- do{ fprintf(stderr,"** ERROR: nifti_read_buffer: %s\n",(msg)) ;  \
-     return 0; } while(0)
-*/
-
-/*----------------------------------------------------------------------*/
-/*! 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.
-*//*--------------------------------------------------------------------*/
-int64_t nifti_read_buffer(znzFile fp, void* dataptr, int64_t ntot,
-                                nifti_image *nim)
-{
-  int64_t ii;
-
-  if( dataptr == NULL ){
-     if( g_opts.debug > 0 )
-        fprintf(stderr,"** 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 )
-       fprintf(stderr,"++ WARNING: nifti_read_buffer(%s):\n"
-               "   data bytes needed = %lld\n"
-               "   data bytes input  = %lld\n"
-               "   number missing    = %lld (set to 0)\n",
-               nim->iname , ntot , ii , (ntot-ii) ) ;
-    /* memset( (char *)(dataptr)+ii , 0 , ntot-ii ) ;  now failure [rickr] */
-    return -1 ;
-  }
-
-  if( g_opts.debug > 2 )
-    fprintf(stderr,"+d nifti_read_buffer: read %lld bytes\n", ii);
-
-  /* byte swap array if needed */
-
-  /* ntot/swapsize might not fit as int, use int64_t    6 Jul 2010 [rickr] */
-  if( nim->swapsize > 1 && nim->byteorder != nifti_short_order() ) {
-    if( g_opts.debug > 1 )
-       fprintf(stderr,"+d nifti_read_buffer: swapping data bytes...\n");
-    nifti_swap_Nbytes( (int)(ntot / nim->swapsize), nim->swapsize , dataptr ) ;
-  }
-
-#ifdef isfinite
-{
-  /* 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 int64_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 int64_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 )
-     fprintf(stderr,"+d in image, %d bad floats were set to 0\n", fix_count);
-}
-#endif
-
-  return ii;
-}
-
-/*--------------------------------------------------------------------------*/
-/*! 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) )
-      fprintf(stderr,"** warning: nifti extension num/ptr mismatch (%d,%p)\n",
-              nim->num_ext, (void *)nim->ext_list);
-
-   if( g_opts.debug > 2 )
-      fprintf(stderr,"+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 ){ fputs(str,stderr) ; free(str) ; }
-   return ;
-}
-
-
-/*--------------------------------------------------------------------------
- * nifti_write_buffer just check for a null znzFile and call znzwrite
- *--------------------------------------------------------------------------*/
-/*! \fn int64_t nifti_write_buffer(znzFile fp, void *buffer, int64_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
-*/
-int64_t nifti_write_buffer(znzFile fp, const void *buffer, int64_t numbytes)
-{
-   /* Write all the image data at once (no swapping here) */
-   int64_t ss;
-   if (znz_isnull(fp)){
-      fprintf(stderr,"** ERROR: nifti_write_buffer: null file pointer\n");
-      return 0;
-   }
-   ss = znzwrite( (const 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)
-{
-   int64_t ss, bnum;
-
-   if( !NBL ){ /* just write one buffer and get out of here */
-      if( nim->data == NULL ){
-         fprintf(stderr,"** 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){
-         fprintf(stderr,
-            "** ERROR: NWAD: wrote only %lld of %lld bytes to file\n",
-            ss, nim->nbyper * nim->nvox);
-         return -1;
-      }
-
-      if( g_opts.debug > 1 )
-         fprintf(stderr,"+d wrote single image of %lld bytes\n", ss);
-   } else {
-      if( ! NBL->bricks || NBL->nbricks <= 0 || NBL->bsize <= 0 ){
-         fprintf(stderr,"** NWAD: no brick data to write (%p,%lld,%lld)\n",
-                 (void *)NBL->bricks, NBL->nbricks, 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 ){
-            fprintf(stderr,
-            "** NWAD ERROR: wrote %lld of %lld bytes of brick %lld of %lld to file",
-            ss, NBL->bsize, bnum+1, NBL->nbricks);
-            return -1;
-         }
-      }
-      if( g_opts.debug > 1 )
-         fprintf(stderr,"+d wrote image of %lld brick(s), each of %lld bytes\n",
-                 NBL->nbricks, 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 )
-         fprintf(stderr,"** 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 )
-         fprintf(stderr,"-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 ){
-      fprintf(stderr,"** 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 ){
-         fprintf(stderr,"** failed while writing extension #%d\n",c);
-         return -1;
-      } else if ( g_opts.debug > 2 )
-         fprintf(stderr,"+d wrote extension %d of %d bytes\n", c, size);
-
-      list++;
-   }
-
-   if( g_opts.debug > 1 )
-      fprintf(stderr,"+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;
-   nifti_2_header nhdr;
-   int nbyper, swapsize;
-
-   memset(&nhdr,0,sizeof(nhdr)) ;  /* zero out header, to be safe */
-
-   nhdr.sizeof_hdr = sizeof(nhdr) ;
-
-   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 ;
-
-   memcpy(nhdr.magic, nifti2_magic, 8);  /* init to single file */
-
-   nim = nifti_convert_n2hdr2nim(nhdr,NULL);
-   nim->fname = NULL;
-   nim->iname = NULL;
-   return nim;
-}
-
-
-/*----------------------------------------------------------------------*/
-/*! basic initialization of a nifti_2_header struct (with given dimensions)
-
-   Return an allocated nifti_2_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_2_header struct
-*//*--------------------------------------------------------------------*/
-nifti_2_header * nifti_make_new_n2_header(const int64_t arg_dims[],
-                                          int arg_dtype)
-{
-   nifti_2_header * nhdr;
-   const int64_t    default_dims[8] = { 3, 1, 1, 1, 0, 0, 0, 0 };
-   const int64_t  * 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 ) {
-      fprintf(stderr,"** nifti_simple_hdr_with_dims: bad dim[0]=%lld\n",dim[0]);
-      dim = default_dims;
-   } else {
-      for( c = 1; c <= dim[0]; c++ )
-         if( dim[c] < 1 )
-         {
-            fprintf(stderr,
-                "** nifti_simple_hdr_with_dims: bad dim[%d]=%lld\n",c,dim[c]);
-            dim = default_dims;
-            break;
-         }
-   }
-
-   /* validate dtype, too */
-   dtype = arg_dtype;
-   if( ! nifti_is_valid_datatype(dtype) ) {
-      fprintf(stderr,"** nifti_simple_hdr_with_dims: bad dtype %d\n",dtype);
-      dtype = DT_FLOAT32;
-   }
-
-   /* now populate the header struct */
-
-   if( g_opts.debug > 1 )
-      fprintf(stderr,"+d make_new_n2_header, dim[0] = %lld, datatype = %d\n",
-              dim[0], dtype);
-
-   nhdr = (nifti_2_header *)calloc(1,sizeof(nifti_2_header));
-   if( !nhdr ){
-      fprintf(stderr,"** make_new_n2_header: failed to alloc hdr\n");
-      return NULL;
-   }
-
-   nhdr->sizeof_hdr = sizeof(nifti_2_header) ;
-
-   /* 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 ;
-
-   memcpy(nhdr->magic, nifti2_magic, 8);  /* init to single file */
-
-   return nhdr;
-}
-
-
-/*----------------------------------------------------------------------*/
-/*! 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_n1_header(const int64_t arg_dims[],
-                                          int arg_dtype)
-{
-   nifti_1_header * nhdr;
-   const int64_t    default_dims[8] = { 3, 1, 1, 1, 0, 0, 0, 0 };
-   const int64_t  * 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 ) {
-      fprintf(stderr,"** nifti_simple_hdr_with_dims: bad dim[0]=%lld\n",dim[0]);
-      dim = default_dims;
-   } else {
-      for( c = 1; c <= dim[0]; c++ )
-         if( dim[c] < 1 )
-         {
-            fprintf(stderr,
-                "** nifti_simple_hdr_with_dims: bad dim[%d]=%lld\n",c,dim[c]);
-            dim = default_dims;
-            break;
-         }
-   }
-
-   /* validate dtype, too */
-   dtype = arg_dtype;
-   if( ! nifti_is_valid_datatype(dtype) ) {
-      fprintf(stderr,"** nifti_simple_hdr_with_dims: bad dtype %d\n",dtype);
-      dtype = DT_FLOAT32;
-   }
-
-   /* now populate the header struct */
-
-   if( g_opts.debug > 1 )
-      fprintf(stderr,"+d make_new_n1_header, dim[0] = %lld, datatype = %d\n",
-              dim[0], dtype);
-
-   nhdr = (nifti_1_header *)calloc(1,sizeof(nifti_1_header));
-   if( !nhdr ){
-      fprintf(stderr,"** make_new_n1_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] = (int)dim[0]; /* rcr n2 - check dim sizes for nifti-1 */
-                               /* (verify vals are < 2^15) */
-   nhdr->pixdim[0] = 0.0f;
-   for( c = 1; c <= dim[0]; c++ ) {
-      nhdr->dim[c] = (int)dim[c];
-      nhdr->pixdim[c] = 1.0f;
-   }
-
-   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 int64_t dims[], int datatype,
-                                 int data_fill)
-{
-   nifti_image    * nim;
-   nifti_2_header * nhdr;
-
-   nhdr = nifti_make_new_n2_header(dims, datatype);
-   if( !nhdr ) return NULL;  /* error already printed */
-
-   nim = nifti_convert_n2hdr2nim(*nhdr,NULL);
-   free(nhdr);               /* in any case, we are done with this */
-   if( !nim ){
-      fprintf(stderr,"** NMNN: nifti_convert_n2hdr2nim failure\n");
-      return NULL;
-   }
-
-   if( g_opts.debug > 1 )
-      fprintf(stderr,"+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 ) {
-         fprintf(stderr,"** NMNN: failed to alloc %lld bytes for data\n",
-                 nim->nvox*nim->nbyper);
-         nifti_image_free(nim);
-         nim = NULL;
-      }
-   }
-
-   return nim;
-}
-
-#undef N_CHECK_2BYTE_VAL
-#define N_CHECK_2BYTE_VAL(fn) do { if( ! NIFTI_IS_16_BIT_INT(nim->fn) ) { \
-   fprintf(stderr,"** nim->%s = %lld does not fit into NIFTI-1 header\n", \
-           #fn, (long long)nim->fn); return 1; } } while(0)
-
-
-/*----------------------------------------------------------------------*/
-/*! 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_nim2n1hdr(my_nim_pointer);
-    </pre>
-*//*--------------------------------------------------------------------*/
-int nifti_convert_nim2n1hdr(const nifti_image * nim, nifti_1_header * hdr)
-{
-   nifti_1_header nhdr;
-
-   if( !hdr ) {
-      fprintf(stderr,"** nifti_CN2N1hdr: no hdr to fill\n");
-      return 1;
-   }
-
-   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 */
-
-   N_CHECK_2BYTE_VAL(ndim);
-   N_CHECK_2BYTE_VAL(nx);
-   N_CHECK_2BYTE_VAL(ny);
-   N_CHECK_2BYTE_VAL(nz);
-   N_CHECK_2BYTE_VAL(nt);
-   N_CHECK_2BYTE_VAL(nu);
-   N_CHECK_2BYTE_VAL(nv);
-   N_CHECK_2BYTE_VAL(nw);
-   N_CHECK_2BYTE_VAL(datatype);
-   N_CHECK_2BYTE_VAL(nbyper);
-
-   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.0f ;
-   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] = (float)fabs(nhdr.pixdim[1]) ;
-     nhdr.pixdim[2] = (float)fabs(nhdr.pixdim[2]) ;
-     nhdr.pixdim[3] = (float)fabs(nhdr.pixdim[3]) ;
-     nhdr.pixdim[4] = (float)fabs(nhdr.pixdim[4]) ;
-     nhdr.pixdim[5] = (float)fabs(nhdr.pixdim[5]) ;
-     nhdr.pixdim[6] = (float)fabs(nhdr.pixdim[6]) ;
-     nhdr.pixdim[7] = (float)fabs(nhdr.pixdim[7]) ;
-
-     N_CHECK_2BYTE_VAL(intent_code);
-     N_CHECK_2BYTE_VAL(qform_code);
-     N_CHECK_2BYTE_VAL(sform_code);
-
-     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.0f : -1.0f ;
-     }
-
-     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] ;
-     }
-
-     N_CHECK_2BYTE_VAL(sform_code);
-     N_CHECK_2BYTE_VAL(slice_start);
-     N_CHECK_2BYTE_VAL(slice_end);
-
-     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 ;
-   }
-
-   memcpy(hdr, &nhdr, sizeof(nhdr));
-
-   return 0;
-}
-
-
-/*----------------------------------------------------------------------*/
-/*! convert a nifti_image structure to a nifti_2_header struct
-
-    No allocation is done, this should be used via structure copy.
-    As in:
-    <pre>
-    nifti_2_header my_header;
-    my_header = nifti_convert_nim2n2hdr(my_nim_pointer);
-    </pre>
-*//*--------------------------------------------------------------------*/
-int nifti_convert_nim2n2hdr(const nifti_image * nim, nifti_2_header * hdr)
-{
-   nifti_2_header nhdr;
-
-   if( !hdr ) {
-      fprintf(stderr,"** nifti_CN2N2hdr: no hdr to fill\n");
-      return 1;
-   }
-
-   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) ;
-   if( nim->nifti_type == NIFTI_FTYPE_NIFTI2_1 ) strcpy(nhdr.magic,"n+2") ;
-   else                                          strcpy(nhdr.magic,"ni2") ;
-
-   nhdr.datatype = nim->datatype ;
-   nhdr.bitpix   = 8 * nim->nbyper ;
-
-   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.intent_p1 = nim->intent_p1 ;
-   nhdr.intent_p2 = nim->intent_p2 ;
-   nhdr.intent_p3 = nim->intent_p3 ;
-
-   nhdr.pixdim[0] = 0.0 ;
-   nhdr.pixdim[1] = fabs(nim->dx) ; nhdr.pixdim[2] = fabs(nim->dy) ;
-   nhdr.pixdim[3] = fabs(nim->dz) ; nhdr.pixdim[4] = fabs(nim->dt) ;
-   nhdr.pixdim[5] = fabs(nim->du) ; nhdr.pixdim[6] = fabs(nim->dv) ;
-   nhdr.pixdim[7] = fabs(nim->dw) ;
-
-   nhdr.vox_offset  = nim->iname_offset ;
-
-   nhdr.scl_slope = nim->scl_slope ;
-   nhdr.scl_inter = nim->scl_inter ;
-
-   nhdr.cal_max = nim->cal_max ;
-   nhdr.cal_min = nim->cal_min ;
-
-   nhdr.slice_duration = nim->slice_duration ;
-   nhdr.toffset        = nim->toffset ;
-   nhdr.slice_start    = nim->slice_start ;
-   nhdr.slice_end      = nim->slice_end ;
-
-   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' ;
-   }
-
-   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.0f : -1.0f ;
-   }
-
-   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.slice_code  = nim->slice_code ;
-   nhdr.xyzt_units  = SPACE_TIME_TO_XYZT( nim->xyz_units, nim->time_units ) ;
-   nhdr.intent_code = nim->intent_code ;
-   if( nim->intent_name[0] != '\0' ){
-     memcpy(nhdr.intent_name,nim->intent_name,15) ;
-     nhdr.intent_name[15] = '\0' ;
-   }
-
-   nhdr.dim_info = FPS_INTO_DIM_INFO( nim->freq_dim ,
-                                      nim->phase_dim , nim->slice_dim ) ;
-
-   nhdr.unused_str[0] = '\0' ;  /* not needed, but complete */
-
-   memcpy(hdr, &nhdr, sizeof(nhdr));
-
-   return 0;
-}
-
-
-/*----------------------------------------------------------------------*/
-/*! \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;
-   int64_t  bytes;
-   int      c, size, old_size;
-
-   if( nim_dest->num_ext > 0 || nim_dest->ext_list != NULL ){
-      fprintf(stderr,"** will not copy extensions over existing ones\n");
-      return -1;
-   }
-
-   if( g_opts.debug > 1 )
-      fprintf(stderr,"+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 ){
-      fprintf(stderr,"** 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 )
-         fprintf(stderr,"+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 ){
-         fprintf(stderr,"** 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 ) fprintf(stderr,"-d ext sizes:");
-
-   for ( c = 0; c < nim->num_ext; c++ ){
-      size += nim->ext_list[c].esize;
-      if( g_opts.debug > 2 ) fprintf(stderr,"  %d",nim->ext_list[c].esize);
-   }
-
-   if( g_opts.debug > 2 ) fprintf(stderr," (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)
-{
-   int64_t 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(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 )
-             fprintf(stderr,"+d changing offset from %lld to %lld\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{ fprintf(stderr,"** 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)
-{
-   nifti_1_header n1hdr ;
-   nifti_2_header n2hdr ;
-   znzFile        fp=NULL;
-   int64_t        ss ;
-   int            write_data, leave_open;
-   int            nver=1, hsize=(int)sizeof(nifti_1_header);  /* 5 Aug 2015 */
-   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 ){
-      fprintf(stderr,"-d writing nifti file '%s'...\n", nim->fname);
-      if( g_opts.debug > 2 )
-         fprintf(stderr,"-d nifti type %d, offset %lld\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);
-
-   /* create the nifti header struct                  5 Aug, 2015 [rickr]
-        - default is NIFTI-1 (option?)
-        - if that fails try NIFTI-2
-   */
-   if( nifti_convert_nim2n1hdr(nim, &n1hdr) ) {
-      if( nifti_convert_nim2n2hdr(nim, &n2hdr) ) return NULL;
-      fprintf(stderr,"+d writing %s as NIFTI-2, instead...\n", nim->fname);
-      nver = 2; /* we will write NIFTI-2 */
-      hsize = (int)sizeof(nifti_2_header);
-   }
-
-   /* 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 ) fprintf(stderr,"+d using passed file for hdr\n");
-      fp = imgfile;
-   }
-   else {
-      if( g_opts.debug > 2 )
-         fprintf(stderr,"+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 */
-
-   if( nver == 2 ) ss = znzwrite(&n2hdr , 1 , hsize , fp); /* write header */
-   else            ss = znzwrite(&n1hdr , 1 , hsize , fp); /* write header */
-
-   if( ss < hsize ){
-      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 ) fprintf(stderr,"-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) fprintf(stderr,"+d using passed file for img\n");
-         fp = imgfile;
-      }
-      else {
-         if( g_opts.debug > 2 )
-            fprintf(stderr,"+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 ){ fprintf(stderr,"** failed image_to_ascii()\n"); return NULL; }
-
-   fp = znzopen( nim->fname , opts , nifti_is_gzfile(nim->fname) ) ;
-   if( znz_isnull(fp) ){
-      free(hstr);
-      fprintf(stderr,"** 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 ) fprintf(stderr,"-d niw: done with znzFile\n");
-      free(fp);
-   }
-   if( g_opts.debug > 1 ) fprintf(stderr,"-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 ) fprintf(stderr,"-d niwb: done with znzFile\n");
-      free(fp);
-   }
-   if( g_opts.debug > 1 ) fprintf(stderr,"-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 ){
-     fprintf(stderr,"** 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:
-     -  &lt;   ->  <
-     -  &gt;   ->  >
-     -  &quot; ->  "
-     -  &apos; ->  '
-     -  &amp;  ->  &
-   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        &&   /* &lt; */
-                 str[ii+1] == 'l' &&
-                 str[ii+2] == 't' &&
-                 str[ii+3] == ';'   ){ str[jj] = '<' ; ii += 3 ; nn++ ; }
-
-        else if( ii+3 < ll        &&   /* &gt; */
-                 str[ii+1] == 'g' &&
-                 str[ii+2] == 't' &&
-                 str[ii+3] == ';'   ){ str[jj] = '>' ; ii += 3 ; nn++ ; }
-
-        else if( ii+5 < ll        &&   /* &quot; */
-                 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        &&   /* &apos; */
-                 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        &&  /* &amp; */
-                 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 &#32; (decimal) and &#xfd; (hex) */
-
-        else if( ii+3 < ll        &&
-                 str[ii+1] == '#' &&
-                 isdigit((int) 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((int) 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 "&amp;" */
-
-       case '<':
-       case '>':  lout += 4 ; break ;  /* replace '<' with "&lt;" */
-
-       case '"' :
-       case '\'': lout += 6 ; break ;  /* replace '"' with "&quot;" */
-
-       case CR:
-       case LF:   lout += 6 ; break ;  /* replace CR with "&#x0d;"
-                                                  LF with "&#x0a;" */
-
-       default: lout++ ; break ;      /* copy all other chars */
-     }
-   }
-   out = (char *)calloc(1,lout) ;     /* allocate output string */
-   if( !out ){
-      fprintf(stderr,"** 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,"&amp;",5)  ; jj+=5 ; break ;
-
-         case '<':  memcpy(out+jj,"&lt;",4)   ; jj+=4 ; break ;
-         case '>':  memcpy(out+jj,"&gt;",4)   ; jj+=4 ; break ;
-
-         case '"' : memcpy(out+jj,"&quot;",6) ; jj+=6 ; break ;
-
-         case '\'': memcpy(out+jj,"&apos;",6) ; jj+=6 ; break ;
-
-         case CR:   memcpy(out+jj,"&#x0d;",6) ; jj+=6 ; break ;
-         case LF:   memcpy(out+jj,"&#x0a;",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 ){
-      fprintf(stderr,"** 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 = '%lld'\n" , nim->iname_offset );
-
-                       sprintf( buf+strlen(buf), "  ndim = '%lld'\n",nim->ndim);
-                       sprintf( buf+strlen(buf), "  nx = '%lld'\n",  nim->nx  );
-   if( nim->ndim > 1 ) sprintf( buf+strlen(buf), "  ny = '%lld'\n",  nim->ny  );
-   if( nim->ndim > 2 ) sprintf( buf+strlen(buf), "  nz = '%lld'\n",  nim->nz  );
-   if( nim->ndim > 3 ) sprintf( buf+strlen(buf), "  nt = '%lld'\n",  nim->nt  );
-   if( nim->ndim > 4 ) sprintf( buf+strlen(buf), "  nu = '%lld'\n",  nim->nu  );
-   if( nim->ndim > 5 ) sprintf( buf+strlen(buf), "  nv = '%lld'\n",  nim->nv  );
-   if( nim->ndim > 6 ) sprintf( buf+strlen(buf), "  nw = '%lld'\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 = '%lld'\n" ,  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 = '%lld'\n"
-              "  slice_end = '%lld'\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_dmat44_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_dmat44_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 ) fprintf(stderr,"** 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,tt) if( strcmp(lhs,#n1)==0 ) nim->n2=(tt)strtod(rhs,NULL)
-
-/* same, but where "n1" == "n2" */
-
-#define QNUM(nam,tt)    QQNUM(nam,nam,tt)
-
-/* 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 ;
-   nifti_image *nim ;              /* will be output */
-
-   if( str == NULL || *str == '\0' ) return NULL ;  /* bad input!? */
-
-   /* scan for opening string */
-
-   spos = 0 ;
-   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 ){
-      fprintf(stderr,"** 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.0f ;
-
-   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 , "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf" ,
-               &(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,int) ;
-     else QNUM(datatype,short int) ;
-     else QNUM(ndim,int) ;
-     else QNUM(nx,int) ;
-     else QNUM(ny,int) ;
-     else QNUM(nz,int) ;
-     else QNUM(nt,int) ;
-     else QNUM(nu,int) ;
-     else QNUM(nv,int) ;
-     else QNUM(nw,int) ;
-     else QNUM(dx,float) ;
-     else QNUM(dy,float) ;
-     else QNUM(dz,float) ;
-     else QNUM(dt,float) ;
-     else QNUM(du,float) ;
-     else QNUM(dv,float) ;
-     else QNUM(dw,float) ;
-     else QNUM(cal_min,float) ;
-     else QNUM(cal_max,float) ;
-     else QNUM(scl_slope,float) ;
-     else QNUM(scl_inter,float) ;
-     else QNUM(intent_code,short) ;
-     else QNUM(intent_p1,float) ;
-     else QNUM(intent_p2,float) ;
-     else QNUM(intent_p3,float) ;
-     else QSTR(intent_name,15) ;
-     else QNUM(toffset,float) ;
-     else QNUM(xyz_units,int) ;
-     else QNUM(time_units,int) ;
-     else QSTR(descrip,79) ;
-     else QSTR(aux_file,23) ;
-     else QNUM(qform_code,int) ;
-     else QNUM(quatern_b,float) ;
-     else QNUM(quatern_c,float) ;
-     else QNUM(quatern_d,float) ;
-     else QNUM(qoffset_x,float) ;
-     else QNUM(qoffset_y,float) ;
-     else QNUM(qoffset_z,float) ;
-     else QNUM(qfac,float) ;
-     else QNUM(sform_code,int) ;
-     else QNUM(freq_dim,int) ;
-     else QNUM(phase_dim,int) ;
-     else QNUM(slice_dim,int) ;
-     else QNUM(slice_code,int) ;
-     else QNUM(slice_start,int) ;
-     else QNUM(slice_end,int) ;
-     else QNUM(slice_duration,float) ;
-     else QNUM(num_ext,int) ;
-
-   } /* 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 = (int64_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_dmat44(
-                      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_dmat44(
-                      0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ,
-                      nim->dx , nim->dy , nim->dz , 0.0 ) ;
-
-
-   nim->qto_ijk = nifti_dmat44_inverse( nim->qto_xyz ) ;
-
-   if( nim->sform_code > 0 )
-     nim->sto_ijk = nifti_dmat44_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_hdr1_looks_good
-*//*-------------------------------------------------------------------------*/
-int nifti_nim_is_valid(nifti_image * nim, int complain)
-{
-   int errs = 0;
-
-   if( !nim ){
-      fprintf(stderr,"** is_valid_nim: nim is NULL\n");
-      return 0;
-   }
-
-   if( g_opts.debug > 2 ) fprintf(stderr,"-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_hdr1_looks_good
-
-    rely on dim[] as the master
-*//*-------------------------------------------------------------------------*/
-int nifti_nim_has_valid_dims(nifti_image * nim, int complain)
-{
-   int64_t prod, c;
-   int     errs = 0;
-
-   /**- start with dim[0]: failure here is considered terminal */
-   if( nim->dim[0] <= 0 || nim->dim[0] > 7 ){
-      errs++;
-      if( complain )
-        fprintf(stderr,"** NVd: dim[0] (%lld) 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;
-      fprintf(stderr,"** NVd: ndim != dim[0] (%lld,%lld)\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;
-      fprintf(stderr,"** NVd mismatch: dims    = %lld,%lld,%lld,%lld,%lld,%lld,%lld\n"
-                     "                 nxyz... = %lld,%lld,%lld,%lld,%lld,%lld,%lld\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 ){
-      fprintf(stderr,"-d check dim[%lld] =", nim->dim[0]);
-      for( c = 0; c < 7; c++ ) fprintf(stderr," %lld", nim->dim[c]);
-      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;
-         fprintf(stderr,"** NVd: dim[%lld] (=%lld) <= 0\n",c, nim->dim[c]);
-         errs++;
-      }
-   }
-   if( prod != nim->nvox ){
-      if( ! complain ) return 0;
-      fprintf(stderr,"** NVd: nvox does not match %lld-dim product (%lld, %lld)\n",
-              nim->dim[0], nim->nvox, 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 )
-            fprintf(stderr,"** NVd warning: dim[%lld] = %lld, but ndim = %lld\n",
-                    c, nim->dim[c], nim->dim[0]);
-
-   if( g_opts.debug > 2 )
-      fprintf(stderr,"-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. { int64_t 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
-*//*-------------------------------------------------------------------------*/
-int64_t nifti_read_collapsed_image( nifti_image * nim, const int64_t dims [8],
-                                void ** data )
-{
-   znzFile fp;
-   int64_t prods[8];          /* sizes are bounded by dims[], so 8 */
-   int     pivots[8], nprods; /* sizes are bounded by dims[], so 8 */
-   int64_t c, bytes;
-
-   /** - check pointers for sanity */
-   if( !nim || !dims || !data ){
-      fprintf(stderr,"** nifti_RCI: bad params %p, %p, %p\n",
-              (void *)nim, (const void *)dims, (void *)data);
-      return -1;
-   }
-
-   if( g_opts.debug > 2 ){
-      fprintf(stderr,"-d read_collapsed_image:\n        dims =");
-      for(c = 0; c < 8; c++) fprintf(stderr," %3lld", dims[c]);
-      fprintf(stderr,"\n   nim->dims =");
-      for(c = 0; c < 8; c++) fprintf(stderr," %3lld", nim->dim[c]);
-      fputc('\n', stderr);
-   }
-
-   /** - verify that dim[] makes sense */
-   if( ! nifti_nim_is_valid(nim, g_opts.debug > 0) ){
-      fprintf(stderr,"** 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] ){
-         fprintf(stderr,"** nifti_RCI: dims[%lld] >= nim->dim[%lld] (%lld,%lld)\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 )
-      fprintf(stderr,"+d read %lld 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(int64_t *strides,const int64_t *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 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 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
-*//*-------------------------------------------------------------------------*/
-int64_t nifti_read_subregion_image( nifti_image * nim,
-                                int64_t *start_index,
-                                int64_t *region_size,
-                                void ** data )
-{
-  znzFile fp;                   /* file to read */
-  int64_t i,j,k,l,m,n;          /* indices for dims */
-  int64_t bytes = 0;            /* total # bytes read */
-  int64_t total_alloc_size;     /* size of buffer allocation */
-  char   *readptr;              /* where in *data to read next */
-  int64_t strides[7];           /* strides between dimensions */
-  int64_t collapsed_dims[8];    /* for read_collapsed_image */
-  int64_t *image_size;          /* pointer to dimensions in header */
-  int64_t initial_offset;
-  int64_t 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)
-        fprintf(stderr,"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) *data = (void *)malloc(total_alloc_size);
-
-  if(! *data) {
-    if(g_opts.debug > 1)
-      fprintf(stderr,"allocation of %lld 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
-  */
-  int64_t 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++) {
-              int64_t 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 subregion */
-              nread = nifti_read_buffer(fp, readptr, read_amount, nim);
-              if(nread != read_amount) {
-                if(g_opts.debug > 1) {
-                  fprintf(stderr,"read of %lld 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, int64_t * prods,
-                         int nprods, const int64_t dims[], char * data,
-                         znzFile fp, int64_t base_offset)
-{
-   int64_t sublen, offset, read_size;
-   int     c;
-
-   /* bad check first - base_offset may not have been checked */
-   if( nprods <= 0 ){
-      fprintf(stderr,"** rci_read_data, bad prods, %d\n", nprods);
-      return -1;
-   }
-
-   /* base case: actually read the data */
-   if( nprods == 1 ){
-      int64_t nread, bytes;
-
-      /* make sure things look good here */
-      if( *pivots != 0 ){
-         fprintf(stderr,"** rciRD: final pivot == %d!\n", *pivots);
-         return -1;
-      }
-
-      /* so just seek and read (prods[0] * nbyper) bytes from the file */
-      znzseek(fp, base_offset, SEEK_SET);
-      bytes = prods[0] * nim->nbyper;
-      nread = nifti_read_buffer(fp, data, bytes, nim);
-      if( nread != bytes ){
-         fprintf(stderr,"** rciRD: read only %lld of %lld bytes from '%s'\n",
-                 nread, bytes, nim->fname);
-         return -1;
-      } else if( g_opts.debug > 3 )
-         fprintf(stderr,"+d successful read of %lld bytes at offset %lld\n",
-                 bytes, 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 = (int64_t)c * sublen * nim->dim[*pivots] +
-               (int64_t)sublen * dims[*pivots];
-      offset *= nim->nbyper;
-
-      if( g_opts.debug > 3 )
-         fprintf(stderr,"-d reading %lld bytes, foff %lld + %lld, doff %lld\n",
-                 read_size, base_offset, offset, 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, int64_t prods[8], int nprods, int nbyper )
-{
-   int64_t size;
-   int     memindex;
-
-   if( nbyper < 0 || nprods < 1 || nprods > 8 ){
-      fprintf(stderr,"** rci_am: bad params, %d, %d\n", nbyper, nprods);
-      return -1;
-   }
-
-   for( memindex = 0, size = 1; memindex < nprods; memindex++ )
-       size *= prods[memindex];
-
-   size *= nbyper;
-
-   if( ! *data ){   /* then allocate what is needed */
-      if( g_opts.debug > 1 )
-         fprintf(stderr,"+d alloc %lld (%lld x %d) bytes for collapsed image\n",
-                 size, size/nbyper, nbyper);
-
-      *data = malloc(size);   /* actually allocate the memory */
-      if( ! *data ){
-        fprintf(stderr,"** rci_am: failed to alloc %lld bytes for data\n", size);
-        return -1;
-      }
-   } else if( g_opts.debug > 1 )
-      fprintf(stderr,"-d rci_am: *data already set, need %lld x %d bytes\n",
-              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 int64_t dims[], int pivots[],
-                                             int64_t prods[], int * nprods )
-{
-   int len, dind;
-
-   len = 0;
-   dind = nim->dim[0];
-   while( dind > 0 ){
-      prods[len] = 1;
-      while( dind > 0 && (nim->dim[dind] == 1 || dims[dind] == -1) ){
-         prods[len] *= nim->dim[dind];
-         dind--;
-      }
-      pivots[len] = dind;
-      len++;
-      dind--;  /* 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 ){
-      fprintf(stderr,"+d pivot list created, pivots :");
-      for(dind = 0; dind < len; dind++) fprintf(stderr," %d", pivots[dind]);
-      fprintf(stderr,", prods :");
-      for(dind = 0; dind < len; dind++) fprintf(stderr," %lld", prods[dind]);
-      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)
-*//*-------------------------------------------------------------------*/
-int64_t * nifti_get_int64list( int64_t nvals , const char * str )
-{
-   int64_t *subv = NULL ;
-   int64_t ii , nout ;
-   int64_t ibot,itop,istep , nused ;
-   int     ipos , slen ;
-   char    *cpt ;
-
-   /* Meaningless input? */
-   if( nvals < 1 ) return NULL ;
-
-   /* No selection list? */
-   if( str == NULL || str[0] == '\0' ) return NULL ;
-
-   /* skip initial '[' or '{' */
-   subv = (int64_t *)malloc( sizeof(int64_t) * 2 ) ;
-   if( !subv ) {
-      fprintf(stderr,"** 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 )
-      fprintf(stderr,"-d making int_list (vals = %lld) 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 = strtoll( str+ipos , &cpt , 10 ) ;
-         if( ibot < 0 ){
-           fprintf(stderr,"** ERROR: list index %lld is out of range 0..%lld\n",
-                   ibot,nvals-1) ;
-           free(subv) ; return NULL ;
-         }
-         if( ibot >= nvals ){
-           fprintf(stderr,"** ERROR: list index %lld is out of range 0..%lld\n",
-                   ibot,nvals-1) ;
-           free(subv) ; return NULL ;
-         }
-         nused = (cpt-(str+ipos)) ;
-         if( ibot == 0 && nused == 0 ){
-           fprintf(stderr,"** 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 = (int64_t *)realloc( (char *)subv , sizeof(int64_t)*(nout+1) ) ;
-         if( !subv ) {
-            fprintf(stderr,"** nifti_get_intlist: failed realloc of %lld 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 {
-         fprintf(stderr,"** 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 = strtoll( str+ipos , &cpt , 10 ) ;
-         if( itop < 0 ){
-           fprintf(stderr,"** ERROR: index %lld is out of range 0..%lld\n",
-                   itop,nvals-1) ;
-           free(subv) ; return NULL ;
-         }
-         if( itop >= nvals ){
-           fprintf(stderr,"** ERROR: index %lld is out of range 0..%lld\n",
-                   itop,nvals-1) ;
-           free(subv) ; return NULL ;
-         }
-         nused = (cpt-(str+ipos)) ;
-         if( itop == 0 && nused == 0 ){
-           fprintf(stderr,"** 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 = strtoll( str+ipos , &cpt , 10 ) ;
-         if( istep == 0 ){
-           fprintf(stderr,"** 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 ){
-        fprintf(stderr,"** WARNING: index list '%lld..%lld(%lld)' means nothing\n",
-                ibot,itop,istep ) ;
-         }
-      }
-
-      /**- add values to output */
-
-      for( ii=ibot ; (ii-itop)*istep <= 0 ; ii += istep ){
-         nout++ ;
-         subv = (int64_t *)realloc( (char *)subv , sizeof(int64_t)*(nout+1) ) ;
-         if( !subv ) {
-            fprintf(stderr,"** nifti_get_intlist: failed realloc of %lld 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 ) {
-      fprintf(stderr,"+d int_list (vals = %lld): ", subv[0]);
-      for( ii = 1; ii <= subv[0]; ii++ ) fprintf(stderr,"%lld ", subv[ii]);
-      fputc('\n',stderr);
-   }
-
-   if( subv[0] == 0 ){ free(subv); subv = NULL; }
-   return subv ;
-}
-
-/*! a 32-bit version of nifti_get_int64list */
-int * nifti_get_intlist( int nvals , const char * str )
-{
-   int     *ilist=NULL;
-   int64_t *i64list=NULL, nints, index;
-
-   i64list = nifti_get_int64list((int64_t)nvals, str);
-   if( !i64list ) return NULL;
-
-   /* check that the length is between 1 and INT_MAX */
-   nints = i64list[0];
-   if( nints <= 0 ) { free(i64list); return NULL; }
-
-   if( nints > INT_MAX ) {
-      fprintf(stderr,"** N_get_intlist: %lld ints is too long for 32-bits\n",
-              nints);
-      free(i64list);
-      return NULL;
-   }
-
-   /* have a valid result, copy as ints */
-   ilist = (int *)malloc((nints+1) * sizeof(int));
-   if( !ilist ) {
-      fprintf(stderr,"** N_get_intlist: failed to alloc %lld ints\n", nints);
-      free(i64list);
-      return NULL;
-   }
-
-   /* copy list, including length at index 0 */
-   for( index=0; index <= nints; index++ ) {
-      if( i64list[index] > INT_MAX ) {
-         fprintf(stderr,"** N_get_intlist: value %lld too big for 32-bits\n",
-                 i64list[index]);
-         free(ilist);
-         free(i64list);
-         return NULL;
-      }
-      ilist[index] = (int)i64list[index];
-   }
-
-   free(i64list);
-
-   return ilist;
-}
-
-/*---------------------------------------------------------------------*/
-/*! 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 )
-                fprintf(stderr, "** 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 )
-        fprintf(stderr,"** nifti_test_datatype_sizes: found %d errors\n",errs);
-    else if( verb || g_opts.debug > 1 )
-        fprintf(stderr,"-- 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 )
-{
-    const 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"; }
-
-    printf("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')     )
-            printf("  %-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/include/nifti/znzlib.h b/include/nifti/znzlib.h
index 0fbbe83fa4d0de2183055d4a7c07da0327630b86..fb10ed94a7bfa2d65b955cb4ec749787d9cd78fe 100644
--- a/include/nifti/znzlib.h
+++ b/include/nifti/znzlib.h
@@ -120,5 +120,3 @@ int znzprintf(znzFile stream, const char *format, ...);
 /*=================*/
 
 #endif
-
-#include "znzlib.i"
\ No newline at end of file
diff --git a/include/nifti/nifti1_io.i b/source/nifti1_io.c
similarity index 99%
rename from include/nifti/nifti1_io.i
rename to source/nifti1_io.c
index c60e8ce435d68445ce7887dfe5d1d545bd9c37fe..7601b93757dd91bf2ac0a5bf71ae0e5daf62f92b 100644
--- a/include/nifti/nifti1_io.i
+++ b/source/nifti1_io.c
@@ -1,5 +1,7 @@
 #define _NIFTI1_IO_C_
 
+#include "nifti/nifti1_io.h"   /* typedefs, prototypes, macros, etc. */
+
 /*****===================================================================*****/
 /*****     Sample functions to deal with NIFTI-1 and ANALYZE files       *****/
 /*****...................................................................*****/
diff --git a/include/nifti/znzlib.i b/source/znzlib.c
similarity index 99%
rename from include/nifti/znzlib.i
rename to source/znzlib.c
index fd45d612f269be2f2134a8f875377b8bb4828b82..9ec6493f3175309faa61bb59a1e1e93626c010af 100644
--- a/include/nifti/znzlib.i
+++ b/source/znzlib.c
@@ -21,6 +21,8 @@ NB: seeks for writable files with compression are quite restricted
 
  */
 
+#include "nifti/znzlib.h"
+
 /*
 znzlib.c  (zipped or non-zipped library)