Rniftilib/0000755000176000001440000000000012073363334012230 5ustar ripleyusersRniftilib/MD50000644000176000001440000000321712073363334012543 0ustar ripleyusers884c037c94842902da2a3c8a0c65d0f6 *DESCRIPTION 76e0dcf8e7f673276552a8716f8a0dcb *NAMESPACE 242236e11d4a2cd05c4b9b12491d44a9 *R/FirstLib.R 77a59777688961dc624920f16efbb0b4 *R/nifti.R 273c6e72840b936f5344c4f86e5ff14f *aclocal.m4 b1aa4ae453e5e1977ac0499b8b063239 *ax_check_zlib.m4 8ff747358eb34ea32927437a911ad4a2 *config.h.in 2c560e99c34240970cc606923ee44ac9 *configure 0a296d28c735d73c45dc405c35fdeb7c *man/nifti.Rd 646418076b2ece81a187867f9ad7e0f5 *man/nifti_compiled_with_zlib.Rd fff00980dc6554bfd269740fd5050eb5 *man/nifti_datatype_string.Rd e7b2e14e203d6e445d82866164ead19d *man/nifti_disp_lib_version.Rd 5e49bd6a3dbcf915b37fc04c86b8e84a *man/nifti_image_alloc_data.Rd 6e9695d6e29816a883e2053b9648636c *man/nifti_image_copy_info.Rd 900db6e48804ebf0a57cb08cbeb5d38b *man/nifti_image_free.Rd 37900ab79fec037a1915854c96e28cda *man/nifti_image_new.Rd dbb7f78a624af299f39c396379f2ac2c *man/nifti_image_read.Rd dca29b72df0b858cbd3511474c4283a6 *man/nifti_image_setdatatype.Rd a3a92959c7f6806f681283c4fd427538 *man/nifti_image_unload.Rd 87d7526759fe7d1c091fe2fbfcc4c538 *man/nifti_image_write.Rd 0f1d716c3f6237f006ab37c88078da2b *man/nifti_interpolate3D.Rd f3980cbeedddc3204acb559a52d6b4a9 *man/nifti_read_subregion_image.Rd c19b86a1ebb48e09b8ad54f619b73994 *man/nifti_set_filenames.Rd 5e403154b3dde7ffeda36f528809a3e5 *man/nifti_units_string.Rd 57bed97ab321fc58adda3494b98176b6 *src/Makevars.in 2f8293076dac8388836c9ce0fd3c13fe *src/Rnifti.c 1bc087b9e954b8b395d9379d43158f6e *src/nifti1.h 4e47ac05ed5c500902736b7f7fe8c78d *src/nifti1_io.c 3ffa2b1885d2ed474f2f0bca5fa6d4af *src/nifti1_io.h 9d845690f5382b6c3bea879e91821b09 *src/znzlib.c 582b9f5d055aad992611f091fc13a26b *src/znzlib.h Rniftilib/src/0000755000176000001440000000000012073247733013023 5ustar ripleyusersRniftilib/src/nifti1.h0000644000176000001440000020716412073250671014373 0ustar ripleyusers/** \file nifti1.h \brief Official definition of the nifti1 header. Written by Bob Cox, SSCC, NIMH. HISTORY: 29 Nov 2007 [rickr] - added DT_RGBA32 and NIFTI_TYPE_RGBA32 - added NIFTI_INTENT codes: TIME_SERIES, NODE_INDEX, RGB_VECTOR, RGBA_VECTOR, SHAPE */ #ifndef _NIFTI_HEADER_ #define _NIFTI_HEADER_ /***************************************************************************** ** This file defines the "NIFTI-1" header format. ** ** It is derived from 2 meetings at the NIH (31 Mar 2003 and ** ** 02 Sep 2003) of the Data Format Working Group (DFWG), ** ** chartered by the NIfTI (Neuroimaging Informatics Technology ** ** Initiative) at the National Institutes of Health (NIH). ** **--------------------------------------------------------------** ** Neither the National Institutes of Health (NIH), the DFWG, ** ** nor any of the members or employees of these institutions ** ** imply any warranty of usefulness of this material for any ** ** purpose, and do not assume any liability for damages, ** ** incidental or otherwise, caused by any use of this document. ** ** If these conditions are not acceptable, do not use this! ** **--------------------------------------------------------------** ** Author: Robert W Cox (NIMH, Bethesda) ** ** Advisors: John Ashburner (FIL, London), ** ** Stephen Smith (FMRIB, Oxford), ** ** Mark Jenkinson (FMRIB, Oxford) ** ******************************************************************************/ /*---------------------------------------------------------------------------*/ /* Note that the ANALYZE 7.5 file header (dbh.h) is (c) Copyright 1986-1995 Biomedical Imaging Resource Mayo Foundation Incorporation of components of dbh.h are by permission of the Mayo Foundation. Changes from the ANALYZE 7.5 file header in this file are released to the public domain, including the functional comments and any amusing asides. -----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /*! INTRODUCTION TO NIFTI-1: ------------------------ The twin (and somewhat conflicting) goals of this modified ANALYZE 7.5 format are: (a) To add information to the header that will be useful for functional neuroimaging data analysis and display. These additions include: - More basic data types. - Two affine transformations to specify voxel coordinates. - "Intent" codes and parameters to describe the meaning of the data. - Affine scaling of the stored data values to their "true" values. - Optional storage of the header and image data in one file (.nii). (b) To maintain compatibility with non-NIFTI-aware ANALYZE 7.5 compatible software (i.e., such a program should be able to do something useful with a NIFTI-1 dataset -- at least, with one stored in a traditional .img/.hdr file pair). Most of the unused fields in the ANALYZE 7.5 header have been taken, and some of the lesser-used fields have been co-opted for other purposes. Notably, most of the data_history substructure has been co-opted for other purposes, since the ANALYZE 7.5 format describes this substructure as "not required". NIFTI-1 FLAG (MAGIC STRINGS): ---------------------------- To flag such a struct as being conformant to the NIFTI-1 spec, the last 4 bytes of the header must be either the C String "ni1" or "n+1"; in hexadecimal, the 4 bytes 6E 69 31 00 or 6E 2B 31 00 (in any future version of this format, the '1' will be upgraded to '2', etc.). Normally, such a "magic number" or flag goes at the start of the file, but trying to avoid clobbering widely-used ANALYZE 7.5 fields led to putting this marker last. However, recall that "the last shall be first" (Matthew 20:16). If a NIFTI-aware program reads a header file that is NOT marked with a NIFTI magic string, then it should treat the header as an ANALYZE 7.5 structure. NIFTI-1 FILE STORAGE: -------------------- "ni1" means that the image data is stored in the ".img" file corresponding to the header file (starting at file offset 0). "n+1" means that the image data is stored in the same file as the header information. We recommend that the combined header+data filename suffix be ".nii". When the dataset is stored in one file, the first byte of image data is stored at byte location (int)vox_offset in this combined file. The minimum allowed value of vox_offset is 352; for compatibility with some software, vox_offset should be an integral multiple of 16. GRACE UNDER FIRE: ---------------- Most NIFTI-aware programs will only be able to handle a subset of the full range of datasets possible with this format. All NIFTI-aware programs should take care to check if an input dataset conforms to the program's needs and expectations (e.g., check datatype, intent_code, etc.). If the input dataset can't be handled by the program, the program should fail gracefully (e.g., print a useful warning; not crash). SAMPLE CODES: ------------ The associated files nifti1_io.h and nifti1_io.c provide a sample implementation in C of a set of functions to read, write, and manipulate NIFTI-1 files. The file nifti1_test.c is a sample program that uses the nifti1_io.c functions. -----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* HEADER STRUCT DECLARATION: ------------------------- In the comments below for each field, only NIFTI-1 specific requirements or changes from the ANALYZE 7.5 format are described. For convenience, the 348 byte header is described as a single struct, rather than as the ANALYZE 7.5 group of 3 substructs. Further comments about the interpretation of various elements of this header are after the data type definition itself. Fields that are marked as ++UNUSED++ have no particular interpretation in this standard. (Also see the UNUSED FIELDS comment section, far below.) The presumption below is that the various C types have particular sizes: sizeof(int) = sizeof(float) = 4 ; sizeof(short) = 2 -----------------------------------------------------------------------------*/ /*=================*/ #ifdef __cplusplus extern "C" { #endif /*=================*/ /*! \struct nifti_1_header \brief Data structure defining the fields in the nifti1 header. This binary header should be found at the beginning of a valid NIFTI-1 header file. */ /*************************/ /************************/ struct nifti_1_header { /* NIFTI-1 usage */ /* ANALYZE 7.5 field(s) */ /*************************/ /************************/ /*--- was header_key substruct ---*/ int sizeof_hdr; /*!< MUST be 348 */ /* int sizeof_hdr; */ char data_type[10]; /*!< ++UNUSED++ */ /* char data_type[10]; */ char db_name[18]; /*!< ++UNUSED++ */ /* char db_name[18]; */ int extents; /*!< ++UNUSED++ */ /* int extents; */ short session_error; /*!< ++UNUSED++ */ /* short session_error; */ char regular; /*!< ++UNUSED++ */ /* char regular; */ char dim_info; /*!< MRI slice ordering. */ /* char hkey_un0; */ /*--- was image_dimension substruct ---*/ short dim[8]; /*!< Data array dimensions.*/ /* short dim[8]; */ float intent_p1 ; /*!< 1st intent parameter. */ /* short unused8; */ /* short unused9; */ float intent_p2 ; /*!< 2nd intent parameter. */ /* short unused10; */ /* short unused11; */ float intent_p3 ; /*!< 3rd intent parameter. */ /* short unused12; */ /* short unused13; */ short intent_code ; /*!< NIFTI_INTENT_* code. */ /* short unused14; */ short datatype; /*!< Defines data type! */ /* short datatype; */ short bitpix; /*!< Number bits/voxel. */ /* short bitpix; */ short slice_start; /*!< First slice index. */ /* short dim_un0; */ float pixdim[8]; /*!< Grid spacings. */ /* float pixdim[8]; */ float vox_offset; /*!< Offset into .nii file */ /* float vox_offset; */ float scl_slope ; /*!< Data scaling: slope. */ /* float funused1; */ float scl_inter ; /*!< Data scaling: offset. */ /* float funused2; */ short slice_end; /*!< Last slice index. */ /* float funused3; */ char slice_code ; /*!< Slice timing order. */ char xyzt_units ; /*!< Units of pixdim[1..4] */ float cal_max; /*!< Max display intensity */ /* float cal_max; */ float cal_min; /*!< Min display intensity */ /* float cal_min; */ float slice_duration;/*!< Time for 1 slice. */ /* float compressed; */ float toffset; /*!< Time axis shift. */ /* float verified; */ int glmax; /*!< ++UNUSED++ */ /* int glmax; */ int glmin; /*!< ++UNUSED++ */ /* int glmin; */ /*--- was data_history substruct ---*/ char descrip[80]; /*!< any text you like. */ /* char descrip[80]; */ char aux_file[24]; /*!< auxiliary filename. */ /* char aux_file[24]; */ short qform_code ; /*!< NIFTI_XFORM_* code. */ /*-- all ANALYZE 7.5 ---*/ short sform_code ; /*!< NIFTI_XFORM_* code. */ /* fields below here */ /* are replaced */ float quatern_b ; /*!< Quaternion b param. */ float quatern_c ; /*!< Quaternion c param. */ float quatern_d ; /*!< Quaternion d param. */ float qoffset_x ; /*!< Quaternion x shift. */ float qoffset_y ; /*!< Quaternion y shift. */ float qoffset_z ; /*!< Quaternion z shift. */ float srow_x[4] ; /*!< 1st row affine transform. */ float srow_y[4] ; /*!< 2nd row affine transform. */ float srow_z[4] ; /*!< 3rd row affine transform. */ char intent_name[16];/*!< 'name' or meaning of data. */ char magic[4] ; /*!< MUST be "ni1\0" or "n+1\0". */ } ; /**** 348 bytes total ****/ typedef struct nifti_1_header nifti_1_header ; /*---------------------------------------------------------------------------*/ /* HEADER EXTENSIONS: ----------------- After the end of the 348 byte header (e.g., after the magic field), the next 4 bytes are a char array field named "extension". By default, all 4 bytes of this array should be set to zero. In a .nii file, these 4 bytes will always be present, since the earliest start point for the image data is byte #352. In a separate .hdr file, these bytes may or may not be present. If not present (i.e., if the length of the .hdr file is 348 bytes), then a NIfTI-1 compliant program should use the default value of extension={0,0,0,0}. The first byte (extension[0]) is the only value of this array that is specified at present. The other 3 bytes are reserved for future use. If extension[0] is nonzero, it indicates that extended header information is present in the bytes following the extension array. In a .nii file, this extended header data is before the image data (and vox_offset must be set correctly to allow for this). In a .hdr file, this extended data follows extension and proceeds (potentially) to the end of the file. The format of extended header data is weakly specified. Each extension must be an integer multiple of 16 bytes long. The first 8 bytes of each extension comprise 2 integers: int esize , ecode ; These values may need to be byte-swapped, as indicated by dim[0] for the rest of the header. * esize is the number of bytes that form the extended header data + esize must be a positive integral multiple of 16 + this length includes the 8 bytes of esize and ecode themselves * ecode is a non-negative integer that indicates the format of the extended header data that follows + different ecode values are assigned to different developer groups + at present, the "registered" values for code are = 0 = unknown private format (not recommended!) = 2 = DICOM format (i.e., attribute tags and values) = 4 = AFNI group (i.e., ASCII XML-ish elements) In the interests of interoperability (a primary rationale for NIfTI), groups developing software that uses this extension mechanism are encouraged to document and publicize the format of their extensions. To this end, the NIfTI DFWG will assign even numbered codes upon request to groups submitting at least rudimentary documentation for the format of their extension; at present, the contact is mailto:rwcox@nih.gov. The assigned codes and documentation will be posted on the NIfTI website. All odd values of ecode (and 0) will remain unassigned; at least, until the even ones are used up, when we get to 2,147,483,646. Note that the other contents of the extended header data section are totally unspecified by the NIfTI-1 standard. In particular, if binary data is stored in such a section, its byte order is not necessarily the same as that given by examining dim[0]; it is incumbent on the programs dealing with such data to determine the byte order of binary extended header data. Multiple extended header sections are allowed, each starting with an esize,ecode value pair. The first esize value, as described above, is at bytes #352-355 in the .hdr or .nii file (files start at byte #0). If this value is positive, then the second (esize2) will be found starting at byte #352+esize1 , the third (esize3) at byte #352+esize1+esize2, et cetera. Of course, in a .nii file, the value of vox_offset must be compatible with these extensions. If a malformed file indicates that an extended header data section would run past vox_offset, then the entire extended header section should be ignored. In a .hdr file, if an extended header data section would run past the end-of-file, that extended header data should also be ignored. With the above scheme, a program can successively examine the esize and ecode values, and skip over each extended header section if the program doesn't know how to interpret the data within. Of course, any program can simply ignore all extended header sections simply by jumping straight to the image data using vox_offset. -----------------------------------------------------------------------------*/ /*! \struct nifti1_extender \brief This structure represents a 4-byte string that should follow the binary nifti_1_header data in a NIFTI-1 header file. If the char values are {1,0,0,0}, the file is expected to contain extensions, values of {0,0,0,0} imply the file does not contain extensions. Other sequences of values are not currently defined. */ struct nifti1_extender { char extension[4] ; } ; typedef struct nifti1_extender nifti1_extender ; /*! \struct nifti1_extension \brief Data structure defining the fields of a header extension. */ struct nifti1_extension { int esize ; /*!< size of extension, in bytes (must be multiple of 16) */ int ecode ; /*!< extension code, one of the NIFTI_ECODE_ values */ char * edata ; /*!< raw data, with no byte swapping (length is esize-8) */ } ; typedef struct nifti1_extension nifti1_extension ; /*---------------------------------------------------------------------------*/ /* DATA DIMENSIONALITY (as in ANALYZE 7.5): --------------------------------------- dim[0] = number of dimensions; - if dim[0] is outside range 1..7, then the header information needs to be byte swapped appropriately - ANALYZE supports dim[0] up to 7, but NIFTI-1 reserves dimensions 1,2,3 for space (x,y,z), 4 for time (t), and 5,6,7 for anything else needed. dim[i] = length of dimension #i, for i=1..dim[0] (must be positive) - also see the discussion of intent_code, far below pixdim[i] = voxel width along dimension #i, i=1..dim[0] (positive) - cf. ORIENTATION section below for use of pixdim[0] - the units of pixdim can be specified with the xyzt_units field (also described far below). Number of bits per voxel value is in bitpix, which MUST correspond with the datatype field. The total number of bytes in the image data is dim[1] * ... * dim[dim[0]] * bitpix / 8 In NIFTI-1 files, dimensions 1,2,3 are for space, dimension 4 is for time, and dimension 5 is for storing multiple values at each spatiotemporal voxel. Some examples: - A typical whole-brain FMRI experiment's time series: - dim[0] = 4 - dim[1] = 64 pixdim[1] = 3.75 xyzt_units = NIFTI_UNITS_MM - dim[2] = 64 pixdim[2] = 3.75 | NIFTI_UNITS_SEC - dim[3] = 20 pixdim[3] = 5.0 - dim[4] = 120 pixdim[4] = 2.0 - A typical T1-weighted anatomical volume: - dim[0] = 3 - dim[1] = 256 pixdim[1] = 1.0 xyzt_units = NIFTI_UNITS_MM - dim[2] = 256 pixdim[2] = 1.0 - dim[3] = 128 pixdim[3] = 1.1 - A single slice EPI time series: - dim[0] = 4 - dim[1] = 64 pixdim[1] = 3.75 xyzt_units = NIFTI_UNITS_MM - dim[2] = 64 pixdim[2] = 3.75 | NIFTI_UNITS_SEC - dim[3] = 1 pixdim[3] = 5.0 - dim[4] = 1200 pixdim[4] = 0.2 - A 3-vector stored at each point in a 3D volume: - dim[0] = 5 - dim[1] = 256 pixdim[1] = 1.0 xyzt_units = NIFTI_UNITS_MM - dim[2] = 256 pixdim[2] = 1.0 - dim[3] = 128 pixdim[3] = 1.1 - dim[4] = 1 pixdim[4] = 0.0 - dim[5] = 3 intent_code = NIFTI_INTENT_VECTOR - A single time series with a 3x3 matrix at each point: - dim[0] = 5 - dim[1] = 1 xyzt_units = NIFTI_UNITS_SEC - dim[2] = 1 - dim[3] = 1 - dim[4] = 1200 pixdim[4] = 0.2 - dim[5] = 9 intent_code = NIFTI_INTENT_GENMATRIX - intent_p1 = intent_p2 = 3.0 (indicates matrix dimensions) -----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* DATA STORAGE: ------------ If the magic field is "n+1", then the voxel data is stored in the same file as the header. In this case, the voxel data starts at offset (int)vox_offset into the header file. Thus, vox_offset=352.0 means that the data starts immediately after the NIFTI-1 header. If vox_offset is greater than 352, the NIFTI-1 format does not say much about the contents of the dataset file between the end of the header and the start of the data. FILES: ----- If the magic field is "ni1", then the voxel data is stored in the associated ".img" file, starting at offset 0 (i.e., vox_offset is not used in this case, and should be set to 0.0). When storing NIFTI-1 datasets in pairs of files, it is customary to name the files in the pattern "name.hdr" and "name.img", as in ANALYZE 7.5. When storing in a single file ("n+1"), the file name should be in the form "name.nii" (the ".nft" and ".nif" suffixes are already taken; cf. http://www.icdatamaster.com/n.html ). BYTE ORDERING: ------------- The byte order of the data arrays is presumed to be the same as the byte order of the header (which is determined by examining dim[0]). Floating point types are presumed to be stored in IEEE-754 format. -----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* DETAILS ABOUT vox_offset: ------------------------ In a .nii file, the vox_offset field value is interpreted as the start location of the image data bytes in that file. In a .hdr/.img file pair, the vox_offset field value is the start location of the image data bytes in the .img file. * If vox_offset is less than 352 in a .nii file, it is equivalent to 352 (i.e., image data never starts before byte #352 in a .nii file). * The default value for vox_offset in a .nii file is 352. * In a .hdr file, the default value for vox_offset is 0. * vox_offset should be an integer multiple of 16; otherwise, some programs may not work properly (e.g., SPM). This is to allow memory-mapped input to be properly byte-aligned. Note that since vox_offset is an IEEE-754 32 bit float (for compatibility with the ANALYZE-7.5 format), it effectively has a 24 bit mantissa. All integers from 0 to 2^24 can be represented exactly in this format, but not all larger integers are exactly storable as IEEE-754 32 bit floats. However, unless you plan to have vox_offset be potentially larger than 16 MB, this should not be an issue. (Actually, any integral multiple of 16 up to 2^27 can be represented exactly in this format, which allows for up to 128 MB of random information before the image data. If that isn't enough, then perhaps this format isn't right for you.) In a .img file (i.e., image data stored separately from the NIfTI-1 header), data bytes between #0 and #vox_offset-1 (inclusive) are completely undefined and unregulated by the NIfTI-1 standard. One potential use of having vox_offset > 0 in the .hdr/.img file pair storage method is to make the .img file be a copy of (or link to) a pre-existing image file in some other format, such as DICOM; then vox_offset would be set to the offset of the image data in this file. (It may not be possible to follow the "multiple-of-16 rule" with an arbitrary external file; using the NIfTI-1 format in such a case may lead to a file that is incompatible with software that relies on vox_offset being a multiple of 16.) In a .nii file, data bytes between #348 and #vox_offset-1 (inclusive) may be used to store user-defined extra information; similarly, in a .hdr file, any data bytes after byte #347 are available for user-defined extra information. The (very weak) regulation of this extra header data is described elsewhere. -----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* DATA SCALING: ------------ If the scl_slope field is nonzero, then each voxel value in the dataset should be scaled as y = scl_slope * x + scl_inter where x = voxel value stored y = "true" voxel value Normally, we would expect this scaling to be used to store "true" floating values in a smaller integer datatype, but that is not required. That is, it is legal to use scaling even if the datatype is a float type (crazy, perhaps, but legal). - However, the scaling is to be ignored if datatype is DT_RGB24. - If datatype is a complex type, then the scaling is to be applied to both the real and imaginary parts. The cal_min and cal_max fields (if nonzero) are used for mapping (possibly scaled) dataset values to display colors: - Minimum display intensity (black) corresponds to dataset value cal_min. - Maximum display intensity (white) corresponds to dataset value cal_max. - Dataset values below cal_min should display as black also, and values above cal_max as white. - Colors "black" and "white", of course, may refer to any scalar display scheme (e.g., a color lookup table specified via aux_file). - cal_min and cal_max only make sense when applied to scalar-valued datasets (i.e., dim[0] < 5 or dim[5] = 1). -----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* TYPE OF DATA (acceptable values for datatype field): --------------------------------------------------- Values of datatype smaller than 256 are ANALYZE 7.5 compatible. Larger values are NIFTI-1 additions. These are all multiples of 256, so that no bits below position 8 are set in datatype. But there is no need to use only powers-of-2, as the original ANALYZE 7.5 datatype codes do. The additional codes are intended to include a complete list of basic scalar types, including signed and unsigned integers from 8 to 64 bits, floats from 32 to 128 bits, and complex (float pairs) from 64 to 256 bits. Note that most programs will support only a few of these datatypes! A NIFTI-1 program should fail gracefully (e.g., print a warning message) when it encounters a dataset with a type it doesn't like. -----------------------------------------------------------------------------*/ #undef DT_UNKNOWN /* defined in dirent.h on some Unix systems */ /*! \defgroup NIFTI1_DATATYPES \brief nifti1 datatype codes @{ */ /*--- the original ANALYZE 7.5 type codes ---*/ #define DT_NONE 0 #define DT_UNKNOWN 0 /* what it says, dude */ #define DT_BINARY 1 /* binary (1 bit/voxel) */ #define DT_UNSIGNED_CHAR 2 /* unsigned char (8 bits/voxel) */ #define DT_SIGNED_SHORT 4 /* signed short (16 bits/voxel) */ #define DT_SIGNED_INT 8 /* signed int (32 bits/voxel) */ #define DT_FLOAT 16 /* float (32 bits/voxel) */ #define DT_COMPLEX 32 /* complex (64 bits/voxel) */ #define DT_DOUBLE 64 /* double (64 bits/voxel) */ #define DT_RGB 128 /* RGB triple (24 bits/voxel) */ #define DT_ALL 255 /* not very useful (?) */ /*----- another set of names for the same ---*/ #define DT_UINT8 2 #define DT_INT16 4 #define DT_INT32 8 #define DT_FLOAT32 16 #define DT_COMPLEX64 32 #define DT_FLOAT64 64 #define DT_RGB24 128 /*------------------- new codes for NIFTI ---*/ #define DT_INT8 256 /* signed char (8 bits) */ #define DT_UINT16 512 /* unsigned short (16 bits) */ #define DT_UINT32 768 /* unsigned int (32 bits) */ #define DT_INT64 1024 /* long long (64 bits) */ #define DT_UINT64 1280 /* unsigned long long (64 bits) */ #define DT_FLOAT128 1536 /* long double (128 bits) */ #define DT_COMPLEX128 1792 /* double pair (128 bits) */ #define DT_COMPLEX256 2048 /* long double pair (256 bits) */ #define DT_RGBA32 2304 /* 4 byte RGBA (32 bits/voxel) */ /* @} */ /*------- aliases for all the above codes ---*/ /*! \defgroup NIFTI1_DATATYPE_ALIASES \brief aliases for the nifti1 datatype codes @{ */ /*! unsigned char. */ #define NIFTI_TYPE_UINT8 2 /*! signed short. */ #define NIFTI_TYPE_INT16 4 /*! signed int. */ #define NIFTI_TYPE_INT32 8 /*! 32 bit float. */ #define NIFTI_TYPE_FLOAT32 16 /*! 64 bit complex = 2 32 bit floats. */ #define NIFTI_TYPE_COMPLEX64 32 /*! 64 bit float = double. */ #define NIFTI_TYPE_FLOAT64 64 /*! 3 8 bit bytes. */ #define NIFTI_TYPE_RGB24 128 /*! signed char. */ #define NIFTI_TYPE_INT8 256 /*! unsigned short. */ #define NIFTI_TYPE_UINT16 512 /*! unsigned int. */ #define NIFTI_TYPE_UINT32 768 /*! signed long long. */ #define NIFTI_TYPE_INT64 1024 /*! unsigned long long. */ #define NIFTI_TYPE_UINT64 1280 /*! 128 bit float = long double. */ #define NIFTI_TYPE_FLOAT128 1536 /*! 128 bit complex = 2 64 bit floats. */ #define NIFTI_TYPE_COMPLEX128 1792 /*! 256 bit complex = 2 128 bit floats */ #define NIFTI_TYPE_COMPLEX256 2048 /*! 4 8 bit bytes. */ #define NIFTI_TYPE_RGBA32 2304 /* @} */ /*-------- sample typedefs for complicated types ---*/ #if 0 typedef struct { float r,i; } complex_float ; typedef struct { double r,i; } complex_double ; typedef struct { long double r,i; } complex_longdouble ; typedef struct { unsigned char r,g,b; } rgb_byte ; #endif /*---------------------------------------------------------------------------*/ /* INTERPRETATION OF VOXEL DATA: ---------------------------- The intent_code field can be used to indicate that the voxel data has some particular meaning. In particular, a large number of codes is given to indicate that the the voxel data should be interpreted as being drawn from a given probability distribution. VECTOR-VALUED DATASETS: ---------------------- The 5th dimension of the dataset, if present (i.e., dim[0]=5 and dim[5] > 1), contains multiple values (e.g., a vector) to be stored at each spatiotemporal location. For example, the header values - dim[0] = 5 - dim[1] = 64 - dim[2] = 64 - dim[3] = 20 - dim[4] = 1 (indicates no time axis) - dim[5] = 3 - datatype = DT_FLOAT - intent_code = NIFTI_INTENT_VECTOR mean that this dataset should be interpreted as a 3D volume (64x64x20), with a 3-vector of floats defined at each point in the 3D grid. A program reading a dataset with a 5th dimension may want to reformat the image data to store each voxels' set of values together in a struct or array. This programming detail, however, is beyond the scope of the NIFTI-1 file specification! Uses of dimensions 6 and 7 are also not specified here. STATISTICAL PARAMETRIC DATASETS (i.e., SPMs): -------------------------------------------- Values of intent_code from NIFTI_FIRST_STATCODE to NIFTI_LAST_STATCODE (inclusive) indicate that the numbers in the dataset should be interpreted as being drawn from a given distribution. Most such distributions have auxiliary parameters (e.g., NIFTI_INTENT_TTEST has 1 DOF parameter). If the dataset DOES NOT have a 5th dimension, then the auxiliary parameters are the same for each voxel, and are given in header fields intent_p1, intent_p2, and intent_p3. If the dataset DOES have a 5th dimension, then the auxiliary parameters are different for each voxel. For example, the header values - dim[0] = 5 - dim[1] = 128 - dim[2] = 128 - dim[3] = 1 (indicates a single slice) - dim[4] = 1 (indicates no time axis) - dim[5] = 2 - datatype = DT_FLOAT - intent_code = NIFTI_INTENT_TTEST mean that this is a 2D dataset (128x128) of t-statistics, with the t-statistic being in the first "plane" of data and the degrees-of-freedom parameter being in the second "plane" of data. If the dataset 5th dimension is used to store the voxel-wise statistical parameters, then dim[5] must be 1 plus the number of parameters required by that distribution (e.g., intent_code=NIFTI_INTENT_TTEST implies dim[5] must be 2, as in the example just above). Note: intent_code values 2..10 are compatible with AFNI 1.5x (which is why there is no code with value=1, which is obsolescent in AFNI). OTHER INTENTIONS: ---------------- The purpose of the intent_* fields is to help interpret the values stored in the dataset. Some non-statistical values for intent_code and conventions are provided for storing other complex data types. The intent_name field provides space for a 15 character (plus 0 byte) 'name' string for the type of data stored. Examples: - intent_code = NIFTI_INTENT_ESTIMATE; intent_name = "T1"; could be used to signify that the voxel values are estimates of the NMR parameter T1. - intent_code = NIFTI_INTENT_TTEST; intent_name = "House"; could be used to signify that the voxel values are t-statistics for the significance of 'activation' response to a House stimulus. - intent_code = NIFTI_INTENT_DISPVECT; intent_name = "ToMNI152"; could be used to signify that the voxel values are a displacement vector that transforms each voxel (x,y,z) location to the corresponding location in the MNI152 standard brain. - intent_code = NIFTI_INTENT_SYMMATRIX; intent_name = "DTI"; could be used to signify that the voxel values comprise a diffusion tensor image. If no data name is implied or needed, intent_name[0] should be set to 0. -----------------------------------------------------------------------------*/ /*! default: no intention is indicated in the header. */ #define NIFTI_INTENT_NONE 0 /*-------- These codes are for probability distributions ---------------*/ /* Most distributions have a number of parameters, below denoted by p1, p2, and p3, and stored in - intent_p1, intent_p2, intent_p3 if dataset doesn't have 5th dimension - image data array if dataset does have 5th dimension Functions to compute with many of the distributions below can be found in the CDF library from U Texas. Formulas for and discussions of these distributions can be found in the following books: [U] Univariate Discrete Distributions, NL Johnson, S Kotz, AW Kemp. [C1] Continuous Univariate Distributions, vol. 1, NL Johnson, S Kotz, N Balakrishnan. [C2] Continuous Univariate Distributions, vol. 2, NL Johnson, S Kotz, N Balakrishnan. */ /*----------------------------------------------------------------------*/ /*! [C2, chap 32] Correlation coefficient R (1 param): p1 = degrees of freedom R/sqrt(1-R*R) is t-distributed with p1 DOF. */ /*! \defgroup NIFTI1_INTENT_CODES \brief nifti1 intent codes, to describe intended meaning of dataset contents @{ */ #define NIFTI_INTENT_CORREL 2 /*! [C2, chap 28] Student t statistic (1 param): p1 = DOF. */ #define NIFTI_INTENT_TTEST 3 /*! [C2, chap 27] Fisher F statistic (2 params): p1 = numerator DOF, p2 = denominator DOF. */ #define NIFTI_INTENT_FTEST 4 /*! [C1, chap 13] Standard normal (0 params): Density = N(0,1). */ #define NIFTI_INTENT_ZSCORE 5 /*! [C1, chap 18] Chi-squared (1 param): p1 = DOF. Density(x) proportional to exp(-x/2) * x^(p1/2-1). */ #define NIFTI_INTENT_CHISQ 6 /*! [C2, chap 25] Beta distribution (2 params): p1=a, p2=b. Density(x) proportional to x^(a-1) * (1-x)^(b-1). */ #define NIFTI_INTENT_BETA 7 /*! [U, chap 3] Binomial distribution (2 params): p1 = number of trials, p2 = probability per trial. Prob(x) = (p1 choose x) * p2^x * (1-p2)^(p1-x), for x=0,1,...,p1. */ #define NIFTI_INTENT_BINOM 8 /*! [C1, chap 17] Gamma distribution (2 params): p1 = shape, p2 = scale. Density(x) proportional to x^(p1-1) * exp(-p2*x). */ #define NIFTI_INTENT_GAMMA 9 /*! [U, chap 4] Poisson distribution (1 param): p1 = mean. Prob(x) = exp(-p1) * p1^x / x! , for x=0,1,2,.... */ #define NIFTI_INTENT_POISSON 10 /*! [C1, chap 13] Normal distribution (2 params): p1 = mean, p2 = standard deviation. */ #define NIFTI_INTENT_NORMAL 11 /*! [C2, chap 30] Noncentral F statistic (3 params): p1 = numerator DOF, p2 = denominator DOF, p3 = numerator noncentrality parameter. */ #define NIFTI_INTENT_FTEST_NONC 12 /*! [C2, chap 29] Noncentral chi-squared statistic (2 params): p1 = DOF, p2 = noncentrality parameter. */ #define NIFTI_INTENT_CHISQ_NONC 13 /*! [C2, chap 23] Logistic distribution (2 params): p1 = location, p2 = scale. Density(x) proportional to sech^2((x-p1)/(2*p2)). */ #define NIFTI_INTENT_LOGISTIC 14 /*! [C2, chap 24] Laplace distribution (2 params): p1 = location, p2 = scale. Density(x) proportional to exp(-abs(x-p1)/p2). */ #define NIFTI_INTENT_LAPLACE 15 /*! [C2, chap 26] Uniform distribution: p1 = lower end, p2 = upper end. */ #define NIFTI_INTENT_UNIFORM 16 /*! [C2, chap 31] Noncentral t statistic (2 params): p1 = DOF, p2 = noncentrality parameter. */ #define NIFTI_INTENT_TTEST_NONC 17 /*! [C1, chap 21] Weibull distribution (3 params): p1 = location, p2 = scale, p3 = power. Density(x) proportional to ((x-p1)/p2)^(p3-1) * exp(-((x-p1)/p2)^p3) for x > p1. */ #define NIFTI_INTENT_WEIBULL 18 /*! [C1, chap 18] Chi distribution (1 param): p1 = DOF. Density(x) proportional to x^(p1-1) * exp(-x^2/2) for x > 0. p1 = 1 = 'half normal' distribution p1 = 2 = Rayleigh distribution p1 = 3 = Maxwell-Boltzmann distribution. */ #define NIFTI_INTENT_CHI 19 /*! [C1, chap 15] Inverse Gaussian (2 params): p1 = mu, p2 = lambda Density(x) proportional to exp(-p2*(x-p1)^2/(2*p1^2*x)) / x^3 for x > 0. */ #define NIFTI_INTENT_INVGAUSS 20 /*! [C2, chap 22] Extreme value type I (2 params): p1 = location, p2 = scale cdf(x) = exp(-exp(-(x-p1)/p2)). */ #define NIFTI_INTENT_EXTVAL 21 /*! Data is a 'p-value' (no params). */ #define NIFTI_INTENT_PVAL 22 /*! Data is ln(p-value) (no params). To be safe, a program should compute p = exp(-abs(this_value)). The nifti_stats.c library returns this_value as positive, so that this_value = -log(p). */ #define NIFTI_INTENT_LOGPVAL 23 /*! Data is log10(p-value) (no params). To be safe, a program should compute p = pow(10.,-abs(this_value)). The nifti_stats.c library returns this_value as positive, so that this_value = -log10(p). */ #define NIFTI_INTENT_LOG10PVAL 24 /*! Smallest intent_code that indicates a statistic. */ #define NIFTI_FIRST_STATCODE 2 /*! Largest intent_code that indicates a statistic. */ #define NIFTI_LAST_STATCODE 24 /*---------- these values for intent_code aren't for statistics ----------*/ /*! To signify that the value at each voxel is an estimate of some parameter, set intent_code = NIFTI_INTENT_ESTIMATE. The name of the parameter may be stored in intent_name. */ #define NIFTI_INTENT_ESTIMATE 1001 /*! To signify that the value at each voxel is an index into some set of labels, set intent_code = NIFTI_INTENT_LABEL. The filename with the labels may stored in aux_file. */ #define NIFTI_INTENT_LABEL 1002 /*! To signify that the value at each voxel is an index into the NeuroNames labels set, set intent_code = NIFTI_INTENT_NEURONAME. */ #define NIFTI_INTENT_NEURONAME 1003 /*! To store an M x N matrix at each voxel: - dataset must have a 5th dimension (dim[0]=5 and dim[5]>1) - intent_code must be NIFTI_INTENT_GENMATRIX - dim[5] must be M*N - intent_p1 must be M (in float format) - intent_p2 must be N (ditto) - the matrix values A[i][[j] are stored in row-order: - A[0][0] A[0][1] ... A[0][N-1] - A[1][0] A[1][1] ... A[1][N-1] - etc., until - A[M-1][0] A[M-1][1] ... A[M-1][N-1] */ #define NIFTI_INTENT_GENMATRIX 1004 /*! To store an NxN symmetric matrix at each voxel: - dataset must have a 5th dimension - intent_code must be NIFTI_INTENT_SYMMATRIX - dim[5] must be N*(N+1)/2 - intent_p1 must be N (in float format) - the matrix values A[i][[j] are stored in row-order: - A[0][0] - A[1][0] A[1][1] - A[2][0] A[2][1] A[2][2] - etc.: row-by-row */ #define NIFTI_INTENT_SYMMATRIX 1005 /*! To signify that the vector value at each voxel is to be taken as a displacement field or vector: - dataset must have a 5th dimension - intent_code must be NIFTI_INTENT_DISPVECT - dim[5] must be the dimensionality of the displacment vector (e.g., 3 for spatial displacement, 2 for in-plane) */ #define NIFTI_INTENT_DISPVECT 1006 /* specifically for displacements */ #define NIFTI_INTENT_VECTOR 1007 /* for any other type of vector */ /*! To signify that the vector value at each voxel is really a spatial coordinate (e.g., the vertices or nodes of a surface mesh): - dataset must have a 5th dimension - intent_code must be NIFTI_INTENT_POINTSET - dim[0] = 5 - dim[1] = number of points - dim[2] = dim[3] = dim[4] = 1 - dim[5] must be the dimensionality of space (e.g., 3 => 3D space). - intent_name may describe the object these points come from (e.g., "pial", "gray/white" , "EEG", "MEG"). */ #define NIFTI_INTENT_POINTSET 1008 /*! To signify that the vector value at each voxel is really a triple of indexes (e.g., forming a triangle) from a pointset dataset: - dataset must have a 5th dimension - intent_code must be NIFTI_INTENT_TRIANGLE - dim[0] = 5 - dim[1] = number of triangles - dim[2] = dim[3] = dim[4] = 1 - dim[5] = 3 - datatype should be an integer type (preferably DT_INT32) - the data values are indexes (0,1,...) into a pointset dataset. */ #define NIFTI_INTENT_TRIANGLE 1009 /*! To signify that the vector value at each voxel is a quaternion: - dataset must have a 5th dimension - intent_code must be NIFTI_INTENT_QUATERNION - dim[0] = 5 - dim[5] = 4 - datatype should be a floating point type */ #define NIFTI_INTENT_QUATERNION 1010 /*! Dimensionless value - no params - although, as in _ESTIMATE the name of the parameter may be stored in intent_name. */ #define NIFTI_INTENT_DIMLESS 1011 /*---------- these values apply to GIFTI datasets ----------*/ /*! To signify that the value at each location is from a time series. */ #define NIFTI_INTENT_TIME_SERIES 2001 /*! To signify that the value at each location is a node index, from a complete surface dataset. */ #define NIFTI_INTENT_NODE_INDEX 2002 /*! To signify that the vector value at each location is an RGB triplet, of whatever type. - dataset must have a 5th dimension - dim[0] = 5 - dim[1] = number of nodes - dim[2] = dim[3] = dim[4] = 1 - dim[5] = 3 */ #define NIFTI_INTENT_RGB_VECTOR 2003 /*! To signify that the vector value at each location is a 4 valued RGBA vector, of whatever type. - dataset must have a 5th dimension - dim[0] = 5 - dim[1] = number of nodes - dim[2] = dim[3] = dim[4] = 1 - dim[5] = 4 */ #define NIFTI_INTENT_RGBA_VECTOR 2004 /*! To signify that the value at each location is a shape value, such as the curvature. */ #define NIFTI_INTENT_SHAPE 2005 /* @} */ /*---------------------------------------------------------------------------*/ /* 3D IMAGE (VOLUME) ORIENTATION AND LOCATION IN SPACE: --------------------------------------------------- There are 3 different methods by which continuous coordinates can attached to voxels. The discussion below emphasizes 3D volumes, and the continuous coordinates are referred to as (x,y,z). The voxel index coordinates (i.e., the array indexes) are referred to as (i,j,k), with valid ranges: i = 0 .. dim[1]-1 j = 0 .. dim[2]-1 (if dim[0] >= 2) k = 0 .. dim[3]-1 (if dim[0] >= 3) The (x,y,z) coordinates refer to the CENTER of a voxel. In methods 2 and 3, the (x,y,z) axes refer to a subject-based coordinate system, with +x = Right +y = Anterior +z = Superior. This is a right-handed coordinate system. However, the exact direction these axes point with respect to the subject depends on qform_code (Method 2) and sform_code (Method 3). N.B.: The i index varies most rapidly, j index next, k index slowest. Thus, voxel (i,j,k) is stored starting at location (i + j*dim[1] + k*dim[1]*dim[2]) * (bitpix/8) into the dataset array. N.B.: The ANALYZE 7.5 coordinate system is +x = Left +y = Anterior +z = Superior which is a left-handed coordinate system. This backwardness is too difficult to tolerate, so this NIFTI-1 standard specifies the coordinate order which is most common in functional neuroimaging. N.B.: The 3 methods below all give the locations of the voxel centers in the (x,y,z) coordinate system. In many cases, programs will wish to display image data on some other grid. In such a case, the program will need to convert its desired (x,y,z) values into (i,j,k) values in order to extract (or interpolate) the image data. This operation would be done with the inverse transformation to those described below. N.B.: Method 2 uses a factor 'qfac' which is either -1 or 1; qfac is stored in the otherwise unused pixdim[0]. If pixdim[0]=0.0 (which should not occur), we take qfac=1. Of course, pixdim[0] is only used when reading a NIFTI-1 header, not when reading an ANALYZE 7.5 header. N.B.: The units of (x,y,z) can be specified using the xyzt_units field. METHOD 1 (the "old" way, used only when qform_code = 0): ------------------------------------------------------- The coordinate mapping from (i,j,k) to (x,y,z) is the ANALYZE 7.5 way. This is a simple scaling relationship: x = pixdim[1] * i y = pixdim[2] * j z = pixdim[3] * k No particular spatial orientation is attached to these (x,y,z) coordinates. (NIFTI-1 does not have the ANALYZE 7.5 orient field, which is not general and is often not set properly.) This method is not recommended, and is present mainly for compatibility with ANALYZE 7.5 files. METHOD 2 (used when qform_code > 0, which should be the "normal" case): --------------------------------------------------------------------- The (x,y,z) coordinates are given by the pixdim[] scales, a rotation matrix, and a shift. This method is intended to represent "scanner-anatomical" coordinates, which are often embedded in the image header (e.g., DICOM fields (0020,0032), (0020,0037), (0028,0030), and (0018,0050)), and represent the nominal orientation and location of the data. This method can also be used to represent "aligned" coordinates, which would typically result from some post-acquisition alignment of the volume to a standard orientation (e.g., the same subject on another day, or a rigid rotation to true anatomical orientation from the tilted position of the subject in the scanner). The formula for (x,y,z) in terms of header parameters and (i,j,k) is: [ x ] [ R11 R12 R13 ] [ pixdim[1] * i ] [ qoffset_x ] [ y ] = [ R21 R22 R23 ] [ pixdim[2] * j ] + [ qoffset_y ] [ z ] [ R31 R32 R33 ] [ qfac * pixdim[3] * k ] [ qoffset_z ] The qoffset_* shifts are in the NIFTI-1 header. Note that the center of the (i,j,k)=(0,0,0) voxel (first value in the dataset array) is just (x,y,z)=(qoffset_x,qoffset_y,qoffset_z). The rotation matrix R is calculated from the quatern_* parameters. This calculation is described below. The scaling factor qfac is either 1 or -1. The rotation matrix R defined by the quaternion parameters is "proper" (has determinant 1). This may not fit the needs of the data; for example, if the image grid is i increases from Left-to-Right j increases from Anterior-to-Posterior k increases from Inferior-to-Superior Then (i,j,k) is a left-handed triple. In this example, if qfac=1, the R matrix would have to be [ 1 0 0 ] [ 0 -1 0 ] which is "improper" (determinant = -1). [ 0 0 1 ] If we set qfac=-1, then the R matrix would be [ 1 0 0 ] [ 0 -1 0 ] which is proper. [ 0 0 -1 ] This R matrix is represented by quaternion [a,b,c,d] = [0,1,0,0] (which encodes a 180 degree rotation about the x-axis). METHOD 3 (used when sform_code > 0): ----------------------------------- The (x,y,z) coordinates are given by a general affine transformation of the (i,j,k) indexes: x = srow_x[0] * i + srow_x[1] * j + srow_x[2] * k + srow_x[3] y = srow_y[0] * i + srow_y[1] * j + srow_y[2] * k + srow_y[3] z = srow_z[0] * i + srow_z[1] * j + srow_z[2] * k + srow_z[3] The srow_* vectors are in the NIFTI_1 header. Note that no use is made of pixdim[] in this method. WHY 3 METHODS? -------------- Method 1 is provided only for backwards compatibility. The intention is that Method 2 (qform_code > 0) represents the nominal voxel locations as reported by the scanner, or as rotated to some fiducial orientation and location. Method 3, if present (sform_code > 0), is to be used to give the location of the voxels in some standard space. The sform_code indicates which standard space is present. Both methods 2 and 3 can be present, and be useful in different contexts (method 2 for displaying the data on its original grid; method 3 for displaying it on a standard grid). In this scheme, a dataset would originally be set up so that the Method 2 coordinates represent what the scanner reported. Later, a registration to some standard space can be computed and inserted in the header. Image display software can use either transform, depending on its purposes and needs. In Method 2, the origin of coordinates would generally be whatever the scanner origin is; for example, in MRI, (0,0,0) is the center of the gradient coil. In Method 3, the origin of coordinates would depend on the value of sform_code; for example, for the Talairach coordinate system, (0,0,0) corresponds to the Anterior Commissure. QUATERNION REPRESENTATION OF ROTATION MATRIX (METHOD 2) ------------------------------------------------------- The orientation of the (x,y,z) axes relative to the (i,j,k) axes in 3D space is specified using a unit quaternion [a,b,c,d], where a*a+b*b+c*c+d*d=1. The (b,c,d) values are all that is needed, since we require that a = sqrt(1.0-(b*b+c*c+d*d)) be nonnegative. The (b,c,d) values are stored in the (quatern_b,quatern_c,quatern_d) fields. The quaternion representation is chosen for its compactness in representing rotations. The (proper) 3x3 rotation matrix that corresponds to [a,b,c,d] is [ a*a+b*b-c*c-d*d 2*b*c-2*a*d 2*b*d+2*a*c ] R = [ 2*b*c+2*a*d a*a+c*c-b*b-d*d 2*c*d-2*a*b ] [ 2*b*d-2*a*c 2*c*d+2*a*b a*a+d*d-c*c-b*b ] [ R11 R12 R13 ] = [ R21 R22 R23 ] [ R31 R32 R33 ] If (p,q,r) is a unit 3-vector, then rotation of angle h about that direction is represented by the quaternion [a,b,c,d] = [cos(h/2), p*sin(h/2), q*sin(h/2), r*sin(h/2)]. Requiring a >= 0 is equivalent to requiring -Pi <= h <= Pi. (Note that [-a,-b,-c,-d] represents the same rotation as [a,b,c,d]; there are 2 quaternions that can be used to represent a given rotation matrix R.) To rotate a 3-vector (x,y,z) using quaternions, we compute the quaternion product [0,x',y',z'] = [a,b,c,d] * [0,x,y,z] * [a,-b,-c,-d] which is equivalent to the matrix-vector multiply [ x' ] [ x ] [ y' ] = R [ y ] (equivalence depends on a*a+b*b+c*c+d*d=1) [ z' ] [ z ] Multiplication of 2 quaternions is defined by the following: [a,b,c,d] = a*1 + b*I + c*J + d*K where I*I = J*J = K*K = -1 (I,J,K are square roots of -1) I*J = K J*K = I K*I = J J*I = -K K*J = -I I*K = -J (not commutative!) For example [a,b,0,0] * [0,0,0,1] = [0,0,-b,a] since this expands to (a+b*I)*(K) = (a*K+b*I*K) = (a*K-b*J). The above formula shows how to go from quaternion (b,c,d) to rotation matrix and direction cosines. Conversely, given R, we can compute the fields for the NIFTI-1 header by a = 0.5 * sqrt(1+R11+R22+R33) (not stored) b = 0.25 * (R32-R23) / a => quatern_b c = 0.25 * (R13-R31) / a => quatern_c d = 0.25 * (R21-R12) / a => quatern_d If a=0 (a 180 degree rotation), alternative formulas are needed. See the nifti1_io.c function mat44_to_quatern() for an implementation of the various cases in converting R to [a,b,c,d]. Note that R-transpose (= R-inverse) would lead to the quaternion [a,-b,-c,-d]. The choice to specify the qoffset_x (etc.) values in the final coordinate system is partly to make it easy to convert DICOM images to this format. The DICOM attribute "Image Position (Patient)" (0020,0032) stores the (Xd,Yd,Zd) coordinates of the center of the first voxel. Here, (Xd,Yd,Zd) refer to DICOM coordinates, and Xd=-x, Yd=-y, Zd=z, where (x,y,z) refers to the NIFTI coordinate system discussed above. (i.e., DICOM +Xd is Left, +Yd is Posterior, +Zd is Superior, whereas +x is Right, +y is Anterior , +z is Superior. ) Thus, if the (0020,0032) DICOM attribute is extracted into (px,py,pz), then qoffset_x = -px qoffset_y = -py qoffset_z = pz is a reasonable setting when qform_code=NIFTI_XFORM_SCANNER_ANAT. That is, DICOM's coordinate system is 180 degrees rotated about the z-axis from the neuroscience/NIFTI coordinate system. To transform between DICOM and NIFTI, you just have to negate the x- and y-coordinates. The DICOM attribute (0020,0037) "Image Orientation (Patient)" gives the orientation of the x- and y-axes of the image data in terms of 2 3-vectors. The first vector is a unit vector along the x-axis, and the second is along the y-axis. If the (0020,0037) attribute is extracted into the value (xa,xb,xc,ya,yb,yc), then the first two columns of the R matrix would be [ -xa -ya ] [ -xb -yb ] [ xc yc ] The negations are because DICOM's x- and y-axes are reversed relative to NIFTI's. The third column of the R matrix gives the direction of displacement (relative to the subject) along the slice-wise direction. This orientation is not encoded in the DICOM standard in a simple way; DICOM is mostly concerned with 2D images. The third column of R will be either the cross-product of the first 2 columns or its negative. It is possible to infer the sign of the 3rd column by examining the coordinates in DICOM attribute (0020,0032) "Image Position (Patient)" for successive slices. However, this method occasionally fails for reasons that I (RW Cox) do not understand. -----------------------------------------------------------------------------*/ /* [qs]form_code value: */ /* x,y,z coordinate system refers to: */ /*-----------------------*/ /*---------------------------------------*/ /*! \defgroup NIFTI1_XFORM_CODES \brief nifti1 xform codes to describe the "standard" coordinate system @{ */ /*! Arbitrary coordinates (Method 1). */ #define NIFTI_XFORM_UNKNOWN 0 /*! Scanner-based anatomical coordinates */ #define NIFTI_XFORM_SCANNER_ANAT 1 /*! Coordinates aligned to another file's, or to anatomical "truth". */ #define NIFTI_XFORM_ALIGNED_ANAT 2 /*! Coordinates aligned to Talairach- Tournoux Atlas; (0,0,0)=AC, etc. */ #define NIFTI_XFORM_TALAIRACH 3 /*! MNI 152 normalized coordinates. */ #define NIFTI_XFORM_MNI_152 4 /* @} */ /*---------------------------------------------------------------------------*/ /* UNITS OF SPATIAL AND TEMPORAL DIMENSIONS: ---------------------------------------- The codes below can be used in xyzt_units to indicate the units of pixdim. As noted earlier, dimensions 1,2,3 are for x,y,z; dimension 4 is for time (t). - If dim[4]=1 or dim[0] < 4, there is no time axis. - A single time series (no space) would be specified with - dim[0] = 4 (for scalar data) or dim[0] = 5 (for vector data) - dim[1] = dim[2] = dim[3] = 1 - dim[4] = number of time points - pixdim[4] = time step - xyzt_units indicates units of pixdim[4] - dim[5] = number of values stored at each time point Bits 0..2 of xyzt_units specify the units of pixdim[1..3] (e.g., spatial units are values 1..7). Bits 3..5 of xyzt_units specify the units of pixdim[4] (e.g., temporal units are multiples of 8). This compression of 2 distinct concepts into 1 byte is due to the limited space available in the 348 byte ANALYZE 7.5 header. The macros XYZT_TO_SPACE and XYZT_TO_TIME can be used to mask off the undesired bits from the xyzt_units fields, leaving "pure" space and time codes. Inversely, the macro SPACE_TIME_TO_XYZT can be used to assemble a space code (0,1,2,...,7) with a time code (0,8,16,32,...,56) into the combined value for xyzt_units. Note that codes are provided to indicate the "time" axis units are actually frequency in Hertz (_HZ), in part-per-million (_PPM) or in radians-per-second (_RADS). The toffset field can be used to indicate a nonzero start point for the time axis. That is, time point #m is at t=toffset+m*pixdim[4] for m=0..dim[4]-1. -----------------------------------------------------------------------------*/ /*! \defgroup NIFTI1_UNITS \brief nifti1 units codes to describe the unit of measurement for each dimension of the dataset @{ */ /*! NIFTI code for unspecified units. */ #define NIFTI_UNITS_UNKNOWN 0 /** Space codes are multiples of 1. **/ /*! NIFTI code for meters. */ #define NIFTI_UNITS_METER 1 /*! NIFTI code for millimeters. */ #define NIFTI_UNITS_MM 2 /*! NIFTI code for micrometers. */ #define NIFTI_UNITS_MICRON 3 /** Time codes are multiples of 8. **/ /*! NIFTI code for seconds. */ #define NIFTI_UNITS_SEC 8 /*! NIFTI code for milliseconds. */ #define NIFTI_UNITS_MSEC 16 /*! NIFTI code for microseconds. */ #define NIFTI_UNITS_USEC 24 /*** These units are for spectral data: ***/ /*! NIFTI code for Hertz. */ #define NIFTI_UNITS_HZ 32 /*! NIFTI code for ppm. */ #define NIFTI_UNITS_PPM 40 /*! NIFTI code for radians per second. */ #define NIFTI_UNITS_RADS 48 /* @} */ #undef XYZT_TO_SPACE #undef XYZT_TO_TIME #define XYZT_TO_SPACE(xyzt) ( (xyzt) & 0x07 ) #define XYZT_TO_TIME(xyzt) ( (xyzt) & 0x38 ) #undef SPACE_TIME_TO_XYZT #define SPACE_TIME_TO_XYZT(ss,tt) ( (((char)(ss)) & 0x07) \ | (((char)(tt)) & 0x38) ) /*---------------------------------------------------------------------------*/ /* MRI-SPECIFIC SPATIAL AND TEMPORAL INFORMATION: --------------------------------------------- A few fields are provided to store some extra information that is sometimes important when storing the image data from an FMRI time series experiment. (After processing such data into statistical images, these fields are not likely to be useful.) { freq_dim } = These fields encode which spatial dimension (1,2, or 3) { phase_dim } = corresponds to which acquisition dimension for MRI data. { slice_dim } = Examples: Rectangular scan multi-slice EPI: freq_dim = 1 phase_dim = 2 slice_dim = 3 (or some permutation) Spiral scan multi-slice EPI: freq_dim = phase_dim = 0 slice_dim = 3 since the concepts of frequency- and phase-encoding directions don't apply to spiral scan slice_duration = If this is positive, AND if slice_dim is nonzero, indicates the amount of time used to acquire 1 slice. slice_duration*dim[slice_dim] can be less than pixdim[4] with a clustered acquisition method, for example. slice_code = If this is nonzero, AND if slice_dim is nonzero, AND if slice_duration is positive, indicates the timing pattern of the slice acquisition. The following codes are defined: NIFTI_SLICE_SEQ_INC == sequential increasing NIFTI_SLICE_SEQ_DEC == sequential decreasing NIFTI_SLICE_ALT_INC == alternating increasing NIFTI_SLICE_ALT_DEC == alternating decreasing NIFTI_SLICE_ALT_INC2 == alternating increasing #2 NIFTI_SLICE_ALT_DEC2 == alternating decreasing #2 { slice_start } = Indicates the start and end of the slice acquisition { slice_end } = pattern, when slice_code is nonzero. These values are present to allow for the possible addition of "padded" slices at either end of the volume, which don't fit into the slice timing pattern. If there are no padding slices, then slice_start=0 and slice_end=dim[slice_dim]-1 are the correct values. For these values to be meaningful, slice_start must be non-negative and slice_end must be greater than slice_start. Otherwise, they should be ignored. The following table indicates the slice timing pattern, relative to time=0 for the first slice acquired, for some sample cases. Here, dim[slice_dim]=7 (there are 7 slices, labeled 0..6), slice_duration=0.1, and slice_start=1, slice_end=5 (1 padded slice on each end). slice index SEQ_INC SEQ_DEC ALT_INC ALT_DEC ALT_INC2 ALT_DEC2 6 : n/a n/a n/a n/a n/a n/a n/a = not applicable 5 : 0.4 0.0 0.2 0.0 0.4 0.2 (slice time offset 4 : 0.3 0.1 0.4 0.3 0.1 0.0 doesn't apply to 3 : 0.2 0.2 0.1 0.1 0.3 0.3 slices outside 2 : 0.1 0.3 0.3 0.4 0.0 0.1 the range 1 : 0.0 0.4 0.0 0.2 0.2 0.4 slice_start .. 0 : n/a n/a n/a n/a n/a n/a slice_end) The SEQ slice_codes are sequential ordering (uncommon but not unknown), either increasing in slice number or decreasing (INC or DEC), as illustrated above. The ALT slice codes are alternating ordering. The 'standard' way for these to operate (without the '2' on the end) is for the slice timing to start at the edge of the slice_start .. slice_end group (at slice_start for INC and at slice_end for DEC). For the 'ALT_*2' slice_codes, the slice timing instead starts at the first slice in from the edge (at slice_start+1 for INC2 and at slice_end-1 for DEC2). This latter acquisition scheme is found on some Siemens scanners. The fields freq_dim, phase_dim, slice_dim are all squished into the single byte field dim_info (2 bits each, since the values for each field are limited to the range 0..3). This unpleasantness is due to lack of space in the 348 byte allowance. The macros DIM_INFO_TO_FREQ_DIM, DIM_INFO_TO_PHASE_DIM, and DIM_INFO_TO_SLICE_DIM can be used to extract these values from the dim_info byte. The macro FPS_INTO_DIM_INFO can be used to put these 3 values into the dim_info byte. -----------------------------------------------------------------------------*/ #undef DIM_INFO_TO_FREQ_DIM #undef DIM_INFO_TO_PHASE_DIM #undef DIM_INFO_TO_SLICE_DIM #define DIM_INFO_TO_FREQ_DIM(di) ( ((di) ) & 0x03 ) #define DIM_INFO_TO_PHASE_DIM(di) ( ((di) >> 2) & 0x03 ) #define DIM_INFO_TO_SLICE_DIM(di) ( ((di) >> 4) & 0x03 ) #undef FPS_INTO_DIM_INFO #define FPS_INTO_DIM_INFO(fd,pd,sd) ( ( ( ((char)(fd)) & 0x03) ) | \ ( ( ((char)(pd)) & 0x03) << 2 ) | \ ( ( ((char)(sd)) & 0x03) << 4 ) ) /*! \defgroup NIFTI1_SLICE_ORDER \brief nifti1 slice order codes, describing the acquisition order of the slices @{ */ #define NIFTI_SLICE_UNKNOWN 0 #define NIFTI_SLICE_SEQ_INC 1 #define NIFTI_SLICE_SEQ_DEC 2 #define NIFTI_SLICE_ALT_INC 3 #define NIFTI_SLICE_ALT_DEC 4 #define NIFTI_SLICE_ALT_INC2 5 /* 05 May 2005: RWCox */ #define NIFTI_SLICE_ALT_DEC2 6 /* 05 May 2005: RWCox */ /* @} */ /*---------------------------------------------------------------------------*/ /* UNUSED FIELDS: ------------- Some of the ANALYZE 7.5 fields marked as ++UNUSED++ may need to be set to particular values for compatibility with other programs. The issue of interoperability of ANALYZE 7.5 files is a murky one -- not all programs require exactly the same set of fields. (Unobscuring this murkiness is a principal motivation behind NIFTI-1.) Some of the fields that may need to be set for other (non-NIFTI aware) software to be happy are: extents dbh.h says this should be 16384 regular dbh.h says this should be the character 'r' glmin, } dbh.h says these values should be the min and max voxel glmax } values for the entire dataset It is best to initialize ALL fields in the NIFTI-1 header to 0 (e.g., with calloc()), then fill in what is needed. -----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* MISCELLANEOUS C MACROS -----------------------------------------------------------------------------*/ /*.................*/ /*! Given a nifti_1_header struct, check if it has a good magic number. Returns NIFTI version number (1..9) if magic is good, 0 if it is not. */ #define NIFTI_VERSION(h) \ ( ( (h).magic[0]=='n' && (h).magic[3]=='\0' && \ ( (h).magic[1]=='i' || (h).magic[1]=='+' ) && \ ( (h).magic[2]>='1' && (h).magic[2]<='9' ) ) \ ? (h).magic[2]-'0' : 0 ) /*.................*/ /*! Check if a nifti_1_header struct says if the data is stored in the same file or in a separate file. Returns 1 if the data is in the same file as the header, 0 if it is not. */ #define NIFTI_ONEFILE(h) ( (h).magic[1] == '+' ) /*.................*/ /*! Check if a nifti_1_header struct needs to be byte swapped. Returns 1 if it needs to be swapped, 0 if it does not. */ #define NIFTI_NEEDS_SWAP(h) ( (h).dim[0] < 0 || (h).dim[0] > 7 ) /*.................*/ /*! Check if a nifti_1_header struct contains a 5th (vector) dimension. Returns size of 5th dimension if > 1, returns 0 otherwise. */ #define NIFTI_5TH_DIM(h) ( ((h).dim[0]>4 && (h).dim[5]>1) ? (h).dim[5] : 0 ) /*****************************************************************************/ /*=================*/ #ifdef __cplusplus } #endif /*=================*/ #endif /* _NIFTI_HEADER_ */ Rniftilib/src/Rnifti.c0000644000176000001440000016126512073250671014430 0ustar ripleyusers#include "nifti1_io.h" /* directly include I/O library functions */ #include "nifti1.h" #include #include //#include "International.h" extern char *gni_version; SEXP NIFTI_type_tag; #define SEXP2NIFTI(nim) ((TYPEOF(nim) != EXTPTRSXP || R_ExternalPtrTag(nim) != NIFTI_type_tag)?NULL:(nifti_image *)R_ExternalPtrAddr(nim)) SEXP Rnifti_image_setdatatype(SEXP nim, SEXP value); /* library(Rniftilib) a=nifti_image_read("C:\\ffmri_L2409-00001-00001-0.img") for(s in 1:(dim(a)[2])) image(a[1,s,,],col=gray(1:255/255)) for(s in 1:(dim(a)[3])) image(a[1,,s,],col=gray(1:255/255)) */ SEXP Rnifti_init(SEXP libpath) { NIFTI_type_tag = install("NIFTI_TYPE_TAG"); return R_NilValue; } char *Rnifti_attributes[] = { "qto.xyz", /* 0 */ "qto.ijk", /* 1 */ "sto.xyz", /* 2 */ "sto.ijk", /* 3 */ "toffset", /* 4 */ "descrip", /* 5 */ "fname", /* 6 */ "iname", /* 7 */ "slice.duration", /* 8 */ "qform.code", /* 9 */ "sform.code", /* 10 */ "quatern.b", /* 11 */ "quatern.c", /* 12 */ "quatern.d", /* 13 */ "qoffset.x", /* 14 */ "qoffset.y", /* 15 */ "qoffset.z", /* 16 */ "qfac", /* 17 */ "pixdim", /* 18 */ "nifti.type", /* 19 */ "sizeof.hdr", /* 20 */ "datatype", /* 21 */ "scl.slope", /* 22 nifti1: Data scaling: slope. analyze 7.5: float funused1; */ "scl.inter", /* 23 nifti1: Data scaling: offset. analyze 7.5: float funused2; */ "qto_xyz", /* 24 */ "qto_ijk", /* 25 */ "sto_xyz", /* 26 */ "sto_ijk", /* 27 */ "dim", /* 28 */ "nbyper", /* 29 */ "xyz_units", /* 30 */ "time_units", /* 31 */ NULL }; SEXP Rnifti_mat44_SEXP(mat44 *mat) { SEXP ret_val; int c,r; PROTECT(ret_val = NEW_NUMERIC(4*4)); for(r=0;r<4;++r) for(c=0;c<4;++c) NUMERIC_POINTER(ret_val)[r+c*4]=(double)(mat->m[r][c]); SEXP dim; PROTECT(dim=NEW_INTEGER(2)); INTEGER_POINTER(dim)[0]=4; INTEGER_POINTER(dim)[1]=4; SET_DIM(ret_val,dim); UNPROTECT(2); return ret_val; } void Rnifti_SEXP_mat44(SEXP val,mat44 *mat) { int c,r; PROTECT(val = AS_NUMERIC(val)); if(LENGTH(val)==16) { for(r=0;r<4;++r) for(c=0;c<4;++c) (mat->m[r][c])=(float)NUMERIC_POINTER(val)[r+c*4]; } else error("matrix must be 4x4\n"); UNPROTECT(1); } SEXP Rnifti_mat33_SEXP(mat33 *mat) { SEXP ret_val; int c,r; PROTECT(ret_val = NEW_NUMERIC(4*4)); for(r=0;r<3;++r) for(c=0;c<3;++c) NUMERIC_POINTER(ret_val)[r+c*4]=(double)mat->m[r][c]; SEXP dim; PROTECT(dim=NEW_INTEGER(2)); INTEGER_POINTER(dim)[0]=3; INTEGER_POINTER(dim)[1]=3; SET_DIM(ret_val,dim); UNPROTECT(2); return ret_val; } void Rnifti_SEXP_mat33(SEXP val,mat33 *mat) { int c,r; PROTECT(val = AS_NUMERIC(val)); if(LENGTH(val)==9) { for(r=0;r<3;++r) for(c=0;c<3;++c) (mat->m[r][c])=(float)NUMERIC_POINTER(val)[r+c*4]; } else error("matrix must be 3x3\n"); UNPROTECT(1); } SEXP Rnifti_float_SEXP(float val) { SEXP ret_val; PROTECT(ret_val=NEW_NUMERIC(1)); NUMERIC_POINTER(ret_val)[0]=val; UNPROTECT(1); return ret_val; } void Rnifti_SEXP_float(SEXP val_sexp, float *val) { PROTECT(val_sexp=AS_NUMERIC(val_sexp)); *val=(float)NUMERIC_POINTER(val_sexp)[0]; UNPROTECT(1); } SEXP Rnifti_int_SEXP(int val) { SEXP ret_val; PROTECT(ret_val=NEW_INTEGER(1)); INTEGER_POINTER(ret_val)[0]=val; UNPROTECT(1); return ret_val; } void Rnifti_SEXP_int(SEXP val_sexp, int *val) { PROTECT(val_sexp=AS_INTEGER(val_sexp)); *val=(int)INTEGER_POINTER(val_sexp)[0]; UNPROTECT(1); } void Rnifti_SEXP_short(SEXP val_sexp, short *val) { PROTECT(val_sexp=AS_INTEGER(val_sexp)); *val=(short)INTEGER_POINTER(val_sexp)[0]; UNPROTECT(1); } SEXP Rnifti_pchar_SEXP(const char* val) { SEXP ret_val; PROTECT(ret_val=NEW_CHARACTER(1)); if(val!=NULL) SET_STRING_ELT(ret_val, 0, mkChar(val)); else SET_STRING_ELT(ret_val, 0, mkChar("")); UNPROTECT(1); return ret_val; } void Rnifti_SEXP_pchar(SEXP val_sexp, char* val, int max_num) { PROTECT(val_sexp=AS_CHARACTER(val_sexp)); const char *pcstring = CHAR(CHARACTER_POINTER(val_sexp)[0]); if(strlen(pcstring)data == NULL ) { int ntot = nifti_get_volsize(pnim); pnim->data = (void *)calloc(1,ntot) ; /* create image memory */ if( pnim->data == NULL ) { error("** failed to alloc %d bytes for image data\n",(int)ntot); } } SEXP nim = R_MakeExternalPtr(pnim,NIFTI_type_tag, R_NilValue); R_RegisterCFinalizer(nim,(R_CFinalizer_t) Rnifti_image_free); /* set class attribute to nifti */ SEXP classattrib; PROTECT(classattrib = allocVector(STRSXP, 1)); SET_STRING_ELT(classattrib, 0, mkChar("nifti")); classgets(nim, classattrib); UNPROTECT(1); return nim; } SEXP Rnifti_image_alloc_data(SEXP nim) { int ntot=0; nifti_image *pnim=SEXP2NIFTI(nim); if(pnim != NULL) { if( pnim->data != NULL ) { free(pnim->data); pnim->data = NULL; } /*- if the data pointer is not yet set, get memory space for the image */ if( pnim->data == NULL ) { ntot = nifti_get_volsize(pnim); pnim->data = (void *)calloc(1,ntot) ; /* create image memory */ if( pnim->data == NULL ) { error("failed to alloc %d bytes for image data\n",(int)ntot); } } } return Rnifti_int_SEXP(ntot); } SEXP Rnifti_image_unload(SEXP nim) { nifti_image *pnim=SEXP2NIFTI(nim); nifti_image_unload( pnim ); return nim; } /* EXPERIMENTAL function ...*/ SEXP Rnifti_read_subregion_image(SEXP nim, SEXP start_index, SEXP region_index) { SEXP ret_val=R_NilValue; int i,region_size_in_voxel=0,region_size_in_bytes=0; void *data=NULL; SEXP start_index_sexp,region_index_sexp; nifti_image *pnim=SEXP2NIFTI(nim); PROTECT(start_index_sexp=AS_INTEGER(start_index)); PROTECT(region_index_sexp=AS_INTEGER(region_index)); if(LENGTH(start_index_sexp)dim[0] || LENGTH(region_index)dim[0]) { UNPROTECT(2); error("ERROR: start_index and region_index must have length >= no. of image dimensions!"); return ret_val; } int *start_index_int=INTEGER_POINTER(start_index_sexp); int *region_index_int=INTEGER_POINTER(region_index_sexp); for(i=0;idim[0];++i) region_size_in_voxel=region_index_int[i]*region_size_in_voxel; region_size_in_bytes=region_size_in_voxel*pnim->nbyper; switch(pnim->datatype) { case DT_NONE: case DT_BINARY: case DT_UNSIGNED_CHAR: PROTECT(ret_val=NEW_CHARACTER(region_size_in_voxel)); data=(void*)CHARACTER_POINTER(ret_val); break; case DT_SIGNED_INT: PROTECT(ret_val=NEW_INTEGER(region_size_in_voxel)); data=(void*)INTEGER_POINTER(ret_val); break; case DT_DOUBLE: PROTECT(ret_val=NEW_NUMERIC(region_size_in_voxel)); data=(void*)NUMERIC_POINTER(ret_val); break; case DT_INT8: case DT_UINT16: case DT_SIGNED_SHORT: case DT_UINT32: case DT_INT64: case DT_UINT64: case DT_FLOAT: case DT_FLOAT128: case DT_COMPLEX: case DT_COMPLEX128: case DT_COMPLEX256: case DT_RGB: case DT_RGBA32: default: warning("Unsupported or unknown data type!"); break; } if(data!=NULL) { if(region_size_in_bytes != nifti_read_subregion_image(pnim, start_index_int, region_index_int,&data )) error("ERROR: calculated region size different from returned region size!"); UNPROTECT(3); // unprotect start_index_sexp and region_index_sexp and ret_val } else UNPROTECT(2); // unprotect start_index_sexp and region_index_sexp return ret_val; } SEXP Rnifti_set_filenames(SEXP nim, SEXP prefix, SEXP check, SEXP set_byte_order) { SEXP ret_val=Rnifti_int_SEXP(1); nifti_image *pnim=SEXP2NIFTI(nim); if(pnim!=NULL) { int icheck; int iset_byte_order; char prefix_buffer[500]; Rnifti_SEXP_pchar(prefix, prefix_buffer, 500); Rnifti_SEXP_int(check, &icheck); Rnifti_SEXP_int(set_byte_order, &iset_byte_order); ret_val = Rnifti_int_SEXP(nifti_set_filenames( pnim, prefix_buffer, icheck, iset_byte_order)); } return ret_val; } SEXP Rnifti_image_listattributes(SEXP nim) { SEXP Rstring; PROTECT( Rstring= NEW_CHARACTER(9)); int iIndex; for(iIndex=0;Rnifti_attributes[iIndex]!=NULL;++iIndex) SET_STRING_ELT(Rstring, iIndex, mkChar(Rnifti_attributes[iIndex])); UNPROTECT(1); return Rstring; } SEXP Rnifti_image_setattribute(SEXP nim, SEXP sym, SEXP value) { nifti_image *pnim=SEXP2NIFTI(nim); if(pnim!=NULL) { SEXP Rstring; PROTECT( Rstring= AS_CHARACTER(sym)); int iIndex; for(iIndex=0;Rnifti_attributes[iIndex]!=NULL;++iIndex) if(strcmp(Rnifti_attributes[iIndex],CHAR(STRING_ELT(Rstring,0)))==0) break; UNPROTECT(1); switch(iIndex) { case 0: /*qto.xyz*/ //Rnifti_SEXP_mat44(value,&(pnim->qto_xyz)); error("set attribute qto.xyz not implemented use qto_xyz!"); break; case 1: /*qto.ijk*/ //Rnifti_SEXP_mat44(value,&(pnim->qto_ijk)); break; error("set attribute qto.ijk not implemented use qto_ijk!"); break; case 2: /*sto.xyz*/ //Rnifti_SEXP_mat44(value,&(pnim->sto_xyz)); break; error("set attribute sto.xyz not implemented use sto_xyz!"); break; case 3: /*sto.ijk*/ //Rnifti_SEXP_mat44(value,&(pnim->sto_ijk)); break; error("set attribute sto.ijk not implemented use sto_ijk!"); break; case 24: /*qto_xyz*/ Rnifti_SEXP_mat44(value,&(pnim->qto_xyz)); break; case 25: /*qto_ijk*/ Rnifti_SEXP_mat44(value,&(pnim->qto_ijk)); break; case 26: /*sto_xyz*/ Rnifti_SEXP_mat44(value,&(pnim->sto_xyz)); break; case 27: /*sto_ijk*/ Rnifti_SEXP_mat44(value,&(pnim->sto_ijk)); break; case 4: /*toffset*/ Rnifti_SEXP_float(value,&pnim->toffset); break; case 5: /*descrip*/ Rnifti_SEXP_pchar(value,pnim->descrip,80); break; case 6: /*fname*/ /* Rnifti_SEXP_pchar(value,pnim->fname,0); break; */ warning("Can not set this attribute directly! Please use the nifti.set.filenames function.\n"); break; case 7: /*iname*/ /* Rnifti_SEXP_pchar(value,pnim->iname,0); break; */ warning("Can not set this attribute directly! Please use the nifti.set.filenames function.\n"); break; case 8: /*slice_duration*/ Rnifti_SEXP_float(value,&(pnim->slice_duration)); break; case 9: /* qform.code */ Rnifti_SEXP_int(value, &(pnim->qform_code)); break; case 10: /* sform.code */ Rnifti_SEXP_int(value, &(pnim->sform_code)); break; case 11: /* quatern_b 11 */ Rnifti_SEXP_float(value,&(pnim->quatern_b)); break; case 12: /* quatern_c 12 */ Rnifti_SEXP_float(value,&(pnim->quatern_c)); break; case 13: /* quatern_d 13 */ Rnifti_SEXP_float(value,&(pnim->quatern_d)); break; case 14: /* qoffset_x 14 */ Rnifti_SEXP_float(value,&(pnim->qoffset_x)); break; case 15: /* qoffset_y 15 */ Rnifti_SEXP_float(value,&(pnim->qoffset_y)); break; case 16: /* qoffset_z 16 */ Rnifti_SEXP_float(value,&(pnim->qoffset_z)); break; case 17: /* qfac 17 */ Rnifti_SEXP_float(value,&(pnim->qfac)); break; case 18: /* pixdim 18 */ if(length(value)<=pnim->dim[0]) { int iIndex; PROTECT(value=AS_NUMERIC(value)); for(iIndex=0;iIndexpixdim[iIndex+1]=NUMERIC_POINTER(value)[iIndex]; } UNPROTECT(1); } else error("Length of pixdim greater than number of dimensions (dim[0])\n"); break; case 19: /* nifti_type 19 */ if(IS_NUMERIC(value)) { Rnifti_SEXP_int(value,&pnim->nifti_type); } else error("Only nummeric values are allowed to set nifti_type.\n"); break; case 21: /* datatype */ if(IS_NUMERIC(value)) { /*SEXP_to_int(value,&pnim->datatype);*/ Rnifti_image_setdatatype(nim, value); } else error("Only nummeric values are allowed to set nifti_datatype.\n"); break; case 22: /* scl_slope nifti1: Data scaling: slope. analyze 7.5: float funused1 */ if(IS_NUMERIC(value)) { Rnifti_SEXP_float(value,&(pnim->scl_slope)); } else error("Only nummeric values are allowed to set scl_slope.\n"); break; case 23: /* scl_inter nifti1: Data scaling: offset. analyze 7.5: float funused2 */ if(IS_NUMERIC(value)) { Rnifti_SEXP_float(value,&(pnim->scl_inter)); } else error("Only nummeric values are allowed to set scl_inter.\n"); break; case 28: /* dim */ PROTECT(value = AS_INTEGER(value)); if(length(value)>1 && length(value)<=7) { int iIndex; pnim->dim[0]=length(value); for(iIndex=0;iIndexdim[iIndex+1]=INTEGER_POINTER(value)[iIndex]; } // correct dependend structure entries nifti_update_dims_from_array(pnim); // correct size of data array if necessary if( pnim->data != NULL ) Rnifti_image_alloc_data(nim); } else error("Length of vector not compatible with the number of dimensions.\n"); UNPROTECT(1); break; case 30: /* xyz_units */ if((IS_NUMERIC(value) || IS_INTEGER(value)) && length(value)==1) { PROTECT(value = AS_INTEGER(value)); pnim->xyz_units=INTEGER_POINTER(value)[0]; UNPROTECT(1); } else error("Length of input vector not compatible with xyz_units.\n"); break; case 31: /* time_units */ if((IS_NUMERIC(value) || IS_INTEGER(value)) && length(value)==1) { PROTECT(value = AS_INTEGER(value)); pnim->time_units=INTEGER_POINTER(value)[0]; UNPROTECT(1); } else error("Length of input vector not compatible with time_units.\n"); break; default: error("Rnifti_image_setattribute: unknown attribute\n"); break; } //Rprintf("symbol: %d\n",is_symbol(sym)); } else error("Rnifti_image_setattribute: not a pointer to a nifti object.\n"); return nim; } SEXP Rnifti_image_getattribute(SEXP nim, SEXP sym) { SEXP ret_val=R_NilValue; nifti_image *pnim=SEXP2NIFTI(nim); if(pnim!=NULL) { SEXP Rstring; PROTECT( Rstring= AS_CHARACTER(sym)); int iIndex; for(iIndex=0;Rnifti_attributes[iIndex]!=NULL;++iIndex) if(strcmp(Rnifti_attributes[iIndex],CHAR(STRING_ELT(Rstring,0)))==0) break; UNPROTECT(1); switch(iIndex) { /* R comaptible transformation matrices */ case 0: /*qto.xyz*/ // old: return Rnifti_mat44_SEXP(&(pnim->qto_xyz)); break; { // generate a matrix compatible with R indexing (voxel start index at 1) mat44 Rqto_xyz; for(int r=0;r<4;++r) { for(int c=0;c<4;++c) { Rqto_xyz.m[r][c]=pnim->qto_xyz.m[r][c]; } Rqto_xyz.m[r][3]=Rqto_xyz.m[r][3]-Rqto_xyz.m[r][0]-Rqto_xyz.m[r][1]-Rqto_xyz.m[r][2]; } return Rnifti_mat44_SEXP(&Rqto_xyz); } break; case 1: /*qto.ijk*/ // old: return Rnifti_mat44_SEXP(&(pnim->qto_ijk)); break; { // generate a matrix compatible with R indexing (voxel start index at 1) mat44 Rqto_ijk; for(int r=0;r<3;++r) { for(int c=0;c<4;++c) { Rqto_ijk.m[r][c]=pnim->qto_ijk.m[r][c]+pnim->qto_ijk.m[3][c]; } } for(int c=0;c<4;++c) { Rqto_ijk.m[3][c]=pnim->qto_ijk.m[3][c]; } return Rnifti_mat44_SEXP(&Rqto_ijk); } break; case 2: /*sto.xyz*/ // old: return Rnifti_mat44_SEXP(&(pnim->sto_xyz)); break; { // generate a matrix compatible with R indexing (voxel start index at 1) mat44 Rsto_xyz; for(int r=0;r<4;++r) { for(int c=0;c<4;++c) { Rsto_xyz.m[r][c]=pnim->sto_xyz.m[r][c]; } Rsto_xyz.m[r][3]=Rsto_xyz.m[r][3]-Rsto_xyz.m[r][0]-Rsto_xyz.m[r][1]-Rsto_xyz.m[r][2]; } return Rnifti_mat44_SEXP(&Rsto_xyz); } break; case 3: /*sto.ijk*/ // old: return Rnifti_mat44_SEXP(&(pnim->sto_ijk)); break; { // generate a matrix compatible with R indexing (voxel index start at 1) mat44 Rsto_ijk; for(int r=0;r<3;++r) { for(int c=0;c<4;++c) { Rsto_ijk.m[r][c]=pnim->sto_ijk.m[r][c]+pnim->sto_ijk.m[3][c]; } } for(int c=0;c<4;++c) { Rsto_ijk.m[3][c]=pnim->sto_ijk.m[3][c]; } return Rnifti_mat44_SEXP(&Rsto_ijk); } break; /* C comaptible transformation matrices (voxel index start at 0)*/ case 24: /*qto_xyz*/ return Rnifti_mat44_SEXP(&(pnim->qto_xyz)); break; case 25: /*qto_ijk*/ return Rnifti_mat44_SEXP(&(pnim->qto_ijk)); break; case 26: /*sto_xyz*/ return Rnifti_mat44_SEXP(&(pnim->sto_xyz)); break; case 27: /*sto_ijk*/ return Rnifti_mat44_SEXP(&(pnim->sto_ijk)); break; case 4: /*toffset*/ return Rnifti_float_SEXP(pnim->toffset); break; case 5: /*descrip*/ return Rnifti_pchar_SEXP(pnim->descrip); break; case 6: /*fname*/ return Rnifti_pchar_SEXP(pnim->fname); break; case 7: /*iname*/ return Rnifti_pchar_SEXP(pnim->iname); break; case 8: /*slice_duration*/ return Rnifti_float_SEXP(pnim->slice_duration); break; case 9: /* qform_code */ switch(pnim->qform_code) { case NIFTI_XFORM_UNKNOWN: /*! Arbitrary coordinates (Method 1). */ return Rnifti_pchar_SEXP("NIFTI.XFORM.UNKNOWN"); break; case NIFTI_XFORM_SCANNER_ANAT: /*! Scanner-based anatomical coordinates */ return Rnifti_pchar_SEXP("NIFTI.XFORM.SCANNER_ANAT"); break; case NIFTI_XFORM_ALIGNED_ANAT: /*! Coordinates aligned to another file's, or to anatomical "truth". */ return Rnifti_pchar_SEXP("NIFTI.XFORM.ALIGNED_ANAT"); break; case NIFTI_XFORM_TALAIRACH: /*! Coordinates aligned to Talairach- Tournoux Atlas; (0,0,0)=AC, etc. */ return Rnifti_pchar_SEXP("NIFTI.XFORM.TALAIRACH"); break; case NIFTI_XFORM_MNI_152: /*! MNI 152 normalized coordinates. */ return Rnifti_pchar_SEXP("NIFTI.XFORM.MNI.152"); break; default: { char buffer[100]; snprintf(buffer,100,"qform code: %d",pnim->qform_code); return Rnifti_pchar_SEXP(buffer); } break; } break; case 10: /* sform_code */ switch(pnim->sform_code) { case NIFTI_XFORM_UNKNOWN: /*! Arbitrary coordinates (Method 1). */ return Rnifti_pchar_SEXP("NIFTI.XFORM.UNKNOWN"); break; case NIFTI_XFORM_SCANNER_ANAT: /*! Scanner-based anatomical coordinates */ return Rnifti_pchar_SEXP("NIFTI.XFORM.SCANNER_ANAT"); break; case NIFTI_XFORM_ALIGNED_ANAT: /*! Coordinates aligned to another file's, or to anatomical "truth". */ return Rnifti_pchar_SEXP("NIFTI.XFORM.ALIGNED.ANAT"); break; case NIFTI_XFORM_TALAIRACH: /*! Coordinates aligned to Talairach- Tournoux Atlas; (0,0,0)=AC, etc. */ return Rnifti_pchar_SEXP("NIFTI.XFORM.TALAIRACH"); break; case NIFTI_XFORM_MNI_152: /*! MNI 152 normalized coordinates. */ return Rnifti_pchar_SEXP("NIFTI.XFORM.MNI.152"); break; default: { char buffer[100]; snprintf(buffer,100,"qform code: %d",pnim->qform_code); return Rnifti_pchar_SEXP(buffer); } break; } break; case 11: /* quatern_b 11 */ return Rnifti_float_SEXP(pnim->quatern_b); break; case 12: /* quatern_c 12 */ return Rnifti_float_SEXP(pnim->quatern_c); break; case 13: /* quatern_d 13 */ return Rnifti_float_SEXP(pnim->quatern_d); break; case 14: /* qoffset_x 14 */ return Rnifti_float_SEXP(pnim->qoffset_x); break; case 15: /* qoffset_y 15 */ return Rnifti_float_SEXP(pnim->qoffset_y); break; case 16: /* qoffset_z 16 */ return Rnifti_float_SEXP(pnim->qoffset_z); break; case 17: /* qfac 17 */ return Rnifti_float_SEXP(pnim->qfac); break; case 18: /* pixdim 18 */ if(pnim->dim[0]<8) { PROTECT(ret_val=NEW_NUMERIC(pnim->dim[0])); for(iIndex=0;iIndexdim[0];++iIndex) { NUMERIC_POINTER(ret_val)[iIndex]=pnim->pixdim[iIndex+1]; } UNPROTECT(1); } else error("number of dimensions (dim[0]) > 7!\n"); break; case 19: /* nifti_type 19 */ switch(pnim->nifti_type) { case NIFTI_FTYPE_ANALYZE: return Rnifti_pchar_SEXP("NIFTI.FTYPE.ANALYZE"); break; case NIFTI_FTYPE_NIFTI1_1: return Rnifti_pchar_SEXP("NIFTI.FTYPE.NIFTI1.1"); break; case NIFTI_FTYPE_NIFTI1_2: return Rnifti_pchar_SEXP("NIFTI.FTYPE.NIFTI1.2"); break; case NIFTI_FTYPE_ASCII: return Rnifti_pchar_SEXP("NIFTI.FTYPE.ASCII"); break; default: return Rnifti_pchar_SEXP("NIFTI.FTYPE.UNKNOWN"); break; } break; case 20: /* sizeof_hdr 20 */ { struct nifti_1_header hdr = nifti_convert_nim2nhdr(pnim); return Rnifti_int_SEXP(hdr.sizeof_hdr); } break; case 21: /* datatype */ return Rnifti_int_SEXP(pnim->datatype); break; case 22: /* scl_slope nifti1: Data scaling: slope. analyze 7.5: float funused1 */ return Rnifti_float_SEXP(pnim->scl_slope); break; case 23: /* scl_inter nifti1: Data scaling: offset. analyze 7.5: float funused2 */ return Rnifti_float_SEXP(pnim->scl_inter); break; case 28: /* dim */ if(pnim->dim[0]>0 && pnim->dim[0]<8) { PROTECT(ret_val=NEW_INTEGER(pnim->dim[0])); for(iIndex=0;iIndexdim[0];++iIndex) { INTEGER_POINTER(ret_val)[iIndex]=pnim->dim[iIndex+1]; } UNPROTECT(1); } else error("Rnifti_image_getattribute: incorrect number of dimensions in dim[0]!\n"); break; case 29: /* nbyper */ return Rnifti_int_SEXP(pnim->nbyper); break; case 30: /* xyz_units */ return Rnifti_int_SEXP(pnim->xyz_units); break; case 31: /* time_units */ return Rnifti_int_SEXP(pnim->time_units); break; default: error("Rnifti_image_getattribute: unknown symbol\n"); break; } //Rprintf("symbol: %d\n",is_symbol(sym)); } else error("Rnifti_image_getattribute: not a pointer to a nifti object.\n"); return ret_val; } /** @brief Copy the nifti_image structure, without data. Duplicate the structure, including fname, iname and extensions. Leave the data pointer as NULL. */ SEXP Rnifti_image_copy_info(SEXP nim) { SEXP ret_val=R_NilValue; nifti_image *pnim=SEXP2NIFTI(nim); if(pnim!=NULL) { nifti_image *pnew_nim=nifti_copy_nim_info(pnim); ret_val = R_MakeExternalPtr(pnew_nim,NIFTI_type_tag, R_NilValue); R_RegisterCFinalizer(ret_val,(R_CFinalizer_t) Rnifti_image_free); // set class attribute to nifti SEXP classattrib; PROTECT(classattrib = allocVector(STRSXP, 1)); SET_STRING_ELT(classattrib, 0, mkChar("nifti")); classgets(ret_val, classattrib); UNPROTECT(1); } else error("nifti_image_copy_info: object is not a nifti image"); return ret_val; } SEXP Rnifti_image_read(SEXP file, SEXP read_data, SEXP rmNaN) { nifti_image *pnim; PROTECT(read_data = AS_INTEGER(read_data)); PROTECT(file = AS_CHARACTER(file)); PROTECT(rmNaN = AS_LOGICAL(rmNaN)); if(!isString(file) || length(file) != 1) { error("Rnifti_image_read: file is not a single string\n"); return R_NilValue; } if(!isLogical(rmNaN) || length(rmNaN) != 1) { error("Rnifti_image_read: rm.NaN is not a single logical\n"); return R_NilValue; } int int_rmNaN = (int)(LOGICAL_POINTER(rmNaN)[0]); if(int_rmNaN<0) { error("Rnifti_image_read: rm.NaN is not a valid logical\n"); return R_NilValue; } if(length(read_data) != 1) { error("Rnifti_image_read: read_data is not a single integer\n"); return R_NilValue; } int *piread_data = INTEGER_POINTER(read_data); const char *pcfilename = CHAR(STRING_ELT(file , 0)); pnim = nifti_image_read_NaN( pcfilename , piread_data[0], int_rmNaN ) ; if(pnim==NULL) { error("Rnifti_image_read: Can not open file \"%s\"",pcfilename); UNPROTECT(3); return R_NilValue; } SEXP nim = R_MakeExternalPtr(pnim,NIFTI_type_tag, R_NilValue); R_RegisterCFinalizer(nim,(R_CFinalizer_t) Rnifti_image_free); // set class attribute to PAC::ImageBase SEXP classattrib; PROTECT(classattrib = allocVector(STRSXP, 1)); SET_STRING_ELT(classattrib, 0, mkChar("nifti")); classgets(nim, classattrib); UNPROTECT(4); return nim; } SEXP Rnifti_image_write(SEXP nim) { nifti_image *pnim=SEXP2NIFTI(nim); if(pnim!=NULL) { nifti_image_write(pnim); } return R_NilValue; } /*SEXP Rnifti_image_getdim(SEXP nim) { SEXP ret_val=R_NilValue; nifti_image *pnim=SEXP2NIFTI(nim); if(pnim!=NULL) { int i; PROTECT(ret_val = NEW_INTEGER(pnim->dim[0])); for(i=0;idim[0];++i) INTEGER(ret_val)[i]=pnim->dim[i+1]; UNPROTECT(1); } return ret_val; }*/ SEXP Rnifti_image_getpixel2(SEXP sexp_args) { SEXP ret_val=R_NilValue; // skip function name sexp_args = CDR(sexp_args); // check first argument (should be a nifti object) if(sexp_args == R_NilValue) { warning("First argument must be a nifti object."); return ret_val; } // grab nifti object SEXP nim = CAR(sexp_args); nifti_image *pnim=SEXP2NIFTI(nim); if(pnim!=NULL) { int i; for(i = 0; sexp_args != R_NilValue; i++) { Rprintf("arg %04d: ",i); SEXP value = CAR(sexp_args); if(value == NULL_USER_OBJECT) Rprintf("NULL"); if(IS_LOGICAL(value) && LENGTH(value)>0) Rprintf("%s ",LOGICAL_POINTER(value)[0]?"TRUE":"FALSE"); if(IS_NUMERIC(value) && LENGTH(value)>0) Rprintf("%f ",NUMERIC_POINTER(value)[0]); if(IS_INTEGER(value) && LENGTH(value)>0) Rprintf("%d ",INTEGER_POINTER(value)[0]); if(IS_CHARACTER(value) && LENGTH(value)>0) { Rprintf("%s ",CHAR(STRING_ELT(value , 0))); } // the name of the argument { SEXP printname = PRINTNAME(TAG(sexp_args)); if(printname != NULL_USER_OBJECT) Rprintf(" (%s) ",CHAR(printname)); } Rprintf("\n"); sexp_args = CDR(sexp_args); } } else warning("First argument must be a nifti object."); return ret_val; } #define REALDIM(iDim) ((iDim<(pnim->dim[0]))?pnim->dim[iDim+1]:1) SEXP Rnifti_image_getpixel(SEXP nim, SEXP sexp_x, SEXP sexp_y, SEXP sexp_z, SEXP sexp_t, SEXP sexp_dim5, SEXP sexp_dim6, SEXP sexp_dim7) { SEXP ret_val=R_NilValue; char buffer[10]; nifti_image *pnim=SEXP2NIFTI(nim); if(IS_LOGICAL(sexp_x) || IS_LOGICAL(sexp_y) || IS_LOGICAL(sexp_z) || IS_LOGICAL(sexp_t) || IS_LOGICAL(sexp_dim5) || IS_LOGICAL(sexp_dim6) || IS_LOGICAL(sexp_dim7)) { error("logical indices are not supported yet!"); return nim; } if(pnim!=NULL) { SEXP coord[7]; PROTECT(coord[0] = AS_INTEGER(sexp_x)); PROTECT(coord[1] = AS_INTEGER(sexp_y)); PROTECT(coord[2] = AS_INTEGER(sexp_z)); PROTECT(coord[3] = AS_INTEGER(sexp_t)); PROTECT(coord[4] = AS_INTEGER(sexp_dim5)); PROTECT(coord[5] = AS_INTEGER(sexp_dim6)); PROTECT(coord[6] = AS_INTEGER(sexp_dim7)); int iDim,outdim=0; int *iCoord[7]; // determine number of dimensions in output matrix for(iDim=0;iDim<7;++iDim) { if(LENGTH(coord[iDim])>1) outdim++; iCoord[iDim]=INTEGER(coord[iDim]); } // check if indices are valid (out of bounds?) int iCoordCounter; for(iDim=0;iDim<7;++iDim) for(iCoordCounter=0;iCoordCounter=REALDIM(iDim)) { error("nifti: index out of range (dimension %d index %d dim: %d) \n",iDim,iCoord[iDim][iCoordCounter],REALDIM(iDim)); UNPROTECT(7); return nim; } if(pnim->datatype==DT_RGB || pnim->datatype==DT_RGBA32) PROTECT(ret_val = NEW_CHARACTER(LENGTH(sexp_x)*LENGTH(sexp_y)*LENGTH(sexp_z)*LENGTH(sexp_t))); else PROTECT(ret_val = NEW_NUMERIC(LENGTH(sexp_x)*LENGTH(sexp_y)*LENGTH(sexp_z)*LENGTH(sexp_t))); int iIndex[7], iTOffset=0, iSOffset=0; /* do type checking outside the main loop to speedup processing...*/ switch(pnim->datatype) { /* uchar (8 bits) */ case DT_UNSIGNED_CHAR: for(iIndex[6]=0;iIndex[6]dim[1] + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6]; NUMERIC_POINTER(ret_val)[iTOffset] = (double)((unsigned char*)pnim->data)[iSOffset]; ++iTOffset; } break; /* signed char (8 bits) */ case DT_INT8: for(iIndex[6]=0;iIndex[6]dim[1] + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6]; NUMERIC_POINTER(ret_val)[iTOffset] = (double)((signed char*)pnim->data)[iSOffset]; ++iTOffset; } break; /* unsigned short (16 bits) */ case DT_UINT16: for(iIndex[6]=0;iIndex[6]dim[1] + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6]; NUMERIC_POINTER(ret_val)[iTOffset] = (double)((unsigned short*)pnim->data)[iSOffset]; ++iTOffset; } break; /* signed short (16 bits) */ case DT_SIGNED_SHORT: for(iIndex[6]=0;iIndex[6]dim[1] + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6]; NUMERIC_POINTER(ret_val)[iTOffset] = (double)((short*)pnim->data)[iSOffset]; ++iTOffset; } break; /* unsigned int (32 bits) */ case DT_UINT32: for(iIndex[6]=0;iIndex[6]dim[1] + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6]; NUMERIC_POINTER(ret_val)[iTOffset] = (double)((unsigned int*)pnim->data)[iSOffset]; ++iTOffset; } break; /* signed int (32 bits) */ case DT_SIGNED_INT: for(iIndex[6]=0;iIndex[6]dim[1] + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6]; NUMERIC_POINTER(ret_val)[iTOffset] = (double)((int*)pnim->data)[iSOffset]; ++iTOffset; } break; /* float (32 bits) */ case DT_FLOAT: for(iIndex[6]=0;iIndex[6]dim[1] + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6]; NUMERIC_POINTER(ret_val)[iTOffset] = (double)((float*)pnim->data)[iSOffset]; ++iTOffset; } break; /* double (64 bits) */ case DT_DOUBLE: for(iIndex[6]=0;iIndex[6]dim[1] + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6]; NUMERIC_POINTER(ret_val)[iTOffset] = (double)((double*)pnim->data)[iSOffset]; ++iTOffset; } break; /* rgb (24 bits) */ case DT_RGB: for(iIndex[6]=0;iIndex[6]dim[1] + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6]; sprintf(buffer,"#%02X%02X%02X",((unsigned char*)pnim->data)[iSOffset*3],((unsigned char*)pnim->data)[iSOffset*3+1],((unsigned char*)pnim->data)[iSOffset*3+2]); SET_STRING_ELT(ret_val, iTOffset, mkChar(buffer)); ++iTOffset; } break; /* rgba (32 bits) */ case DT_RGBA32: for(iIndex[6]=0;iIndex[6]dim[1] + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6]; sprintf(buffer,"#%02X%02X%02X%02X",((unsigned char*)pnim->data)[iSOffset*4],((unsigned char*)pnim->data)[iSOffset*4+1],((unsigned char*)pnim->data)[iSOffset*4+2],((unsigned char*)pnim->data)[iSOffset*4+3]); SET_STRING_ELT(ret_val, iTOffset, mkChar(buffer)); ++iTOffset; } break; default: warning("unsupported data format (identifier %d)",pnim->datatype); } /*Rprintf("outdim=%d\n",outdim);*/ /* set the dimension attribute */ if(outdim>1) { SEXP dim; PROTECT(dim=NEW_INTEGER(outdim)); int iDimCount=0; for(iDim=0;iDim<7;++iDim) { /*Rprintf("length[%d]=%d\n",iDim,LENGTH(coord[iDim]));*/ if(LENGTH(coord[iDim])>1) { INTEGER_POINTER(dim)[iDimCount++]=LENGTH(coord[iDim]); } } SET_DIM(ret_val,dim); UNPROTECT(1); } UNPROTECT(8); } return ret_val; } SEXP Rnifti_image_printinfo(SEXP nim) { int iIndex; SEXP ret_val=R_NilValue; nifti_image *pnim=SEXP2NIFTI(nim); if(pnim!=NULL) { Rprintf("dimension: "); for(iIndex=0;iIndexdim[0];++iIndex) Rprintf("%d ",pnim->dim[iIndex+1]); Rprintf("\n"); Rprintf("dimensions: freq = %d, phase = %d, slice = %d\n", pnim->freq_dim, pnim->phase_dim, pnim->slice_dim); if(pnim->qform_code!=NIFTI_XFORM_UNKNOWN) { int icod, jcod, kcod; nifti_mat44_to_orientation( pnim->qto_xyz , &icod, &jcod, &kcod ); Rprintf("i orientation (voxel x-axis): %s\n",nifti_orientation_string(icod)); Rprintf("j orientation (voxel y-axis): %s\n",nifti_orientation_string(jcod)); Rprintf("k orientation (voxel z-axis): %s\n",nifti_orientation_string(kcod)); } int c; Rprintf("number of nifti ext. : %d\n",pnim->num_ext); for (c = 0; c < pnim->num_ext; c++ ) { Rprintf("%d] size: %d code: %d",c,pnim->ext_list[c].esize,pnim->ext_list[c].ecode); switch(pnim->ext_list[c].ecode) { case NIFTI_ECODE_IGNORE: Rprintf("(ignore /unknown)\n"); break; case NIFTI_ECODE_DICOM: Rprintf("(raw DICOM attributes)\n"); break; case NIFTI_ECODE_AFNI: Rprintf("(Robert W Cox: http://afni.nimh.nih.gov/afni)\n"); break; case NIFTI_ECODE_COMMENT: Rprintf("(plain ASCII text)\n"); break; case NIFTI_ECODE_XCEDE: Rprintf("(David B Keator: http://www.nbirn.net/Resources/Users/Applications/xcede/index.htm)\n"); break; case NIFTI_ECODE_JIMDIMINFO: Rprintf("(Mark A Horsfield: http://someplace/something)\n"); break; case NIFTI_ECODE_WORKFLOW_FWDS: Rprintf("(Kate Fissell: http://kraepelin.wpic.pitt.edu)\n"); break; default: Rprintf("(unknown NIFTI_ECODE)\n"); break; } } Rprintf("data type: %s (%d)\n",nifti_datatype_to_string(pnim->datatype),pnim->datatype); /*switch(pnim->datatype) { //--- the original ANALYZE 7.5 type codes --- case DT_BINARY: // 1 binary (1 bit/voxel) Rprintf(" data type: 1 binary (1 bit/voxel)\n"); break; case DT_UNSIGNED_CHAR: // 2 unsigned char (8 bits/voxel) Rprintf(" data type: 2 unsigned char (8 bits/voxel)\n"); break; case DT_SIGNED_SHORT: // 4 signed short (16 bits/voxel) Rprintf(" data type: 4 signed short (16 bits/voxel)\n"); break; case DT_SIGNED_INT: // 8 signed int (32 bits/voxel) Rprintf(" data type: 8 signed int (32 bits/voxel)\n"); break; case DT_FLOAT: // 16 float (32 bits/voxel) Rprintf(" data type: 16 float (32 bits/voxel)\n"); break; case DT_COMPLEX: // 32 complex (64 bits/voxel) Rprintf(" data type: 32 complex (64 bits/voxel)\n"); break; case DT_DOUBLE: // 64 double (64 bits/voxel) Rprintf(" data type: 64 double (64 bits/voxel) \n"); break; case DT_RGB: //128 RGB triple (24 bits/voxel) Rprintf(" data type: 128 RGB triple (24 bits/voxel)\n"); break; //------------------- new codes for NIFTI --- case DT_INT8: // 256 signed char (8 bits) Rprintf(" data type: 256 signed char (8 bits)\n"); break; case DT_UINT16: // 512 unsigned short (16 bits) Rprintf(" data type: 512 unsigned short (16 bits)\n"); break; case DT_UINT32: // 768 unsigned int (32 bits) Rprintf(" data type: 768 unsigned int (32 bits)\n"); break; case DT_INT64: //1024 long long (64 bits) Rprintf(" data type: 1024 long long (64 bits)\n"); break; case DT_UINT64: //1280 unsigned long long (64 bits) Rprintf(" data type: 1280 unsigned long long (64 bits)\n"); break; case DT_FLOAT128: //1536 long double (128 bits) Rprintf(" data type: 1536 long double (128 bits)\n"); break; case DT_COMPLEX128: //1792 double pair (128 bits) Rprintf(" data type: 1792 double pair (128 bits)\n"); break; case DT_COMPLEX256: //2048 long double pair (256 bits) Rprintf(" data type: 2048 long double pair (256 bits)\n"); break; case DT_RGBA32: //2304 RGBA (32 bits/voxel) Rprintf(" data type: 2304 RGBA32 (32 bits/voxel)\n"); break; default: // what it says, dude Rprintf(" data type: %u what it says, dude\n",pnim->datatype); break; }*/ } Rprintf("intent: %s\n",nifti_intent_string(pnim->intent_code)); Rprintf("attributes: (accessible via $ operator)\n"); for(iIndex=0;Rnifti_attributes[iIndex]!=NULL;++iIndex) { if(iIndex!=0) { if(iIndex%5==0) Rprintf("\n"); else Rprintf("; "); } Rprintf("\"%s\"",Rnifti_attributes[iIndex]); } Rprintf("\n"); return ret_val; } SEXP Rnifti_image_setpixel( SEXP nim, SEXP sexp_x, SEXP sexp_y, SEXP sexp_z, SEXP sexp_t, SEXP sexp_dim5, SEXP sexp_dim6, SEXP sexp_dim7, SEXP value) { nifti_image *pnim=SEXP2NIFTI(nim); if(IS_LOGICAL(sexp_x) || IS_LOGICAL(sexp_y) || IS_LOGICAL(sexp_z) || IS_LOGICAL(sexp_t) || IS_LOGICAL(sexp_dim5) || IS_LOGICAL(sexp_dim6) || IS_LOGICAL(sexp_dim7)) { error("logical indices are not supported"); return nim; } /*PROTECT(value = AS_NUMERIC(value));*/ if(pnim!=NULL) { SEXP coord[7]; PROTECT(coord[0] = AS_INTEGER(sexp_x)); PROTECT(coord[1] = AS_INTEGER(sexp_y)); PROTECT(coord[2] = AS_INTEGER(sexp_z)); PROTECT(coord[3] = AS_INTEGER(sexp_t)); PROTECT(coord[4] = AS_INTEGER(sexp_dim5)); PROTECT(coord[5] = AS_INTEGER(sexp_dim6)); PROTECT(coord[6] = AS_INTEGER(sexp_dim7)); int iDim,outdim=0; int *iCoord[7]; // determine number of dimensions in output matrix for(iDim=0;iDim<7;++iDim) { if(LENGTH(coord[iDim])>1) outdim++; iCoord[iDim]=INTEGER(coord[iDim]); } // check if indices are valid (out of bounds?) int iCoordCounter; for(iDim=0;iDim<7;++iDim) for(iCoordCounter=0;iCoordCounter=REALDIM(iDim)) { error("nifti: index out of range (dimension %d index %d)",iDim+1,iCoord[iDim][iCoordCounter]+1); UNPROTECT(8); return nim; } int iIndex[7], iTOffset=0, iSOffset=0; int total=LENGTH(coord[0]); for(iDim=1;iDim<7;++iDim) total*=LENGTH(coord[iDim]); if(LENGTH(value)>total || total%LENGTH(value)!=0) { UNPROTECT(7); error("Number of items to replace is not a multiple of replacement length!"); return nim; } #define LOOP_START for(iIndex[6]=0;iIndex[6]dim[1] \ + iCoord[2][iIndex[2]]*pnim->dim[1]*pnim->dim[2] \ + iCoord[3][iIndex[3]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3] \ + iCoord[4][iIndex[4]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4] \ + iCoord[5][iIndex[5]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5] \ + iCoord[6][iIndex[6]]*pnim->dim[1]*pnim->dim[2]*pnim->dim[3]*pnim->dim[4]*pnim->dim[5]*pnim->dim[6]; #define LOOP_END ++iSOffset; if(iSOffset==LENGTH(value)) iSOffset=0; } break; if(IS_NUMERIC(value)) { switch(pnim->datatype) { /* uchar (8 bits) */ case DT_UNSIGNED_CHAR: LOOP_START ((unsigned char*)pnim->data)[iTOffset]=(unsigned char)(NUMERIC_POINTER(value)[iSOffset]); LOOP_END /* signed char (8 bits) */ case DT_INT8: LOOP_START ((signed char*)pnim->data)[iTOffset]=(signed char)(NUMERIC_POINTER(value)[iSOffset]); LOOP_END /* unsigned short (16 bits) */ case DT_UINT16: LOOP_START ((unsigned short*)pnim->data)[iTOffset]=(unsigned short)(NUMERIC_POINTER(value)[iSOffset]); LOOP_END // signed short (16 bits) case DT_SIGNED_SHORT: LOOP_START ((short*)pnim->data)[iTOffset]=(short)(NUMERIC_POINTER(value)[iSOffset]); LOOP_END // signed int (32 bits) case DT_SIGNED_INT: LOOP_START ((int*)pnim->data)[iTOffset]=(int)(NUMERIC_POINTER(value)[iSOffset]); LOOP_END /* unsigned int (32 bits) */ case DT_UINT32: LOOP_START ((unsigned int*)pnim->data)[iTOffset]=(unsigned int)(NUMERIC_POINTER(value)[iSOffset]); LOOP_END /* float (32 bits) */ case DT_FLOAT: LOOP_START ((float*)pnim->data)[iTOffset]=(float)(NUMERIC_POINTER(value)[iSOffset]); LOOP_END /* double (64 bits) */ case DT_DOUBLE: LOOP_START ((double*)pnim->data)[iTOffset]=(double)(NUMERIC_POINTER(value)[iSOffset]); LOOP_END /* rgb (24 bits) case DT_RGB: LOOP_START unsigned r,g,b; Rprintf("%s\n",CHAR(CHARACTER_POINTER(value)[iSOffset])); sscanf(CHAR(CHARACTER_POINTER(value)[iSOffset]),"#%2X%2X%2X",&r,&g,&b); Rprintf("%d %d %d\n",r,g,b); ((unsigned char *)pnim->data)[iTOffset*3+0]=(unsigned char)r; ((unsigned char *)pnim->data)[iTOffset*3+1]=(unsigned char)g; ((unsigned char *)pnim->data)[iTOffset*3+2]=(unsigned char)b; LOOP_END*/ /* rgba (32 bits) case DT_RGBA32: LOOP_START unsigned r,g,b,a; sscanf(CHAR(CHARACTER_POINTER(value)[iSOffset]),"#%2X%2X%2X%2X",&r,&g,&b,&a); ((unsigned char *)pnim->data)[iTOffset*4+0]=(unsigned char)r; ((unsigned char *)pnim->data)[iTOffset*4+1]=(unsigned char)g; ((unsigned char *)pnim->data)[iTOffset*4+2]=(unsigned char)b; ((unsigned char *)pnim->data)[iTOffset*4+3]=(unsigned char)a; LOOP_END */ default: warning("Unsupported data format for input type NUMERIC (nifti image datatype is %d)!",pnim->datatype); } } else if(IS_INTEGER(value)) { switch(pnim->datatype) { /* uchar (8 bits) */ case DT_UNSIGNED_CHAR: LOOP_START ((unsigned char*)pnim->data)[iTOffset]=(unsigned char)(INTEGER_POINTER(value)[iSOffset]); LOOP_END /* signed char (8 bits) */ case DT_INT8: LOOP_START ((signed char*)pnim->data)[iTOffset]=(signed char)(INTEGER_POINTER(value)[iSOffset]); LOOP_END /* unsigned short (16 bits) */ case DT_UINT16: LOOP_START ((unsigned short*)pnim->data)[iTOffset]=(unsigned short)(INTEGER_POINTER(value)[iSOffset]); LOOP_END // signed short (16 bits) case DT_SIGNED_SHORT: LOOP_START ((short*)pnim->data)[iTOffset]=(short)(INTEGER_POINTER(value)[iSOffset]); LOOP_END // signed int (32 bits) case DT_SIGNED_INT: LOOP_START ((int*)pnim->data)[iTOffset]=(int)(INTEGER_POINTER(value)[iSOffset]); LOOP_END /* unsigned int (32 bits) */ case DT_UINT32: LOOP_START ((unsigned int*)pnim->data)[iTOffset]=(unsigned int)(INTEGER_POINTER(value)[iSOffset]); LOOP_END /* float (32 bits) */ case DT_FLOAT: LOOP_START ((float*)pnim->data)[iTOffset]=(float)(INTEGER_POINTER(value)[iSOffset]); LOOP_END /* double (64 bits) */ case DT_DOUBLE: LOOP_START ((double*)pnim->data)[iTOffset]=(double)(INTEGER_POINTER(value)[iSOffset]); LOOP_END default: warning("Unsupported data format for input of type INTEGER (nifti image datatype is %d)!",pnim->datatype); } } else if(IS_CHARACTER(value)) { switch(pnim->datatype) { /* rgb (24 bits) */ case DT_RGB: LOOP_START unsigned r,g,b; /*Rprintf("%s\n",CHAR(CHARACTER_POINTER(value)[iSOffset]));*/ sscanf(CHAR(CHARACTER_POINTER(value)[iSOffset]),"#%2X%2X%2X",&r,&g,&b); /*Rprintf("%d %d %d\n",r,g,b);*/ ((unsigned char *)pnim->data)[iTOffset*3+0]=(unsigned char)r; ((unsigned char *)pnim->data)[iTOffset*3+1]=(unsigned char)g; ((unsigned char *)pnim->data)[iTOffset*3+2]=(unsigned char)b; LOOP_END /* rgba (32 bits) */ case DT_RGBA32: LOOP_START unsigned r,g,b,a; sscanf(CHAR(CHARACTER_POINTER(value)[iSOffset]),"#%2X%2X%2X%2X",&r,&g,&b,&a); ((unsigned char *)pnim->data)[iTOffset*4+0]=(unsigned char)r; ((unsigned char *)pnim->data)[iTOffset*4+1]=(unsigned char)g; ((unsigned char *)pnim->data)[iTOffset*4+2]=(unsigned char)b; ((unsigned char *)pnim->data)[iTOffset*4+3]=(unsigned char)a; LOOP_END default: warning("Unsupported data format for input type CHARACTER (nifti image datatype is %d)",pnim->datatype); } } else error("Unsupported input data format (need NUMERIC, INTEGER or CHARACTER vectors)!"); UNPROTECT(7); } return nim; } SEXP Rnifti_image_setdatatype(SEXP nim, SEXP value) { nifti_image *pnim=SEXP2NIFTI(nim); if(pnim!=NULL) { int itype=DT_UNKNOWN; if(IS_NUMERIC(value) || IS_INTEGER(value)) { PROTECT(value = AS_INTEGER(value)); itype=INTEGER(value)[0]; UNPROTECT(1); } else if(isString(value) || length(value) != 1) { const char *pctype = CHAR(STRING_ELT(value , 0)); itype=nifti_datatype_from_string(pctype); } else warning("Unsupported or unknown second argument (type set to DT_UNKNOWN)!"); switch(itype) { case DT_NONE: pnim->nbyper=0; break; case DT_BINARY: pnim->nbyper=0; break; case DT_UNSIGNED_CHAR: pnim->nbyper=1; break; case DT_INT8: pnim->nbyper=1; break; case DT_UINT16: pnim->nbyper=2; break; case DT_SIGNED_SHORT: pnim->nbyper=2; break; case DT_SIGNED_INT: pnim->nbyper=4; break; case DT_UINT32: pnim->nbyper=4; break; case DT_INT64: pnim->nbyper=8; break; case DT_UINT64: pnim->nbyper=8; break; case DT_FLOAT: pnim->nbyper=4; break; case DT_FLOAT128: pnim->nbyper=16; break; case DT_DOUBLE: pnim->nbyper=8; break; case DT_COMPLEX: pnim->nbyper=8; break; case DT_COMPLEX128: pnim->nbyper=16; break; case DT_COMPLEX256: pnim->nbyper=32; break; case DT_RGB: pnim->nbyper=3; break; case DT_RGBA32: pnim->nbyper=4; break; default: warning("Unsupported or unknown data type!"); break; } pnim->datatype=itype; } return nim; } SEXP Rnifti_compiled_with_zlib(void) { SEXP ret_val=R_NilValue; PROTECT(ret_val=NEW_LOGICAL(1)); LOGICAL_POINTER(ret_val)[0]=nifti_compiled_with_zlib(); UNPROTECT(1); return ret_val; } SEXP Rnifti_disp_lib_version(void) { SEXP ret_val=R_NilValue; char buffer[200]; snprintf(buffer, 200, "%s, compiled %s", nifti_lib_version(), __DATE__); PROTECT(ret_val = NEW_CHARACTER(1)); SET_STRING_ELT(ret_val, 0, mkChar(buffer)); UNPROTECT(1); return ret_val; } SEXP Rnifti_units_string(SEXP value) { SEXP ret_val=R_NilValue; PROTECT(value=AS_INTEGER(value)); if(IS_INTEGER(value) && LENGTH(value)==1) ret_val = Rnifti_pchar_SEXP(nifti_units_string(INTEGER_POINTER(value)[0])); UNPROTECT(1); return ret_val; } SEXP Rnifti_datatype_string(SEXP value) { SEXP ret_val=R_NilValue; PROTECT(value=AS_INTEGER(value)); if(IS_INTEGER(value) && LENGTH(value)==1) ret_val = Rnifti_pchar_SEXP(nifti_datatype_string(INTEGER_POINTER(value)[0])); UNPROTECT(1); return ret_val; } Rniftilib/src/nifti1_io.h0000644000176000001440000006261212073250672015060 0ustar ripleyusers/** \file nifti1_io.h \brief Data structures for using nifti1_io API. - Written by Bob Cox, SSCC NIMH - Revisions by Rick Reynolds, SSCC NIMH */ #ifndef _NIFTI_IO_HEADER_ #define _NIFTI_IO_HEADER_ #include #include #include #include #include #ifndef DONT_INCLUDE_ANALYZE_STRUCT #define DONT_INCLUDE_ANALYZE_STRUCT /*** not needed herein ***/ #endif #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include "nifti1.h" /*** NIFTI-1 header specification ***/ #include "znzlib.h" /*=================*/ #ifdef __cplusplus extern "C" { #endif /*=================*/ /*****===================================================================*****/ /***** File nifti1_io.h == Declarations for nifti1_io.c *****/ /*****...................................................................*****/ /***** This code is released to the public domain. *****/ /*****...................................................................*****/ /***** Author: Robert W Cox, SSCC/DIRP/NIMH/NIH/DHHS/USA/EARTH *****/ /***** Date: August 2003 *****/ /*****...................................................................*****/ /***** Neither the National Institutes of Health (NIH), nor any of its *****/ /***** employees imply any warranty of usefulness of this software for *****/ /***** any purpose, and do not assume any liability for damages, *****/ /***** incidental or otherwise, caused by any use of this document. *****/ /*****===================================================================*****/ /* Modified by: Mark Jenkinson (FMRIB Centre, University of Oxford, UK) Date: July/August 2004 Mainly adding low-level IO and changing things to allow gzipped files to be read and written Full backwards compatability should have been maintained Modified by: Rick Reynolds (SSCC/DIRP/NIMH, National Institutes of Health) Date: December 2004 Modified and added many routines for I/O. */ /********************** Some sample data structures **************************/ typedef struct { /** 4x4 matrix struct **/ float m[4][4] ; } mat44 ; typedef struct { /** 3x3 matrix struct **/ float m[3][3] ; } mat33 ; /*...........................................................................*/ /*! \enum analyze_75_orient_code * \brief Old-style analyze75 orientation * codes. */ typedef enum _analyze75_orient_code { a75_transverse_unflipped = 0, a75_coronal_unflipped = 1, a75_sagittal_unflipped = 2, a75_transverse_flipped = 3, a75_coronal_flipped = 4, a75_sagittal_flipped = 5, a75_orient_unknown = 6 } analyze_75_orient_code; /*! \struct nifti_image \brief High level data structure for open nifti datasets in the nifti1_io API. Note that this structure is not part of the nifti1 format definition; it is used to implement one API for reading/writing formats in the nifti1 format. */ typedef struct { /*!< Image storage struct **/ int ndim ; /*!< last dimension greater than 1 (1..7) */ int nx ; /*!< dimensions of grid array */ int ny ; /*!< dimensions of grid array */ int nz ; /*!< dimensions of grid array */ int nt ; /*!< dimensions of grid array */ int nu ; /*!< dimensions of grid array */ int nv ; /*!< dimensions of grid array */ int nw ; /*!< dimensions of grid array */ int dim[8] ; /*!< dim[0]=ndim, dim[1]=nx, etc. */ size_t nvox ; /*!< number of voxels = nx*ny*nz*...*nw */ int nbyper ; /*!< bytes per voxel, matches datatype */ int datatype ; /*!< type of data in voxels: DT_* code */ float dx ; /*!< grid spacings */ float dy ; /*!< grid spacings */ float dz ; /*!< grid spacings */ float dt ; /*!< grid spacings */ float du ; /*!< grid spacings */ float dv ; /*!< grid spacings */ float dw ; /*!< grid spacings */ float pixdim[8] ; /*!< pixdim[1]=dx, etc. */ float scl_slope ; /*!< scaling parameter - slope */ float scl_inter ; /*!< scaling parameter - intercept */ float cal_min ; /*!< calibration parameter, minimum */ float cal_max ; /*!< calibration parameter, maximum */ int qform_code ; /*!< codes for (x,y,z) space meaning */ int sform_code ; /*!< codes for (x,y,z) space meaning */ int freq_dim ; /*!< indexes (1,2,3, or 0) for MRI */ int phase_dim ; /*!< directions in dim[]/pixdim[] */ int slice_dim ; /*!< directions in dim[]/pixdim[] */ int slice_code ; /*!< code for slice timing pattern */ int slice_start ; /*!< index for start of slices */ int slice_end ; /*!< index for end of slices */ float slice_duration ; /*!< time between individual slices */ /*! quaternion transform parameters [when writing a dataset, these are used for qform, NOT qto_xyz] */ float quatern_b , quatern_c , quatern_d , qoffset_x , qoffset_y , qoffset_z , qfac ; mat44 qto_xyz ; /*!< qform: transform (i,j,k) to (x,y,z) */ mat44 qto_ijk ; /*!< qform: transform (x,y,z) to (i,j,k) */ mat44 sto_xyz ; /*!< sform: transform (i,j,k) to (x,y,z) */ mat44 sto_ijk ; /*!< sform: transform (x,y,z) to (i,j,k) */ float toffset ; /*!< time coordinate offset */ int xyz_units ; /*!< dx,dy,dz units: NIFTI_UNITS_* code */ int time_units ; /*!< dt units: NIFTI_UNITS_* code */ int nifti_type ; /*!< 0==ANALYZE, 1==NIFTI-1 (1 file), 2==NIFTI-1 (2 files), 3==NIFTI-ASCII (1 file) */ int intent_code ; /*!< statistic type (or something) */ float intent_p1 ; /*!< intent parameters */ float intent_p2 ; /*!< intent parameters */ float intent_p3 ; /*!< intent parameters */ char intent_name[16] ; /*!< optional description of intent data */ char descrip[80] ; /*!< optional text to describe dataset */ char aux_file[24] ; /*!< auxiliary filename */ char *fname ; /*!< header filename (.hdr or .nii) */ char *iname ; /*!< image filename (.img or .nii) */ int iname_offset ; /*!< offset into iname where data starts */ int swapsize ; /*!< swap unit in image data (might be 0) */ int byteorder ; /*!< byte order on disk (MSB_ or LSB_FIRST) */ void *data ; /*!< pointer to data: nbyper*nvox bytes */ int num_ext ; /*!< number of extensions in ext_list */ nifti1_extension * ext_list ; /*!< array of extension structs (with data) */ analyze_75_orient_code analyze75_orient; /*!< for old analyze files, orient */ } nifti_image ; /* struct for return from nifti_image_read_bricks() */ typedef struct { int nbricks; /* the number of allocated pointers in 'bricks' */ size_t bsize; /* the length of each data block, in bytes */ void ** bricks; /* array of pointers to data blocks */ } nifti_brick_list; /*****************************************************************************/ /*------------------ NIfTI version of ANALYZE 7.5 structure -----------------*/ /* (based on fsliolib/dbh.h, but updated for version 7.5) */ typedef struct { /* header info fields - describes the header overlap with NIfTI */ /* ------------------ */ int sizeof_hdr; /* 0 + 4 same */ char data_type[10]; /* 4 + 10 same */ char db_name[18]; /* 14 + 18 same */ int extents; /* 32 + 4 same */ short int session_error; /* 36 + 2 same */ char regular; /* 38 + 1 same */ char hkey_un0; /* 39 + 1 40 bytes */ /* image dimension fields - describes image sizes */ short int dim[8]; /* 0 + 16 same */ short int unused8; /* 16 + 2 intent_p1... */ short int unused9; /* 18 + 2 ... */ short int unused10; /* 20 + 2 intent_p2... */ short int unused11; /* 22 + 2 ... */ short int unused12; /* 24 + 2 intent_p3... */ short int unused13; /* 26 + 2 ... */ short int unused14; /* 28 + 2 intent_code */ short int datatype; /* 30 + 2 same */ short int bitpix; /* 32 + 2 same */ short int dim_un0; /* 34 + 2 slice_start */ float pixdim[8]; /* 36 + 32 same */ float vox_offset; /* 68 + 4 same */ float funused1; /* 72 + 4 scl_slope */ float funused2; /* 76 + 4 scl_inter */ float funused3; /* 80 + 4 slice_end, */ /* slice_code, */ /* xyzt_units */ float cal_max; /* 84 + 4 same */ float cal_min; /* 88 + 4 same */ float compressed; /* 92 + 4 slice_duration */ float verified; /* 96 + 4 toffset */ int glmax,glmin; /* 100 + 8 108 bytes */ /* data history fields - optional */ char descrip[80]; /* 0 + 80 same */ char aux_file[24]; /* 80 + 24 same */ char orient; /* 104 + 1 NO GOOD OVERLAP */ char originator[10]; /* 105 + 10 FROM HERE DOWN... */ char generated[10]; /* 115 + 10 */ char scannum[10]; /* 125 + 10 */ char patient_id[10]; /* 135 + 10 */ char exp_date[10]; /* 145 + 10 */ char exp_time[10]; /* 155 + 10 */ char hist_un0[3]; /* 165 + 3 */ int views; /* 168 + 4 */ int vols_added; /* 172 + 4 */ int start_field; /* 176 + 4 */ int field_skip; /* 180 + 4 */ int omax, omin; /* 184 + 8 */ int smax, smin; /* 192 + 8 200 bytes */ } nifti_analyze75; /* total: 348 bytes */ /*****************************************************************************/ /*--------------- Prototypes of functions defined in this file --------------*/ char *nifti_datatype_string ( int dt ) ; char *nifti_units_string ( int uu ) ; char *nifti_intent_string ( int ii ) ; char *nifti_xform_string ( int xx ) ; char *nifti_slice_string ( int ss ) ; char *nifti_orientation_string( int ii ) ; int nifti_is_inttype( int dt ) ; mat44 nifti_mat44_inverse( mat44 R ) ; mat33 nifti_mat33_inverse( mat33 R ) ; mat33 nifti_mat33_polar ( mat33 A ) ; float nifti_mat33_rownorm( mat33 A ) ; float nifti_mat33_colnorm( mat33 A ) ; float nifti_mat33_determ ( mat33 R ) ; mat33 nifti_mat33_mul ( mat33 A , mat33 B ) ; void nifti_swap_2bytes ( size_t n , void *ar ) ; void nifti_swap_4bytes ( size_t n , void *ar ) ; void nifti_swap_8bytes ( size_t n , void *ar ) ; void nifti_swap_16bytes( size_t n , void *ar ) ; void nifti_swap_Nbytes ( size_t n , int siz , void *ar ) ; int nifti_datatype_is_valid (int dtype, int for_nifti); int nifti_datatype_from_string(const char * name); const char * nifti_datatype_to_string (int dtype); int nifti_get_filesize( const char *pathname ) ; void swap_nifti_header ( struct nifti_1_header *h , int is_nifti ) ; void old_swap_nifti_header( struct nifti_1_header *h , int is_nifti ); int nifti_swap_as_analyze( nifti_analyze75 *h ); /* main read/write routines */ nifti_image *nifti_image_read_bricks(const char *hname , int nbricks, const int *blist, nifti_brick_list * NBL); int nifti_image_load_bricks(nifti_image *nim , int nbricks, const int *blist, nifti_brick_list * NBL); void nifti_free_NBL( nifti_brick_list * NBL ); nifti_image *nifti_image_read ( const char *hname , int read_data ); nifti_image *nifti_image_read_NaN ( const char *hname , int read_data , int rmNaN); int nifti_image_load ( nifti_image *nim ) ; int nifti_image_load_NaN ( nifti_image *nim , int rmNaN) ; void nifti_image_unload ( nifti_image *nim ) ; void nifti_image_free ( nifti_image *nim ) ; int nifti_read_collapsed_image( nifti_image * nim, const int dims [8], void ** data ); int nifti_read_subregion_image( nifti_image * nim, int *start_index, int *region_size, void ** data ); void nifti_image_write ( nifti_image * nim ) ; void nifti_image_write_bricks(nifti_image * nim, const nifti_brick_list * NBL); void nifti_image_infodump( const nifti_image * nim ) ; void nifti_disp_lib_hist( void ) ; /* to display library history */ void nifti_disp_lib_version( void ) ; /* to display library version */ const char *nifti_lib_version( void ); int nifti_disp_matrix_orient( const char * mesg, mat44 mat ); int nifti_disp_type_list( int which ); char * nifti_image_to_ascii ( const nifti_image * nim ) ; nifti_image *nifti_image_from_ascii( const char * str, int * bytes_read ) ; size_t nifti_get_volsize(const nifti_image *nim) ; /* basic file operations */ int nifti_set_filenames(nifti_image * nim, const char * prefix, int check, int set_byte_order); char * nifti_makehdrname (const char * prefix, int nifti_type, int check, int comp); char * nifti_makeimgname (const char * prefix, int nifti_type, int check, int comp); int is_nifti_file (const char *hname); char * nifti_find_file_extension(const char * name); int nifti_is_complete_filename(const char* fname); int nifti_validfilename(const char* fname); int disp_nifti_1_header(const char * info, const nifti_1_header * hp ) ; void nifti_set_debug_level( int level ) ; void nifti_set_skip_blank_ext( int skip ) ; void nifti_set_allow_upper_fext( int allow ) ; int valid_nifti_brick_list(nifti_image * nim , int nbricks, const int * blist, int disp_error); /* znzFile operations */ znzFile nifti_image_open(const char * hname, char * opts, nifti_image ** nim); znzFile nifti_image_write_hdr_img(nifti_image *nim, int write_data, const char* opts); znzFile nifti_image_write_hdr_img2( nifti_image *nim , int write_opts , const char* opts, znzFile imgfile, const nifti_brick_list * NBL); size_t nifti_read_buffer_NaN(znzFile fp, void* datatptr, size_t ntot, nifti_image *nim, int rmNaN); size_t nifti_read_buffer(znzFile fp, void* datatptr, size_t ntot, nifti_image *nim); int nifti_write_all_data(znzFile fp, nifti_image * nim, const nifti_brick_list * NBL); size_t nifti_write_buffer(znzFile fp, const void * buffer, size_t numbytes); nifti_image *nifti_read_ascii_image(znzFile fp, char *fname, int flen, int read_data); znzFile nifti_write_ascii_image(nifti_image *nim, const nifti_brick_list * NBL, const char * opts, int write_data, int leave_open); void nifti_datatype_sizes( int datatype , int *nbyper, int *swapsize ) ; void nifti_mat44_to_quatern( mat44 R , float *qb, float *qc, float *qd, float *qx, float *qy, float *qz, float *dx, float *dy, float *dz, float *qfac ) ; mat44 nifti_quatern_to_mat44( float qb, float qc, float qd, float qx, float qy, float qz, float dx, float dy, float dz, float qfac ); mat44 nifti_make_orthog_mat44( float r11, float r12, float r13 , float r21, float r22, float r23 , float r31, float r32, float r33 ) ; int nifti_short_order(void) ; /* CPU byte order */ /* Orientation codes that might be returned from nifti_mat44_to_orientation().*/ #define NIFTI_L2R 1 /* Left to Right */ #define NIFTI_R2L 2 /* Right to Left */ #define NIFTI_P2A 3 /* Posterior to Anterior */ #define NIFTI_A2P 4 /* Anterior to Posterior */ #define NIFTI_I2S 5 /* Inferior to Superior */ #define NIFTI_S2I 6 /* Superior to Inferior */ void nifti_mat44_to_orientation( mat44 R , int *icod, int *jcod, int *kcod ) ; /*--------------------- Low level IO routines ------------------------------*/ char * nifti_findhdrname (const char* fname); char * nifti_findimgname (const char* fname , int nifti_type); int nifti_is_gzfile (const char* fname); char * nifti_makebasename(const char* fname); /* other routines */ struct nifti_1_header nifti_convert_nim2nhdr(const nifti_image* nim); nifti_1_header * nifti_make_new_header(const int arg_dims[], int arg_dtype); nifti_1_header * nifti_read_header(const char *hname, int *swapped, int check); nifti_image * nifti_copy_nim_info(const nifti_image * src); nifti_image * nifti_make_new_nim(const int dims[], int datatype, int data_fill); nifti_image * nifti_simple_init_nim(void); nifti_image * nifti_convert_nhdr2nim(struct nifti_1_header nhdr, const char * fname); int nifti_hdr_looks_good (const nifti_1_header * hdr); int nifti_is_valid_datatype (int dtype); int nifti_is_valid_ecode (int ecode); int nifti_nim_is_valid (nifti_image * nim, int complain); int nifti_nim_has_valid_dims (nifti_image * nim, int complain); int is_valid_nifti_type (int nifti_type); int nifti_test_datatype_sizes (int verb); int nifti_type_and_names_match (nifti_image * nim, int show_warn); int nifti_update_dims_from_array(nifti_image * nim); void nifti_set_iname_offset (nifti_image *nim); int nifti_set_type_from_names (nifti_image * nim); int nifti_add_extension(nifti_image * nim, const char * data, int len, int ecode ); int nifti_compiled_with_zlib (void); int nifti_copy_extensions (nifti_image *nim_dest,const nifti_image *nim_src); int nifti_free_extensions (nifti_image *nim); int * nifti_get_intlist (int nvals , const char *str); char * nifti_strdup (const char *str); int valid_nifti_extensions(const nifti_image *nim); /*-------------------- Some C convenience macros ----------------------------*/ /* NIfTI-1.1 extension codes: see http://nifti.nimh.nih.gov/nifti-1/documentation/faq#Q21 */ #define NIFTI_ECODE_IGNORE 0 /* changed from UNKNOWN, 29 June 2005 */ #define NIFTI_ECODE_DICOM 2 /* intended for raw DICOM attributes */ #define NIFTI_ECODE_AFNI 4 /* Robert W Cox: rwcox@nih.gov http://afni.nimh.nih.gov/afni */ #define NIFTI_ECODE_COMMENT 6 /* plain ASCII text only */ #define NIFTI_ECODE_XCEDE 8 /* David B Keator: dbkeator@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_MAX_ECODE 30 /******* maximum extension code *******/ /* nifti_type file codes */ #define NIFTI_FTYPE_ANALYZE 0 #define NIFTI_FTYPE_NIFTI1_1 1 #define NIFTI_FTYPE_NIFTI1_2 2 #define NIFTI_FTYPE_ASCII 3 #define NIFTI_MAX_FTYPE 3 /* this should match the maximum code */ /*------------------------------------------------------------------------*/ /*-- the rest of these apply only to nifti1_io.c, check for _NIFTI1_IO_C_ */ /* Feb 9, 2005 [rickr] */ #ifdef _NIFTI1_IO_C_ typedef struct { int debug; /*!< debug level for status reports */ int skip_blank_ext; /*!< skip extender if no extensions */ int allow_upper_fext; /*!< allow uppercase file extensions */ } nifti_global_options; typedef struct { int type; /* should match the NIFTI_TYPE_ #define */ int nbyper; /* bytes per value, matches nifti_image */ int swapsize; /* bytes per swap piece, matches nifti_image */ char * name; /* text string to match #define */ } nifti_type_ele; #undef LNI_FERR /* local nifti file error, to be compact and repetative */ #define LNI_FERR(func,msg,file) \ REprintf("** ERROR (%s): %s '%s'\n",func,msg,file) #undef swap_2 #undef swap_4 #define swap_2(s) nifti_swap_2bytes(1,&(s)) /* s: 2-byte short; swap in place */ #define swap_4(v) nifti_swap_4bytes(1,&(v)) /* v: 4-byte value; swap in place */ /***** isfinite() is a C99 macro, which is present in many C implementations already *****/ #undef IS_GOOD_FLOAT #undef FIXED_FLOAT #ifdef isfinite /* use isfinite() to check floats/doubles for goodness */ # define IS_GOOD_FLOAT(x) isfinite(x) /* check if x is a "good" float */ # define FIXED_FLOAT(x) (isfinite(x) ? (x) : 0) /* fixed if bad */ #else # define IS_GOOD_FLOAT(x) 1 /* don't check it */ # define FIXED_FLOAT(x) (x) /* don't fix it */ #endif #undef ASSIF /* assign v to *p, if possible */ #define ASSIF(p,v) if( (p)!=NULL ) *(p) = (v) #undef MSB_FIRST #undef LSB_FIRST #undef REVERSE_ORDER #define LSB_FIRST 1 #define MSB_FIRST 2 #define REVERSE_ORDER(x) (3-(x)) /* convert MSB_FIRST <--> LSB_FIRST */ #define LNI_MAX_NIA_EXT_LEN 100000 /* consider a longer extension invalid */ #endif /* _NIFTI1_IO_C_ section */ /*------------------------------------------------------------------------*/ /*=================*/ #ifdef __cplusplus } #endif /*=================*/ #endif /* _NIFTI_IO_HEADER_ */ Rniftilib/src/znzlib.h0000644000176000001440000000613012073250672014500 0ustar ripleyusers#ifndef _ZNZLIB_H_ #define _ZNZLIB_H_ /* znzlib.h (zipped or non-zipped library) ***** This code is released to the public domain. ***** ***** Author: Mark Jenkinson, FMRIB Centre, University of Oxford ***** ***** Date: September 2004 ***** ***** Neither the FMRIB Centre, the University of Oxford, nor any of ***** ***** its employees imply any warranty of usefulness of this software ***** ***** for any purpose, and do not assume any liability for damages, ***** ***** incidental or otherwise, caused by any use of this document. ***** */ /* This library provides an interface to both compressed (gzip/zlib) and uncompressed (normal) file IO. The functions are written to have the same interface as the standard file IO functions. To use this library instead of normal file IO, the following changes are required: - replace all instances of FILE* with znzFile - change the name of all function calls, replacing the initial character f with the znz (e.g. fseek becomes znzseek) - add a third parameter to all calls to znzopen (previously fopen) that specifies whether to use compression (1) or not (0) - use znz_isnull rather than any (pointer == NULL) comparisons in the code NB: seeks for writable files with compression are quite restricted */ /* changes by Oliver Granert: - change HAVE_ZLIB to HAVE_LIBZ to fit autoconf tests */ /*=================*/ #ifdef __cplusplus extern "C" { #endif /*=================*/ #include #include #include #include #if HAVE_CONFIG_H #include #endif /* include optional check for HAVE_FDOPEN here, from deleted config.h: uncomment the following line if fdopen() exists for your compiler and compiler options */ /* #define HAVE_FDOPEN */ #ifdef HAVE_LIBZ #if defined(ITKZLIB) #include "itk_zlib.h" #else #include "zlib.h" #endif #endif struct znzptr { int withz; FILE* nzfptr; #ifdef HAVE_LIBZ gzFile zfptr; #endif } ; /* the type for all file pointers */ typedef struct znzptr * znzFile; /* int znz_isnull(znzFile f); */ /* int znzclose(znzFile f); */ #define znz_isnull(f) ((f) == NULL) #define znzclose(f) Xznzclose(&(f)) /* Note extra argument (use_compression) where use_compression==0 is no compression use_compression!=0 uses zlib (gzip) compression */ znzFile znzopen(const char *path, const char *mode, int use_compression); znzFile znzdopen(int fd, const char *mode, int use_compression); int Xznzclose(znzFile * file); size_t znzread(void* buf, size_t size, size_t nmemb, znzFile file); size_t znzwrite(const void* buf, size_t size, size_t nmemb, znzFile file); long znzseek(znzFile file, long offset, int whence); int znzrewind(znzFile stream); long znztell(znzFile file); int znzputs(const char *str, znzFile file); char * znzgets(char* str, int size, znzFile file); int znzputc(int c, znzFile file); int znzgetc(znzFile file); #if !defined(WIN32) int znzprintf(znzFile stream, const char *format, ...); #endif /*=================*/ #ifdef __cplusplus } #endif /*=================*/ #endif Rniftilib/src/Makevars.in0000644000176000001440000000012111432314460015104 0ustar ripleyusersPKG_CPPFLAGS=-I.. @CFLAGS@ @CPPFLAGS@ @INCLUDE@ @DEFS@ PKG_LIBS=@LDFLAGS@ @LIBS@ Rniftilib/src/znzlib.c0000644000176000001440000002033412073250672014475 0ustar ripleyusers/** \file znzlib.c \brief Low level i/o interface to compressed and noncompressed files. Written by Mark Jenkinson, FMRIB This library provides an interface to both compressed (gzip/zlib) and uncompressed (normal) file IO. The functions are written to have the same interface as the standard file IO functions. To use this library instead of normal file IO, the following changes are required: - replace all instances of FILE* with znzFile - change the name of all function calls, replacing the initial character f with the znz (e.g. fseek becomes znzseek) one exception is rewind() -> znzrewind() - add a third parameter to all calls to znzopen (previously fopen) that specifies whether to use compression (1) or not (0) - use znz_isnull rather than any (pointer == NULL) comparisons in the code for znzfile types (normally done after a return from znzopen) NB: seeks for writable files with compression are quite restricted */ /* changes by Oliver Granert: - change HAVE_ZLIB to HAVE_LIBZ to fit autoconf tests */ #include "znzlib.h" #include /* znzlib.c (zipped or non-zipped library) ***** This code is released to the public domain. ***** ***** Author: Mark Jenkinson, FMRIB Centre, University of Oxford ***** ***** Date: September 2004 ***** ***** Neither the FMRIB Centre, the University of Oxford, nor any of ***** ***** its employees imply any warranty of usefulness of this software ***** ***** for any purpose, and do not assume any liability for damages, ***** ***** incidental or otherwise, caused by any use of this document. ***** */ /* Note extra argument (use_compression) where use_compression==0 is no compression use_compression!=0 uses zlib (gzip) compression */ znzFile znzopen(const char *path, const char *mode, int use_compression) { znzFile file; file = (znzFile) calloc(1,sizeof(struct znzptr)); if( file == NULL ){ REprintf(/*fprintf(stderr,*/"** ERROR: znzopen failed to alloc znzptr\n"); return NULL; } file->nzfptr = NULL; #ifdef HAVE_LIBZ file->zfptr = NULL; if (use_compression) { file->withz = 1; if((file->zfptr = gzopen(path,mode)) == NULL) { free(file); file = NULL; } } else { #endif file->withz = 0; if((file->nzfptr = fopen(path,mode)) == NULL) { free(file); file = NULL; } #ifdef HAVE_LIBZ } #endif return file; } znzFile znzdopen(int fd, const char *mode, int use_compression) { znzFile file; file = (znzFile) calloc(1,sizeof(struct znzptr)); if( file == NULL ){ REprintf(/*fprintf(stderr,*/"** ERROR: znzdopen failed to alloc znzptr\n"); return NULL; } #ifdef HAVE_LIBZ if (use_compression) { file->withz = 1; file->zfptr = gzdopen(fd,mode); file->nzfptr = NULL; } else { #endif file->withz = 0; #ifdef HAVE_FDOPEN file->nzfptr = fdopen(fd,mode); #endif #ifdef HAVE_LIBZ file->zfptr = NULL; }; #endif return file; } int Xznzclose(znzFile * file) { int retval = 0; if (*file!=NULL) { #ifdef HAVE_LIBZ if ((*file)->zfptr!=NULL) { retval = gzclose((*file)->zfptr); } #endif if ((*file)->nzfptr!=NULL) { retval = fclose((*file)->nzfptr); } free(*file); *file = NULL; } return retval; } /* we already assume ints are 4 bytes */ #undef ZNZ_MAX_BLOCK_SIZE #define ZNZ_MAX_BLOCK_SIZE (1<<30) size_t znzread(void* buf, size_t size, size_t nmemb, znzFile file) { #ifdef HAVE_LIBZ size_t remain = size*nmemb; char * cbuf = (char *)buf; unsigned n2read; int nread; #endif if (file==NULL) { return 0; } #ifdef HAVE_LIBZ if (file->zfptr!=NULL) { /* gzread/write take unsigned int length, so maybe read in int pieces (noted by M Hanke, example given by M Adler) 6 July 2010 [rickr] */ while( remain > 0 ) { n2read = (remain < ZNZ_MAX_BLOCK_SIZE) ? remain : ZNZ_MAX_BLOCK_SIZE; nread = gzread(file->zfptr, (void *)cbuf, n2read); if( nread < 0 ) return nread; /* returns -1 on error */ remain -= nread; cbuf += nread; /* require reading n2read bytes, so we don't get stuck */ if( nread < (int)n2read ) break; /* return will be short */ } /* warn of a short read that will seem complete */ if( remain > 0 && remain < size ) REprintf(/*fprintf(stderr,*/"** znzread: read short by %u bytes\n",(unsigned)remain); return nmemb - remain/size; /* return number of members processed */ } #endif return fread(buf,size,nmemb,file->nzfptr); } size_t znzwrite(const void* buf, size_t size, size_t nmemb, znzFile file) { #ifdef HAVE_LIBZ size_t remain = size*nmemb; char * cbuf = (char *)buf; unsigned n2write; int nwritten; #endif if (file==NULL) { return 0; } #ifdef HAVE_LIBZ if (file->zfptr!=NULL) { while( remain > 0 ) { n2write = (remain < ZNZ_MAX_BLOCK_SIZE) ? remain : ZNZ_MAX_BLOCK_SIZE; nwritten = gzwrite(file->zfptr, (void *)cbuf, n2write); /* gzread returns 0 on error, but in case that ever changes... */ if( nwritten < 0 ) return nwritten; remain -= nwritten; cbuf += nwritten; /* require writing n2write bytes, so we don't get stuck */ if( nwritten < (int)n2write ) break; } /* warn of a short write that will seem complete */ if( remain > 0 && remain < size ) REprintf(/*fprintf(stderr,*/"** znzwrite: write short by %u bytes\n",(unsigned)remain); return nmemb - remain/size; /* return number of members processed */ } #endif return fwrite(buf,size,nmemb,file->nzfptr); } long znzseek(znzFile file, long offset, int whence) { if (file==NULL) { return 0; } #ifdef HAVE_LIBZ if (file->zfptr!=NULL) return (long) gzseek(file->zfptr,offset,whence); #endif return fseek(file->nzfptr,offset,whence); } int znzrewind(znzFile stream) { if (stream==NULL) { return 0; } #ifdef HAVE_LIBZ /* On some systems, gzrewind() fails for uncompressed files. Use gzseek(), instead. 10, May 2005 [rickr] if (stream->zfptr!=NULL) return gzrewind(stream->zfptr); */ if (stream->zfptr!=NULL) return (int)gzseek(stream->zfptr, 0L, SEEK_SET); #endif rewind(stream->nzfptr); return 0; } long znztell(znzFile file) { if (file==NULL) { return 0; } #ifdef HAVE_LIBZ if (file->zfptr!=NULL) return (long) gztell(file->zfptr); #endif return ftell(file->nzfptr); } int znzputs(const char * str, znzFile file) { if (file==NULL) { return 0; } #ifdef HAVE_LIBZ if (file->zfptr!=NULL) return gzputs(file->zfptr,str); #endif return fputs(str,file->nzfptr); } char * znzgets(char* str, int size, znzFile file) { if (file==NULL) { return NULL; } #ifdef HAVE_LIBZ if (file->zfptr!=NULL) return gzgets(file->zfptr,str,size); #endif return fgets(str,size,file->nzfptr); } int znzflush(znzFile file) { if (file==NULL) { return 0; } #ifdef HAVE_LIBZ if (file->zfptr!=NULL) return gzflush(file->zfptr,Z_SYNC_FLUSH); #endif return fflush(file->nzfptr); } int znzeof(znzFile file) { if (file==NULL) { return 0; } #ifdef HAVE_LIBZ if (file->zfptr!=NULL) return gzeof(file->zfptr); #endif return feof(file->nzfptr); } int znzputc(int c, znzFile file) { if (file==NULL) { return 0; } #ifdef HAVE_LIBZ if (file->zfptr!=NULL) return gzputc(file->zfptr,c); #endif return fputc(c,file->nzfptr); } int znzgetc(znzFile file) { if (file==NULL) { return 0; } #ifdef HAVE_LIBZ if (file->zfptr!=NULL) return gzgetc(file->zfptr); #endif return fgetc(file->nzfptr); } #if !defined (WIN32) int znzprintf(znzFile stream, const char *format, ...) { int retval=0; char *tmpstr; va_list va; if (stream==NULL) { return 0; } va_start(va, format); #ifdef HAVE_LIBZ if (stream->zfptr!=NULL) { int size; /* local to HAVE_LIBZ block */ size = strlen(format) + 1000000; /* overkill I hope */ tmpstr = (char *)calloc(1, size); if( tmpstr == NULL ){ REprintf(/*fprintf(stderr,*/"** ERROR: znzprintf failed to alloc %d bytes\n", size); return retval; } vsprintf(tmpstr,format,va); retval=gzprintf(stream->zfptr,"%s",tmpstr); free(tmpstr); } else #endif { retval=vfprintf(stream->nzfptr,format,va); } va_end(va); return retval; } #endif Rniftilib/src/nifti1_io.c0000644000176000001440000102137012073250672015050 0ustar ripleyusers#define _NIFTI1_IO_C_ #include "nifti1_io.h" /* typedefs, prototypes, macros, etc. */ #include /*****===================================================================*****/ /***** Sample functions to deal with NIFTI-1 and ANALYZE files *****/ /*****...................................................................*****/ /***** This code is released to the public domain. *****/ /*****...................................................................*****/ /***** Author: Robert W Cox, SSCC/DIRP/NIMH/NIH/DHHS/USA/EARTH *****/ /***** Date: August 2003 *****/ /*****...................................................................*****/ /***** Neither the National Institutes of Health (NIH), nor any of its *****/ /***** employees imply any warranty of usefulness of this software for *****/ /***** any purpose, and do not assume any liability for damages, *****/ /***** incidental or otherwise, caused by any use of this document. *****/ /*****===================================================================*****/ /** \file nifti1_io.c \brief main collection of nifti1 i/o routines - written by Bob Cox, SSCC NIMH - revised by Mark Jenkinson, FMRIB - revised by Rick Reynolds, SSCC, NIMH - revised by Kate Fissell, University of Pittsburgh The library history can be viewed via "nifti_tool -nifti_hist".
The library version can be viewed via "nifti_tool -nifti_ver". */ /* changes by Oliver Granert: - change HAVE_ZLIB to HAVE_LIBZ to fit autoconf tests */ /*! global history and version strings, for printing */ static char * gni_history[] = { "----------------------------------------------------------------------\n" "history (of nifti library changes):\n" "\n", "0.0 August, 2003 [rwcox]\n" " (Robert W Cox of the National Institutes of Health, SSCC/DIRP/NIMH)\n" " - initial version\n" "\n", "0.1 July/August, 2004 [Mark Jenkinson]\n" " (FMRIB Centre, University of Oxford, UK)\n" " - Mainly adding low-level IO and changing things to allow gzipped\n" " files to be read and written\n" " - Full backwards compatability should have been maintained\n" "\n", "0.2 16 Nov 2004 [rickr]\n" " (Rick Reynolds of the National Institutes of Health, SSCC/DIRP/NIMH)\n" " - included Mark's changes in the AFNI distribution (including znzlib/)\n" " (HAVE_LIBZ is commented out for the standard distribution)\n" " - modified nifti_validfilename() and nifti_makebasename()\n" " - added nifti_find_file_extension()\n" "\n", "0.3 3 Dec 2004 [rickr]\n" " - note: header extensions are not yet checked for\n" " - added formatted history as global string, for printing\n" " - added nifti_disp_lib_hist(), to display the nifti library history\n" " - added nifti_disp_lib_version(), to display the nifti library history\n", " - re-wrote nifti_findhdrname()\n" " o used nifti_find_file_extension()\n" " o changed order of file tests (default is .nii, depends on input)\n" " o free hdrname on failure\n" " - made similar changes to nifti_findimgname()\n" " - check for NULL return from nifti_findhdrname() calls\n", " - removed most of ERREX() macros\n" " - modified nifti_image_read()\n" " o added debug info and error checking (on gni_debug > 0, only)\n" " o fail if workingname is NULL\n" " o check for failure to open header file\n" " o free workingname on failure\n" " o check for failure of nifti_image_load()\n" " o check for failure of nifti_convert_nhdr2nim()\n", " - changed nifti_image_load() to int, and check nifti_read_buffer return\n" " - changed nifti_read_buffer() to fail on short read, and to count float\n" " fixes (to print on debug)\n" " - changed nifti_image_infodump to print to stderr\n" " - updated function header comments, or moved comments above header\n" " - removed const keyword\n" " - added LNI_FERR() macro for error reporting on input files\n" "\n", "0.4 10 Dec 2004 [rickr] - added header extensions\n" " - in nifti1_io.h:\n" " o added num_ext and ext_list to the definition of nifti_image\n" " o made many functions static (more to follow)\n" " o added LNI_MAX_NIA_EXT_LEN, for max nifti_type 3 extension length\n", " - added __DATE__ to version output in nifti_disp_lib_version()\n" " - added nifti_disp_matrix_orient() to print orientation information\n" " - added '.nia' as a valid file extension in nifti_find_file_extension()\n" " - added much more debug output\n" " - in nifti_image_read(), in the case of an ASCII header, check for\n" " extensions after the end of the header\n", " - added nifti_read_extensions() function\n" " - added nifti_read_next_extension() function\n" " - added nifti_add_exten_to_list() function\n" " - added nifti_check_extension() function\n" " - added nifti_write_extensions() function\n" " - added nifti_extension_size() function\n" " - in nifti_set_iname_offest():\n" " o adjust offset by the extension size and the extender size\n", " o fixed the 'ceiling modulo 16' computation\n" " - in nifti_image_write_hdr_img2(): \n" " o added extension writing\n" " o check for NULL return from nifti_findimgname()\n" " - include number of extensions in nifti_image_to_ascii() output\n" " - in nifti_image_from_ascii():\n" " o return bytes_read as a parameter, computed from the final spos\n" " o extract num_ext from ASCII header\n" "\n", "0.5 14 Dec 2004 [rickr] - added sub-brick reading functions\n" " - added nifti_brick_list type to nifti1_io.h, along with new prototypes\n" " - added main nifti_image_read_bricks() function, with description\n" " - added nifti_image_load_bricks() - library function (requires nim)\n" " - added valid_nifti_brick_list() - library function\n" " - added free_NBL() - library function\n", " - added update_nifti_image_for_brick_list() for dimension update\n" " - added nifti_load_NBL_bricks(), nifti_alloc_NBL_mem(),\n" " nifti_copynsort() and force_positive() (static functions)\n" " - in nifti_image_read(), check for failed load only if read_data is set\n" " - broke most of nifti_image_load() into nifti_image_load_prep()\n" "\n", "0.6 15 Dec 2004 [rickr] - added sub-brick writing functionality\n" " - in nifti1_io.h, removed znzlib directory from include - all nifti\n" " library files are now under the nifti directory\n" " - nifti_read_extensions(): print no offset warning for nifti_type 3\n" " - nifti_write_all_data():\n" " o pass nifti_brick_list * NBL, for optional writing\n" " o if NBL, write each sub-brick, sequentially\n", " - nifti_set_iname_offset(): case 1 must have sizeof() cast to int\n" " - pass NBL to nifti_image_write_hdr_img2(), and allow NBL or data\n" " - added nifti_image_write_bricks() wrapper for ...write_hdr_img2()\n" " - included compression abilities\n" "\n", "0.7 16 Dec 2004 [rickr] - minor changes to extension reading\n" "\n", "0.8 21 Dec 2004 [rickr] - restrict extension reading, and minor changes\n" " - in nifti_image_read(), compute bytes for extensions (see remaining)\n" " - in nifti_read_extensions(), pass 'remain' as space for extensions,\n" " pass it to nifti_read_next_ext(), and update for each one read \n" " - in nifti_check_extension(), require (size <= remain)\n", " - in update_nifti_image_brick_list(), update nvox\n" " - in nifti_image_load_bricks(), make explicit check for nbricks <= 0\n" " - in int_force_positive(), check for (!list)\n" " - in swap_nifti_header(), swap sizeof_hdr, and reorder to struct order\n" " - change get_filesize functions to signed ( < 0 is no file or error )\n", " - in nifti_validfilename(), lose redundant (len < 0) check\n" " - make print_hex_vals() static\n" " - in disp_nifti_1_header, restrict string field widths\n" "\n", "0.9 23 Dec 2004 [rickr] - minor changes\n" " - broke ASCII header reading out of nifti_image_read(), into new\n" " functions has_ascii_header() and read_ascii_image()\n", " - check image_read failure and znzseek failure\n" " - altered some debug output\n" " - nifti_write_all_data() now returns an int\n" "\n", "0.10 29 Dec 2004 [rickr]\n" " - renamed nifti_valid_extension() to nifti_check_extension()\n" " - added functions nifti_makehdrname() and nifti_makeimgname()\n" " - added function valid_nifti_extensions()\n" " - in nifti_write_extensions(), check for validity before writing\n", " - rewrote nifti_image_write_hdr_img2():\n" " o set write_data and leave_open flags from write_opts\n" " o add debug print statements\n" " o use nifti_write_ascii_image() for the ascii case\n" " o rewrote the logic of all cases to be easier to follow\n", " - broke out code as nifti_write_ascii_image() function\n" " - added debug to top-level write functions, and free the znzFile\n" " - removed unused internal function nifti_image_open()\n" "\n", "0.11 30 Dec 2004 [rickr] - small mods\n" " - moved static function prototypes from header to C file\n" " - free extensions in nifti_image_free()\n" "\n", "1.0 07 Jan 2005 [rickr] - INITIAL RELEASE VERSION\n" " - added function nifti_set_filenames()\n" " - added function nifti_read_header()\n" " - added static function nhdr_looks_good()\n" " - added static function need_nhdr_swap()\n" " - exported nifti_add_exten_to_list symbol\n", " - fixed #bytes written in nifti_write_extensions()\n" " - only modify offset if it is too small (nifti_set_iname_offset)\n" " - added nifti_type 3 to nifti_makehdrname and nifti_makeimgname\n" " - added function nifti_set_filenames()\n" "\n", "1.1 07 Jan 2005 [rickr]\n" " - in nifti_read_header(), swap if needed\n" "\n", "1.2 07 Feb 2005 [kate fissell c/o rickr] \n" " - nifti1.h: added doxygen comments for main struct and #define groups\n" " - nifti1_io.h: added doxygen comments for file and nifti_image struct\n" " - nifti1_io.h: added doxygen comments for file and some functions\n" " - nifti1_io.c: changed nifti_copy_nim_info to use memcpy\n" "\n", "1.3 09 Feb 2005 [rickr]\n" " - nifti1.h: added doxygen comments for extension structs\n" " - nifti1_io.h: put most #defines in #ifdef _NIFTI1_IO_C_ block\n" " - added a doxygen-style description to every exported function\n" " - added doxygen-style comments within some functions\n" " - re-exported many znzFile functions that I had made static\n" " - re-added nifti_image_open (sorry, Mark)\n" " - every exported function now has 'nifti' in the name (19 functions)\n", " - made sure every alloc() has a failure test\n" " - added nifti_copy_extensions function, for use in nifti_copy_nim_info\n" " - nifti_is_gzfile: added initial strlen test\n" " - nifti_set_filenames: added set_byte_order parameter option\n" " (it seems appropriate to set the BO when new files are associated)\n" " - disp_nifti_1_header: prints to stdout (a.o.t. stderr), with fflush\n" "\n", "1.4 23 Feb 2005 [rickr] - sourceforge merge\n" " - merged into the nifti_io CVS directory structure at sourceforge.net\n" " - merged in 4 changes by Mark, and re-added his const keywords\n" " - cast some pointers to (void *) for -pedantic compile option\n" " - added nifti_free_extensions()\n" "\n", "1.5 02 Mar 2005 [rickr] - started nifti global options\n" " - gni_debug is now g_opts.debug\n" " - added validity check parameter to nifti_read_header\n" " - need_nhdr_swap no longer does test swaps on the stack\n" "\n", "1.6 05 April 2005 [rickr] - validation and collapsed_image_read\n" " - added nifti_read_collapsed_image(), an interface for reading partial\n" " datasets, specifying a subset of array indices\n" " - for read_collapsed_image, added static functions: rci_read_data(),\n" " rci_alloc_mem(), and make_pivot_list()\n", " - added nifti_nim_is_valid() to check for consistency (more to do)\n" " - added nifti_nim_has_valid_dims() to do many dimensions tests\n" "\n", "1.7 08 April 2005 [rickr]\n" " - added nifti_update_dims_from_array() - to update dimensions\n" " - modified nifti_makehdrname() and nifti_makeimgname():\n" " if prefix has a valid extension, use it (else make one up)\n" " - added nifti_get_intlist - for making an array of ints\n" " - fixed init of NBL->bsize in nifti_alloc_NBL_mem() {thanks, Bob}\n" "\n", "1.8 14 April 2005 [rickr]\n" " - added nifti_set_type_from_names(), for nifti_set_filenames()\n" " (only updates type if number of files does not match it)\n" " - added is_valid_nifti_type(), just to be sure\n" " - updated description of nifti_read_collapsed_image() for *data change\n" " (if *data is already set, assume memory exists for results)\n" " - modified rci_alloc_mem() to allocate only if *data is NULL\n" "\n", "1.9 19 April 2005 [rickr]\n" " - added extension codes NIFTI_ECODE_COMMENT and NIFTI_ECODE_XCEDE\n" " - added nifti_type codes NIFTI_MAX_ECODE and NIFTI_MAX_FTYPE\n" " - added nifti_add_extension() {exported}\n" " - added nifti_fill_extension() as a static function\n" " - added nifti_is_valid_ecode() {exported}\n", " - nifti_type values are now NIFTI_FTYPE_* file codes\n" " - in nifti_read_extensions(), decrement 'remain' by extender size, 4\n" " - in nifti_set_iname_offset(), case 1, update if offset differs\n" " - only output '-d writing nifti file' if debug > 1\n" "\n", "1.10 10 May 2005 [rickr]\n" " - files are read using ZLIB only if they end in '.gz'\n" "\n", "1.11 12 August 2005 [kate fissell]\n" " - Kate's 0.2 release packaging, for sourceforge\n" "\n", "1.12 17 August 2005 [rickr] - comment (doxygen) updates\n" " - updated comments for most functions (2 updates from Cinly Ooi)\n" " - added nifti_type_and_names_match()\n" "\n", "1.12a 24 August 2005 [rickr] - remove all tabs from Clibs/*/*.[ch]\n", "1.12b 25 August 2005 [rickr] - changes by Hans Johnson\n", "1.13 25 August 2005 [rickr]\n", " - finished changes by Hans for Insight\n" " - added const in all appropraite parameter locations (30-40)\n" " (any pointer referencing data that will not change)\n" " - shortened all string constants below 509 character limit\n" "1.14 28 October 2005 [HJohnson]\n", " - use nifti_set_filenames() in nifti_convert_nhdr2nim()\n" "1.15 02 November 2005 [rickr]\n", " - added skip_blank_ext to nifti_global_options\n" " - added nifti_set_skip_blank_ext(), to set option\n" " - if skip_blank_ext and no extensions, do not read/write extender\n" "1.16 18 November 2005 [rickr]\n", " - removed any test or access of dim[i], i>dim[0]\n" " - do not set pixdim for collapsed dims to 1.0, leave them as they are\n" " - added magic and dim[i] tests in nifti_hdr_looks_good()\n" " - added 2 size_t casts\n" "1.17 22 November 2005 [rickr]\n", " - in hdr->nim, for i > dim[0], pass 0 or 1, else set to 1\n" "1.18 02 March 2006 [rickr]\n", " - in nifti_alloc_NBL_mem(), fixed nt=0 case from 1.17 change\n" "1.19 23 May 2006 [HJohnson,rickr]\n", " - nifti_write_ascii_image(): free(hstr)\n" " - nifti_copy_extensions(): clear num_ext and ext_list\n" "1.20 27 Jun 2006 [rickr]\n", " - nifti_findhdrname(): fixed assign of efirst to match stated logic\n" " (problem found by Atle Bjørnerud)\n" "1.21 05 Sep 2006 [rickr] update for nifticlib-0.4 release\n", " - was reminded to actually add nifti_set_skip_blank_ext()\n" " - init g_opts.skip_blank_ext to 0\n" "1.22 01 Jun 2007 nifticlib-0.5 release\n", "1.23 05 Jun 2007 nifti_add_exten_to_list: revert on failure, free old list\n" "1.24 07 Jun 2007 nifti_copy_extensions: use esize-8 for data size\n" "1.25 12 Jun 2007 [rickr] EMPTY_IMAGE creation\n", " - added nifti_make_new_header() - to create from dims/dtype\n" " - added nifti_make_new_nim() - to create from dims/dtype/fill\n" " - added nifti_is_valid_datatype(), and more debug info\n", "1.26 27 Jul 2007 [rickr] handle single volumes > 2^31 bytes (but < 2^32)\n", "1.27 28 Jul 2007 [rickr] nim->nvox, NBL-bsize are now type size_t\n" "1.28 30 Jul 2007 [rickr] size_t updates\n", "1.29 08 Aug 2007 [rickr] for list, valid_nifti_brick_list requires 3 dims\n" "1.30 08 Nov 2007 [Yaroslav/rickr]\n" " - fix ARM struct alignment problem in byte-swapping routines\n", "1.31 29 Nov 2007 [rickr] for nifticlib-1.0.0\n" " - added nifti_datatype_to/from_string routines\n" " - added DT_RGBA32/NIFTI_TYPE_RGBA32 datatype macros (2304)\n" " - added NIFTI_ECODE_FREESURFER (14)\n", "1.32 08 Dec 2007 [rickr]\n" " - nifti_hdr_looks_good() allows ANALYZE headers (req. by V. Luccio)\n" " - added nifti_datatype_is_valid()\n", "1.33 05 Feb 2008 [hansj,rickr] - block nia.gz use\n" "1.34 13 Jun 2008 [rickr] - added nifti_compiled_with_zlib()\n" "1.35 03 Aug 2008 [rickr]\n", " - deal with swapping, so that CPU type does not affect output\n" " (motivated by C Burns)\n" " - added nifti_analyze75 structure and nifti_swap_as_analyze()\n" " - previous swap_nifti_header is saved as old_swap_nifti_header\n" " - also swap UNUSED fields in nifti_1_header struct\n", "1.36 07 Oct 2008 [rickr]\n", " - added nifti_NBL_matches_nim() check for write_bricks()\n" "1.37 10 Mar 2009 [rickr]\n", " - H Johnson cast updates (06 Feb)\n" " - added NIFTI_ECODE_PYPICKLE for PyNIfTI (06 Feb)\n" " - added NIFTI_ECODEs 18-28 for the LONI MiND group\n" "1.38 28 Apr 2009 [rickr]\n", " - uppercase extensions are now valid (requested by M. Coursolle)\n" " - nifti_set_allow_upper_fext controls this option (req by C. Ooi)\n" "1.39 23 Jun 2009 [rickr]: added 4 checks of alloc() returns\n", "1.40 16 Mar 2010 [rickr]: added NIFTI_ECODE_VOXBO for D. Kimberg\n", "1.41 28 Apr 2010 [rickr]: added NIFTI_ECODE_CARET for J. Harwell\n", "1.42 06 Jul 2010 [rickr]: trouble with large (gz) files\n", " - noted/investigated by M Hanke and Y Halchenko\n" " - fixed znzread/write, noting example by M Adler\n" " - changed nifti_swap_* routines/calls to take size_t (6)\n" "1.43 07 Jul 2010 [rickr]: fixed znzR/W to again return nmembers\n", "1.43r 09 Jan 2013 [oliverg]: replace outputs to stdout and stderr by \n", " Rprintf and REprintf\n", "----------------------------------------------------------------------\n" }; static char gni_version[] = "nifti library version 1.43r (9 Jan, 2013)"; /*! global nifti options structure - init with defaults */ static nifti_global_options g_opts = { 1, /* debug level */ 0, /* skip_blank_ext - skip extender if no extensions */ 1 /* allow_upper_fext - allow uppercase file extensions */ }; /*! global nifti types structure list (per type, ordered oldest to newest) */ static nifti_type_ele nifti_type_list[] = { /* type nbyper swapsize name */ { 0, 0, 0, "DT_UNKNOWN" }, { 0, 0, 0, "DT_NONE" }, { 1, 0, 0, "DT_BINARY" }, /* not usable */ { 2, 1, 0, "DT_UNSIGNED_CHAR" }, { 2, 1, 0, "DT_UINT8" }, { 2, 1, 0, "NIFTI_TYPE_UINT8" }, { 4, 2, 2, "DT_SIGNED_SHORT" }, { 4, 2, 2, "DT_INT16" }, { 4, 2, 2, "NIFTI_TYPE_INT16" }, { 8, 4, 4, "DT_SIGNED_INT" }, { 8, 4, 4, "DT_INT32" }, { 8, 4, 4, "NIFTI_TYPE_INT32" }, { 16, 4, 4, "DT_FLOAT" }, { 16, 4, 4, "DT_FLOAT32" }, { 16, 4, 4, "NIFTI_TYPE_FLOAT32" }, { 32, 8, 4, "DT_COMPLEX" }, { 32, 8, 4, "DT_COMPLEX64" }, { 32, 8, 4, "NIFTI_TYPE_COMPLEX64" }, { 64, 8, 8, "DT_DOUBLE" }, { 64, 8, 8, "DT_FLOAT64" }, { 64, 8, 8, "NIFTI_TYPE_FLOAT64" }, { 128, 3, 0, "DT_RGB" }, { 128, 3, 0, "DT_RGB24" }, { 128, 3, 0, "NIFTI_TYPE_RGB24" }, { 255, 0, 0, "DT_ALL" }, { 256, 1, 0, "DT_INT8" }, { 256, 1, 0, "NIFTI_TYPE_INT8" }, { 512, 2, 2, "DT_UINT16" }, { 512, 2, 2, "NIFTI_TYPE_UINT16" }, { 768, 4, 4, "DT_UINT32" }, { 768, 4, 4, "NIFTI_TYPE_UINT32" }, { 1024, 8, 8, "DT_INT64" }, { 1024, 8, 8, "NIFTI_TYPE_INT64" }, { 1280, 8, 8, "DT_UINT64" }, { 1280, 8, 8, "NIFTI_TYPE_UINT64" }, { 1536, 16, 16, "DT_FLOAT128" }, { 1536, 16, 16, "NIFTI_TYPE_FLOAT128" }, { 1792, 16, 8, "DT_COMPLEX128" }, { 1792, 16, 8, "NIFTI_TYPE_COMPLEX128" }, { 2048, 32, 16, "DT_COMPLEX256" }, { 2048, 32, 16, "NIFTI_TYPE_COMPLEX256" }, { 2304, 4, 0, "DT_RGBA32" }, { 2304, 4, 0, "NIFTI_TYPE_RGBA32" }, }; /*---------------------------------------------------------------------------*/ /* prototypes for internal functions - not part of exported library */ /* extension routines */ static int nifti_read_extensions( nifti_image *nim, znzFile fp, int remain ); static int nifti_read_next_extension( nifti1_extension * nex, nifti_image *nim, int remain, znzFile fp ); static int nifti_check_extension(nifti_image *nim, int size,int code, int rem); static void update_nifti_image_for_brick_list(nifti_image * nim , int nbricks); static int nifti_add_exten_to_list(nifti1_extension * new_ext, nifti1_extension ** list, int new_length); static int nifti_fill_extension(nifti1_extension * ext, const char * data, int len, int ecode); /* NBL routines */ static int nifti_load_NBL_bricks(nifti_image * nim , int * slist, int * sindex, nifti_brick_list * NBL, znzFile fp ); static int nifti_alloc_NBL_mem( nifti_image * nim, int nbricks, nifti_brick_list * nbl); static int nifti_copynsort(int nbricks, const int *blist, int **slist, int **sindex); static int nifti_NBL_matches_nim(const nifti_image *nim, const nifti_brick_list *NBL); /* for nifti_read_collapsed_image: */ static int rci_read_data(nifti_image *nim, int *pivots, int *prods, int nprods, const int dims[], char *data, znzFile fp, size_t base_offset); static int rci_alloc_mem(void ** data, int prods[8], int nprods, int nbyper ); static int make_pivot_list(nifti_image * nim, const int dims[], int pivots[], int prods[], int * nprods ); /* misc */ static int compare_strlist (const char * str, char ** strlist, int len); static int fileext_compare (const char * test_ext, const char * known_ext); static int fileext_n_compare (const char * test_ext, const char * known_ext, int maxlen); static int is_mixedcase (const char * str); static int is_uppercase (const char * str); static int make_lowercase (char * str); static int make_uppercase (char * str); static int need_nhdr_swap (short dim0, int hdrsize); static int print_hex_vals (const char * data, int nbytes/*, FILE * fp*/); static int unescape_string (char *str); /* string utility functions */ static char *escapize_string (const char *str); /* internal I/O routines */ static znzFile nifti_image_load_prep( nifti_image *nim ); static int has_ascii_header(znzFile fp); /*---------------------------------------------------------------------------*/ /* for calling from some main program */ /*----------------------------------------------------------------------*/ /*! display the nifti library module history (via stdout) *//*--------------------------------------------------------------------*/ void nifti_disp_lib_hist( void ) { int c, len = sizeof(gni_history)/sizeof(char *); for( c = 0; c < len; c++ ) Rprintf(gni_history[c]); } /*----------------------------------------------------------------------*/ /*! display the nifti library version (via stdout) *//*--------------------------------------------------------------------*/ /* replaced for use in R by function "const char *nifti_lib_version( void )" void nifti_disp_lib_version( void ) { printf("%s, compiled %s\n", gni_version, __DATE__); }*/ /*----------------------------------------------------------------------*/ /*! return the nifti library version (via constant string) *//*--------------------------------------------------------------------*/ const char *nifti_lib_version( void ) { return gni_version; } /*----------------------------------------------------------------------*/ /*! nifti_image_read_bricks - read nifti data as array of bricks * * 13 Dec 2004 [rickr] * * \param hname - filename of dataset to read (must be valid) * \param nbricks - number of sub-bricks to read * (if blist is valid, nbricks must be > 0) * \param blist - list of sub-bricks to read * (can be NULL; if NULL, read complete dataset) * \param NBL - pointer to empty nifti_brick_list struct * (must be a valid pointer) * * \return *
nim - same as nifti_image_read, but * nim->nt = NBL->nbricks (or nt*nu*nv*nw) * nim->nu,nv,nw = 1 * nim->data = NULL *
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: * *
 * { 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);
 * }
 * 
* * Here, nim_orig gets the entire dataset, where NB_orig.nbricks = 12. But * nim_select has NB_select.nbricks = 5. * * Note that the first case is not quite the same as just calling the * nifti_image_read function, as here the data is separated into sub-bricks. * * Note that valid blist elements are in [0..nt*nu*nv*nw-1], * or written [ 0 .. (dim[4]*dim[5]*dim[6]*dim[7] - 1) ]. * * Note that, as is the case with all of the reading functions, the * data will be allocated, read in, and properly byte-swapped, if * necessary. * * \sa nifti_image_load_bricks, nifti_free_NBL, valid_nifti_brick_list, nifti_image_read *//*----------------------------------------------------------------------*/ nifti_image *nifti_image_read_bricks(const char * hname, int nbricks, const int * blist, nifti_brick_list * NBL) { nifti_image * nim; if( !hname || !NBL ){ REprintf("** nifti_image_read_bricks: bad params (%p,%p)\n", hname, (void *)NBL); return NULL; } if( blist && nbricks <= 0 ){ REprintf("** nifti_image_read_bricks: bad nbricks, %d\n", nbricks); return NULL; } nim = nifti_image_read(hname, 0); /* read header, but not data */ if( !nim ) return NULL; /* errors were already printed */ /* if we fail, free image and return */ if( nifti_image_load_bricks(nim, nbricks, blist, NBL) <= 0 ){ nifti_image_free(nim); return NULL; } if( blist ) update_nifti_image_for_brick_list(nim, nbricks); return nim; } /*---------------------------------------------------------------------- * update_nifti_image_for_brick_list - update nifti_image * * When loading a specific brick list, the distinction between * nt, nu, nv and nw is lost. So put everything in t, and set * dim[0] = 4. *----------------------------------------------------------------------*/ static void update_nifti_image_for_brick_list( nifti_image * nim , int nbricks ) { int ndim; if( g_opts.debug > 2 ){ REprintf("+d updating image dimensions for %d bricks in list\n", nbricks); REprintf(" ndim = %d\n",nim->ndim); REprintf(" nx,ny,nz,nt,nu,nv,nw: (%d,%d,%d,%d,%d,%d,%d)\n", nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw); } nim->nt = nbricks; nim->nu = nim->nv = nim->nw = 1; nim->dim[4] = nbricks; nim->dim[5] = nim->dim[6] = nim->dim[7] = 1; /* compute nvox */ /* do not rely on dimensions above dim[0] 16 Nov 2005 [rickr] */ for( nim->nvox = 1, ndim = 1; ndim <= nim->dim[0]; ndim++ ) nim->nvox *= nim->dim[ndim]; /* update the dimensions to 4 or lower */ for( ndim = 4; (ndim > 1) && (nim->dim[ndim] <= 1); ndim-- ) ; if( g_opts.debug > 2 ){ REprintf("+d ndim = %d -> %d\n",nim->ndim, ndim); REprintf(" --> (%d,%d,%d,%d,%d,%d,%d)\n", nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw); } nim->dim[0] = nim->ndim = ndim; } /*----------------------------------------------------------------------*/ /*! nifti_update_dims_from_array - update nx, ny, ... from nim->dim[] Fix all the dimension information, based on a new nim->dim[]. Note: we assume that dim[0] will not increase. Check for updates to pixdim[], dx,..., nx,..., nvox, ndim, dim[0]. *//*--------------------------------------------------------------------*/ int nifti_update_dims_from_array( nifti_image * nim ) { int c, ndim; if( !nim ){ REprintf("** update_dims: missing nim\n"); return 1; } if( g_opts.debug > 2 ){ REprintf("+d updating image dimensions given nim->dim:"); for( c = 0; c < 8; c++ ) REprintf(" %d", nim->dim[c]); REprintf("\n");/*fputc('\n',stderr);*/ } /* verify dim[0] first */ if(nim->dim[0] < 1 || nim->dim[0] > 7){ REprintf("** invalid dim[0], dim[] = "); for( c = 0; c < 8; c++ ) REprintf(" %d", nim->dim[c]); REprintf("\n");/*fputc('\n',stderr);*/ return 1; } /* set nx, ny ..., dx, dy, ..., one by one */ /* less than 1, set to 1, else copy */ if(nim->dim[1] < 1) nim->nx = nim->dim[1] = 1; else nim->nx = nim->dim[1]; nim->dx = nim->pixdim[1]; /* if undefined, or less than 1, set to 1 */ if(nim->dim[0] < 2 || (nim->dim[0] >= 2 && nim->dim[2] < 1)) nim->ny = nim->dim[2] = 1; else nim->ny = nim->dim[2]; /* copy delta values, in any case */ nim->dy = nim->pixdim[2]; if(nim->dim[0] < 3 || (nim->dim[0] >= 3 && nim->dim[3] < 1)) nim->nz = nim->dim[3] = 1; else /* just copy vals from arrays */ nim->nz = nim->dim[3]; nim->dz = nim->pixdim[3]; if(nim->dim[0] < 4 || (nim->dim[0] >= 4 && nim->dim[4] < 1)) nim->nt = nim->dim[4] = 1; else /* just copy vals from arrays */ nim->nt = nim->dim[4]; nim->dt = nim->pixdim[4]; if(nim->dim[0] < 5 || (nim->dim[0] >= 5 && nim->dim[5] < 1)) nim->nu = nim->dim[5] = 1; else /* just copy vals from arrays */ nim->nu = nim->dim[5]; nim->du = nim->pixdim[5]; if(nim->dim[0] < 6 || (nim->dim[0] >= 6 && nim->dim[6] < 1)) nim->nv = nim->dim[6] = 1; else /* just copy vals from arrays */ nim->nv = nim->dim[6]; nim->dv = nim->pixdim[6]; if(nim->dim[0] < 7 || (nim->dim[0] >= 7 && nim->dim[7] < 1)) nim->nw = nim->dim[7] = 1; else /* just copy vals from arrays */ nim->nw = nim->dim[7]; nim->dw = nim->pixdim[7]; for( c = 1, nim->nvox = 1; c <= nim->dim[0]; c++ ) nim->nvox *= nim->dim[c]; /* compute ndim, assuming it can be no larger than the old one */ for( ndim = nim->dim[0]; (ndim > 1) && (nim->dim[ndim] <= 1); ndim-- ) ; if( g_opts.debug > 2 ){ REprintf("+d ndim = %d -> %d\n",nim->ndim, ndim); REprintf(" --> (%d,%d,%d,%d,%d,%d,%d)\n", nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw); } nim->dim[0] = nim->ndim = ndim; return 0; } /*----------------------------------------------------------------------*/ /*! Load the image data from disk into an already-prepared image struct. * * \param nim - initialized nifti_image, without data * \param nbricks - the length of blist (must be 0 if blist is NULL) * \param blist - an array of xyz volume indices to read (can be NULL) * \param NBL - pointer to struct where resulting data will be stored * * If blist is NULL, read all sub-bricks. * * \return the number of loaded bricks (NBL->nbricks), * 0 on failure, < 0 on error * * NOTE: it is likely that another function will copy the data pointers * out of NBL, in which case the only pointer the calling function * will want to free is NBL->bricks (not each NBL->bricks[i]). *//*--------------------------------------------------------------------*/ int nifti_image_load_bricks( nifti_image * nim , int nbricks, const int * blist, nifti_brick_list * NBL ) { int * slist = NULL, * sindex = NULL, rv; znzFile fp; /* we can have blist == NULL */ if( !nim || !NBL ){ REprintf("** nifti_image_load_bricks, bad params (%p,%p)\n", (void *)nim, (void *)NBL); return -1; } if( blist && nbricks <= 0 ){ if( g_opts.debug > 1 ) REprintf("-d load_bricks: received blist with nbricks = %d," "ignoring blist\n", nbricks); blist = NULL; /* pretend nothing was passed */ } if( blist && ! valid_nifti_brick_list(nim, nbricks, blist, g_opts.debug>0) ) return -1; /* for efficiency, let's read the file in order */ if( blist && nifti_copynsort( nbricks, blist, &slist, &sindex ) != 0 ) return -1; /* open the file and position the FILE pointer */ fp = nifti_image_load_prep( nim ); if( !fp ){ if( g_opts.debug > 0 ) REprintf("** nifti_image_load_bricks, failed load_prep\n"); if( blist ){ free(slist); free(sindex); } return -1; } /* this will flag to allocate defaults */ if( !blist ) nbricks = 0; if( nifti_alloc_NBL_mem( nim, nbricks, NBL ) != 0 ){ if( blist ){ free(slist); free(sindex); } znzclose(fp); return -1; } rv = nifti_load_NBL_bricks(nim, slist, sindex, NBL, fp); if( rv != 0 ){ nifti_free_NBL( NBL ); /* failure! */ NBL->nbricks = 0; /* repetative, but clear */ } if( slist ){ free(slist); free(sindex); } znzclose(fp); return NBL->nbricks; } /*----------------------------------------------------------------------*/ /*! nifti_free_NBL - free all pointers and clear structure * * note: this does not presume to free the structure pointer *//*--------------------------------------------------------------------*/ void nifti_free_NBL( nifti_brick_list * NBL ) { int c; if( NBL->bricks ){ for( c = 0; c < NBL->nbricks; c++ ) if( NBL->bricks[c] ) free(NBL->bricks[c]); free(NBL->bricks); NBL->bricks = NULL; } NBL->bsize = NBL->nbricks = 0; } /*---------------------------------------------------------------------- * nifti_load_NBL_bricks - read the file data into the NBL struct * * return 0 on success, -1 on failure *----------------------------------------------------------------------*/ static int nifti_load_NBL_bricks( nifti_image * nim , int * slist, int * sindex, nifti_brick_list * NBL, znzFile fp ) { size_t oposn, fposn; /* orig and current file positions */ size_t rv; long test; int c; int prev, isrc, idest; /* previous and current sub-brick, and new index */ test = znztell(fp); /* store current file position */ if( test < 0 ){ REprintf("** load bricks: ztell failed??\n"); return -1; } fposn = oposn = test; /* first, handle the default case, no passed blist */ if( !slist ){ for( c = 0; c < NBL->nbricks; c++ ) { rv = nifti_read_buffer(fp, NBL->bricks[c], NBL->bsize, nim); if( rv != NBL->bsize ){ REprintf("** load bricks: cannot read brick %d from '%s'\n", c, nim->iname ? nim->iname : nim->fname); return -1; } } if( g_opts.debug > 1 ) REprintf("+d read %d default %u-byte bricks from file %s\n", NBL->nbricks, (unsigned int)NBL->bsize, nim->iname ? nim->iname:nim->fname ); return 0; } if( !sindex ){ REprintf("** load_NBL_bricks: missing index list\n"); return -1; } prev = -1; /* use prev for previous sub-brick */ for( c = 0; c < NBL->nbricks; c++ ){ isrc = slist[c]; /* this is original brick index (c is new one) */ idest = sindex[c]; /* this is the destination index for this data */ /* if this sub-brick is not the previous, we must read from disk */ if( isrc != prev ){ /* if we are not looking at the correct sub-brick, scan forward */ if( fposn != (oposn + isrc*NBL->bsize) ){ fposn = oposn + isrc*NBL->bsize; if( znzseek(fp, (long)fposn, SEEK_SET) < 0 ){ REprintf("** failed to locate brick %d in file '%s'\n", isrc, nim->iname ? nim->iname : nim->fname); return -1; } } /* only 10,000 lines later and we're actually reading something! */ rv = nifti_read_buffer(fp, NBL->bricks[idest], NBL->bsize, nim); if( rv != NBL->bsize ){ REprintf("** failed to read brick %d from file '%s'\n", isrc, nim->iname ? nim->iname : nim->fname); if( g_opts.debug > 1 ) REprintf(" (read %u of %u bytes)\n", (unsigned int)rv, (unsigned int)NBL->bsize); return -1; } fposn += NBL->bsize; } else { /* we have already read this sub-brick, just copy the previous one */ /* note that this works because they are sorted */ memcpy(NBL->bricks[idest], NBL->bricks[sindex[c-1]], NBL->bsize); } prev = isrc; /* in any case, note the now previous sub-brick */ } return 0; } /*---------------------------------------------------------------------- * nifti_alloc_NBL_mem - allocate memory for bricks * * return 0 on success, -1 on failure *----------------------------------------------------------------------*/ static int nifti_alloc_NBL_mem(nifti_image * nim, int nbricks, nifti_brick_list * nbl) { int c; /* if nbricks is not specified, use the default */ if( nbricks > 0 ) nbl->nbricks = nbricks; else { /* I missed this one with the 1.17 change 02 Mar 2006 [rickr] */ nbl->nbricks = 1; for( c = 4; c <= nim->ndim; c++ ) nbl->nbricks *= nim->dim[c]; } nbl->bsize = (size_t)nim->nx * nim->ny * nim->nz * nim->nbyper;/* bytes */ nbl->bricks = (void **)malloc(nbl->nbricks * sizeof(void *)); if( ! nbl->bricks ){ REprintf("** NANM: failed to alloc %d void ptrs\n",nbricks); return -1; } for( c = 0; c < nbl->nbricks; c++ ){ nbl->bricks[c] = (void *)malloc(nbl->bsize); if( ! nbl->bricks[c] ){ REprintf("** NANM: failed to alloc %u bytes for brick %d\n", (unsigned int)nbl->bsize, c); /* so free and clear everything before returning */ while( c > 0 ){ c--; free(nbl->bricks[c]); } free(nbl->bricks); nbl->bricks = NULL; nbl->bsize = nbl->nbricks = 0; return -1; } } if( g_opts.debug > 2 ) REprintf("+d NANM: alloc'd %d bricks of %u bytes for NBL\n", nbl->nbricks, (unsigned int)nbl->bsize); return 0; } /*---------------------------------------------------------------------- * nifti_copynsort - copy int list, and sort with indices * * 1. duplicate the incoming list * 2. create an sindex list, and init with 0..nbricks-1 * 3. do a slow insertion sort on the small slist, along with sindex list * 4. check results, just to be positive * * So slist is sorted, and sindex hold original positions. * * return 0 on success, -1 on failure *----------------------------------------------------------------------*/ static int nifti_copynsort(int nbricks, const int * blist, int ** slist, int ** sindex) { int * stmp, * itmp; /* for ease of typing/reading */ int c1, c2, spos, tmp; *slist = (int *)malloc(nbricks * sizeof(int)); *sindex = (int *)malloc(nbricks * sizeof(int)); if( !*slist || !*sindex ){ REprintf("** NCS: failed to alloc %d ints for sorting\n",nbricks); if(*slist) free(*slist); /* maybe one succeeded */ if(*sindex) free(*sindex); return -1; } /* init the lists */ memcpy(*slist, blist, nbricks*sizeof(int)); for( c1 = 0; c1 < nbricks; c1++ ) (*sindex)[c1] = c1; /* now actually sort slist */ stmp = *slist; itmp = *sindex; for( c1 = 0; c1 < nbricks-1; c1++ ) { /* find smallest value, init to current */ spos = c1; for( c2 = c1+1; c2 < nbricks; c2++ ) if( stmp[c2] < stmp[spos] ) spos = c2; if( spos != c1 ) /* swap: fine, don't maintain sub-order, see if I care */ { tmp = stmp[c1]; /* first swap the sorting values */ stmp[c1] = stmp[spos]; stmp[spos] = tmp; tmp = itmp[c1]; /* then swap the index values */ itmp[c1] = itmp[spos]; itmp[spos] = tmp; } } if( g_opts.debug > 2 ){ REprintf( "+d sorted indexing list:\n"); REprintf( " orig : "); for( c1 = 0; c1 < nbricks; c1++ ) REprintf( " %d",blist[c1]); REprintf("\n new : "); for( c1 = 0; c1 < nbricks; c1++ ) REprintf( " %d",stmp[c1]); REprintf("\n indices: "); for( c1 = 0; c1 < nbricks; c1++ ) REprintf( " %d",itmp[c1]); REprintf("\n"); /*fputc('\n', stderr);*/ } /* check the sort (why not? I've got time...) */ for( c1 = 0; c1 < nbricks-1; c1++ ){ if( (stmp[c1] > stmp[c1+1]) || (blist[itmp[c1]] != stmp[c1]) ){ REprintf("** sorting screw-up, way to go, rick!\n"); free(stmp); free(itmp); *slist = NULL; *sindex = NULL; return -1; } } if( g_opts.debug > 2 ) REprintf("-d sorting is okay\n"); return 0; } /*----------------------------------------------------------------------*/ /*! valid_nifti_brick_list - check sub-brick list for image * * This function verifies that nbricks and blist are appropriate * for use with this nim, based on the dimensions. * * \param nim nifti_image to check against * \param nbricks number of brick indices in blist * \param blist list of brick indices to check in nim * \param disp_error if this flag is set, report errors to user * * \return 1 if valid, 0 if not *//*--------------------------------------------------------------------*/ int valid_nifti_brick_list(nifti_image * nim , int nbricks, const int * blist, int disp_error) { int c, nsubs; if( !nim ){ if( disp_error || g_opts.debug > 0 ) REprintf("** valid_nifti_brick_list: missing nifti image\n"); return 0; } if( nbricks <= 0 || !blist ){ if( disp_error || g_opts.debug > 1 ) REprintf("** valid_nifti_brick_list: no brick list to check\n"); return 0; } if( nim->dim[0] < 3 ){ if( disp_error || g_opts.debug > 1 ) REprintf("** cannot read explict brick list from %d-D dataset\n", nim->dim[0]); return 0; } /* nsubs sub-brick is nt*nu*nv*nw */ for( c = 4, nsubs = 1; c <= nim->dim[0]; c++ ) nsubs *= nim->dim[c]; if( nsubs <= 0 ){ REprintf("** VNBL warning: bad dim list (%d,%d,%d,%d)\n", nim->dim[4], nim->dim[5], nim->dim[6], nim->dim[7]); return 0; } for( c = 0; c < nbricks; c++ ) if( (blist[c] < 0) || (blist[c] >= nsubs) ){ if( disp_error || g_opts.debug > 1 ) REprintf("** volume index %d (#%d) is out of range [0,%d]\n", blist[c], c, nsubs-1); return 0; } return 1; /* all is well */ } /*----------------------------------------------------------------------*/ /* verify that NBL struct is a valid data source for the image * * return 1 if so, 0 otherwise *//*--------------------------------------------------------------------*/ static int nifti_NBL_matches_nim(const nifti_image *nim, const nifti_brick_list *NBL) { size_t volbytes = 0; /* bytes per volume */ int ind, errs = 0, nvols = 0; if( !nim || !NBL ) { if( g_opts.debug > 0 ) REprintf("** nifti_NBL_matches_nim: NULL pointer(s)\n"); return 0; } /* for nim, compute volbytes and nvols */ if( nim->ndim > 0 ) { /* first 3 indices are over a single volume */ volbytes = (size_t)nim->nbyper; for( ind = 1; ind <= nim->ndim && ind < 4; ind++ ) volbytes *= (size_t)nim->dim[ind]; for( ind = 4, nvols = 1; ind <= nim->ndim; ind++ ) nvols *= nim->dim[ind]; } if( volbytes != NBL->bsize ) { if( g_opts.debug > 1 ) REprintf("** NBL/nim mismatch, volbytes = %u, %u\n", (unsigned)NBL->bsize, (unsigned)volbytes); errs++; } if( nvols != NBL->nbricks ) { if( g_opts.debug > 1 ) REprintf("** NBL/nim mismatch, nvols = %d, %d\n", NBL->nbricks, nvols); errs++; } if( errs ) return 0; else if ( g_opts.debug > 2 ) REprintf("-- nim/NBL agree: nvols = %d, nbytes = %u\n", nvols, (unsigned)volbytes); return 1; } /* end of new nifti_image_read_bricks() functionality */ /*----------------------------------------------------------------------*/ /*! display the orientation from the quaternian fields * * \param mesg if non-NULL, display this message first * \param mat the matrix to convert to "nearest" orientation * * \return -1 if results cannot be determined, 0 if okay *//*--------------------------------------------------------------------*/ int nifti_disp_matrix_orient( const char * mesg, mat44 mat ) { int i, j, k; if ( mesg ) Rprintf(mesg); /* use stdout? */ nifti_mat44_to_orientation( mat, &i,&j,&k ); if ( i <= 0 || j <= 0 || k <= 0 ) return -1; /* so we have good codes */ Rprintf(" i orientation = '%s'\n" " j orientation = '%s'\n" " k orientation = '%s'\n", nifti_orientation_string(i), nifti_orientation_string(j), nifti_orientation_string(k) ); return 0; } /*----------------------------------------------------------------------*/ /*! duplicate the given string (alloc length+1) * * \return allocated pointer (or NULL on failure) *//*--------------------------------------------------------------------*/ char *nifti_strdup(const char *str) { char *dup; if( !str ) return NULL; /* allow calls passing NULL */ dup = (char *)malloc(strlen(str) + 1); /* check for failure */ if( dup ) strcpy(dup, str); else REprintf("** nifti_strdup: failed to alloc %u bytes\n", (unsigned int)strlen(str)+1); return dup; } /*---------------------------------------------------------------------------*/ /*! Return a pointer to a string holding the name of a NIFTI datatype. \param dt NIfTI-1 datatype \return pointer to static string holding the datatype name \warning Do not free() or modify this string! It points to static storage. \sa NIFTI1_DATATYPES group in nifti1.h *//*-------------------------------------------------------------------------*/ char *nifti_datatype_string( int dt ) { switch( dt ){ case DT_UNKNOWN: return "UNKNOWN" ; case DT_BINARY: return "BINARY" ; case DT_INT8: return "INT8" ; case DT_UINT8: return "UINT8" ; case DT_INT16: return "INT16" ; case DT_UINT16: return "UINT16" ; case DT_INT32: return "INT32" ; case DT_UINT32: return "UINT32" ; case DT_INT64: return "INT64" ; case DT_UINT64: return "UINT64" ; case DT_FLOAT32: return "FLOAT32" ; case DT_FLOAT64: return "FLOAT64" ; case DT_FLOAT128: return "FLOAT128" ; case DT_COMPLEX64: return "COMPLEX64" ; case DT_COMPLEX128: return "COMPLEX128" ; case DT_COMPLEX256: return "COMPLEX256" ; case DT_RGB24: return "RGB24" ; case DT_RGBA32: return "RGBA32" ; } return "**ILLEGAL**" ; } /*----------------------------------------------------------------------*/ /*! Determine if the datatype code dt is an integer type (1=YES, 0=NO). \return whether the given NIfTI-1 datatype code is valid \sa NIFTI1_DATATYPES group in nifti1.h *//*--------------------------------------------------------------------*/ int nifti_is_inttype( int dt ) { switch( dt ){ case DT_UNKNOWN: return 0 ; case DT_BINARY: return 0 ; case DT_INT8: return 1 ; case DT_UINT8: return 1 ; case DT_INT16: return 1 ; case DT_UINT16: return 1 ; case DT_INT32: return 1 ; case DT_UINT32: return 1 ; case DT_INT64: return 1 ; case DT_UINT64: return 1 ; case DT_FLOAT32: return 0 ; case DT_FLOAT64: return 0 ; case DT_FLOAT128: return 0 ; case DT_COMPLEX64: return 0 ; case DT_COMPLEX128: return 0 ; case DT_COMPLEX256: return 0 ; case DT_RGB24: return 1 ; case DT_RGBA32: return 1 ; } return 0 ; } /*---------------------------------------------------------------------------*/ /*! Return a pointer to a string holding the name of a NIFTI units type. \param uu NIfTI-1 unit code \return pointer to static string for the given unit type \warning Do not free() or modify this string! It points to static storage. \sa NIFTI1_UNITS group in nifti1.h *//*-------------------------------------------------------------------------*/ char *nifti_units_string( int uu ) { switch( uu ){ case NIFTI_UNITS_METER: return "m" ; case NIFTI_UNITS_MM: return "mm" ; case NIFTI_UNITS_MICRON: return "um" ; case NIFTI_UNITS_SEC: return "s" ; case NIFTI_UNITS_MSEC: return "ms" ; case NIFTI_UNITS_USEC: return "us" ; case NIFTI_UNITS_HZ: return "Hz" ; case NIFTI_UNITS_PPM: return "ppm" ; case NIFTI_UNITS_RADS: return "rad/s" ; } return "Unknown" ; } /*---------------------------------------------------------------------------*/ /*! Return a pointer to a string holding the name of a NIFTI transform type. \param xx NIfTI-1 xform code \return pointer to static string describing xform code \warning Do not free() or modify this string! It points to static storage. \sa NIFTI1_XFORM_CODES group in nifti1.h *//*-------------------------------------------------------------------------*/ char *nifti_xform_string( int xx ) { switch( xx ){ case NIFTI_XFORM_SCANNER_ANAT: return "Scanner Anat" ; case NIFTI_XFORM_ALIGNED_ANAT: return "Aligned Anat" ; case NIFTI_XFORM_TALAIRACH: return "Talairach" ; case NIFTI_XFORM_MNI_152: return "MNI_152" ; } return "Unknown" ; } /*---------------------------------------------------------------------------*/ /*! Return a pointer to a string holding the name of a NIFTI intent type. \param ii NIfTI-1 intent code \return pointer to static string describing code \warning Do not free() or modify this string! It points to static storage. \sa NIFTI1_INTENT_CODES group in nifti1.h *//*-------------------------------------------------------------------------*/ char *nifti_intent_string( int ii ) { switch( ii ){ case NIFTI_INTENT_CORREL: return "Correlation statistic" ; case NIFTI_INTENT_TTEST: return "T-statistic" ; case NIFTI_INTENT_FTEST: return "F-statistic" ; case NIFTI_INTENT_ZSCORE: return "Z-score" ; case NIFTI_INTENT_CHISQ: return "Chi-squared distribution" ; case NIFTI_INTENT_BETA: return "Beta distribution" ; case NIFTI_INTENT_BINOM: return "Binomial distribution" ; case NIFTI_INTENT_GAMMA: return "Gamma distribution" ; case NIFTI_INTENT_POISSON: return "Poisson distribution" ; case NIFTI_INTENT_NORMAL: return "Normal distribution" ; case NIFTI_INTENT_FTEST_NONC: return "F-statistic noncentral" ; case NIFTI_INTENT_CHISQ_NONC: return "Chi-squared noncentral" ; case NIFTI_INTENT_LOGISTIC: return "Logistic distribution" ; case NIFTI_INTENT_LAPLACE: return "Laplace distribution" ; case NIFTI_INTENT_UNIFORM: return "Uniform distribition" ; case NIFTI_INTENT_TTEST_NONC: return "T-statistic noncentral" ; case NIFTI_INTENT_WEIBULL: return "Weibull distribution" ; case NIFTI_INTENT_CHI: return "Chi distribution" ; case NIFTI_INTENT_INVGAUSS: return "Inverse Gaussian distribution" ; case NIFTI_INTENT_EXTVAL: return "Extreme Value distribution" ; case NIFTI_INTENT_PVAL: return "P-value" ; case NIFTI_INTENT_LOGPVAL: return "Log P-value" ; case NIFTI_INTENT_LOG10PVAL: return "Log10 P-value" ; case NIFTI_INTENT_ESTIMATE: return "Estimate" ; case NIFTI_INTENT_LABEL: return "Label index" ; case NIFTI_INTENT_NEURONAME: return "NeuroNames index" ; case NIFTI_INTENT_GENMATRIX: return "General matrix" ; case NIFTI_INTENT_SYMMATRIX: return "Symmetric matrix" ; case NIFTI_INTENT_DISPVECT: return "Displacement vector" ; case NIFTI_INTENT_VECTOR: return "Vector" ; case NIFTI_INTENT_POINTSET: return "Pointset" ; case NIFTI_INTENT_TRIANGLE: return "Triangle" ; case NIFTI_INTENT_QUATERNION: return "Quaternion" ; case NIFTI_INTENT_DIMLESS: return "Dimensionless number" ; } return "Unknown" ; } /*---------------------------------------------------------------------------*/ /*! Return a pointer to a string holding the name of a NIFTI slice_code. \param ss NIfTI-1 slice order code \return pointer to static string describing code \warning Do not free() or modify this string! It points to static storage. \sa NIFTI1_SLICE_ORDER group in nifti1.h *//*-------------------------------------------------------------------------*/ char *nifti_slice_string( int ss ) { switch( ss ){ case NIFTI_SLICE_SEQ_INC: return "sequential_increasing" ; case NIFTI_SLICE_SEQ_DEC: return "sequential_decreasing" ; case NIFTI_SLICE_ALT_INC: return "alternating_increasing" ; case NIFTI_SLICE_ALT_DEC: return "alternating_decreasing" ; case NIFTI_SLICE_ALT_INC2: return "alternating_increasing_2" ; case NIFTI_SLICE_ALT_DEC2: return "alternating_decreasing_2" ; } return "Unknown" ; } /*---------------------------------------------------------------------------*/ /*! Return a pointer to a string holding the name of a NIFTI orientation. \param ii orientation code \return pointer to static string holding the orientation information \warning Do not free() or modify the return string! It points to static storage. \sa NIFTI_L2R in nifti1_io.h *//*-------------------------------------------------------------------------*/ char *nifti_orientation_string( int ii ) { switch( ii ){ case NIFTI_L2R: return "Left-to-Right" ; case NIFTI_R2L: return "Right-to-Left" ; case NIFTI_P2A: return "Posterior-to-Anterior" ; case NIFTI_A2P: return "Anterior-to-Posterior" ; case NIFTI_I2S: return "Inferior-to-Superior" ; case NIFTI_S2I: return "Superior-to-Inferior" ; } return "Unknown" ; } /*--------------------------------------------------------------------------*/ /*! Given a datatype code, set number of bytes per voxel and the swapsize. \param datatype nifti1 datatype code \param nbyper pointer to return value: number of bytes per voxel \param swapsize pointer to return value: size of swap blocks \return appropriate values at nbyper and swapsize The swapsize is set to 0 if this datatype doesn't ever need swapping. \sa NIFTI1_DATATYPES in nifti1.h *//*------------------------------------------------------------------------*/ void nifti_datatype_sizes( int datatype , int *nbyper, int *swapsize ) { int nb=0, ss=0 ; switch( datatype ){ case DT_INT8: case DT_UINT8: nb = 1 ; ss = 0 ; break ; case DT_INT16: case DT_UINT16: nb = 2 ; ss = 2 ; break ; case DT_RGB24: nb = 3 ; ss = 0 ; break ; case DT_RGBA32: nb = 4 ; ss = 0 ; break ; case DT_INT32: case DT_UINT32: case DT_FLOAT32: nb = 4 ; ss = 4 ; break ; case DT_COMPLEX64: nb = 8 ; ss = 4 ; break ; case DT_FLOAT64: case DT_INT64: case DT_UINT64: nb = 8 ; ss = 8 ; break ; case DT_FLOAT128: nb = 16 ; ss = 16 ; break ; case DT_COMPLEX128: nb = 16 ; ss = 8 ; break ; case DT_COMPLEX256: nb = 32 ; ss = 16 ; break ; } ASSIF(nbyper,nb) ; ASSIF(swapsize,ss) ; return ; } /*---------------------------------------------------------------------------*/ /*! Given the quaternion parameters (etc.), compute a transformation matrix. See comments in nifti1.h for details. - qb,qc,qd = quaternion parameters - qx,qy,qz = offset parameters - dx,dy,dz = grid stepsizes (non-negative inputs are set to 1.0) - qfac = sign of dz step (< 0 is negative; >= 0 is positive)
   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.
   
\see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h \see nifti_mat44_to_quatern, nifti_make_orthog_mat44, nifti_mat44_to_orientation *//*-------------------------------------------------------------------------*/ mat44 nifti_quatern_to_mat44( float qb, float qc, float qd, float qx, float qy, float qz, float dx, float dy, float dz, float qfac ) { mat44 R ; double a,b=qb,c=qc,d=qd , xd,yd,zd ; /* last row is always [ 0 0 0 1 ] */ R.m[3][0]=R.m[3][1]=R.m[3][2] = 0.0 ; R.m[3][3]= 1.0 ; /* compute a parameter from b,c,d */ a = 1.0l - (b*b + c*c + d*d) ; if( a < 1.e-7l ){ /* special case */ a = 1.0l / sqrt(b*b+c*c+d*d) ; b *= a ; c *= a ; d *= a ; /* normalize (b,c,d) vector */ a = 0.0l ; /* a = 0 ==> 180 degree rotation */ } else{ a = sqrt(a) ; /* angle = 2*arccos(a) */ } /* load rotation matrix, including scaling factors for voxel sizes */ xd = (dx > 0.0) ? dx : 1.0l ; /* make sure are positive */ yd = (dy > 0.0) ? dy : 1.0l ; zd = (dz > 0.0) ? dz : 1.0l ; if( qfac < 0.0 ) zd = -zd ; /* left handedness? */ R.m[0][0] = (a*a+b*b-c*c-d*d) * xd ; R.m[0][1] = 2.0l * (b*c-a*d ) * yd ; R.m[0][2] = 2.0l * (b*d+a*c ) * zd ; R.m[1][0] = 2.0l * (b*c+a*d ) * xd ; R.m[1][1] = (a*a+c*c-b*b-d*d) * yd ; R.m[1][2] = 2.0l * (c*d-a*b ) * zd ; R.m[2][0] = 2.0l * (b*d-a*c ) * xd ; R.m[2][1] = 2.0l * (c*d+a*b ) * yd ; R.m[2][2] = (a*a+d*d-c*c-b*b) * zd ; /* load offsets */ R.m[0][3] = qx ; R.m[1][3] = qy ; R.m[2][3] = qz ; return R ; } /*---------------------------------------------------------------------------*/ /*! Given the 3x4 upper corner of the matrix R, compute the quaternion parameters that fit it. - Any NULL pointer on input won't get assigned (e.g., if you don't want dx,dy,dz, just pass NULL in for those pointers). - If the 3 input matrix columns are NOT orthogonal, they will be orthogonalized prior to calculating the parameters, using the polar decomposition to find the orthogonal matrix closest to the column-normalized input matrix. - However, if the 3 input matrix columns are NOT orthogonal, then the matrix produced by nifti_quatern_to_mat44 WILL have orthogonal columns, so it won't be the same as the matrix input here. This "feature" is because the NIFTI 'qform' transform is deliberately not fully general -- it is intended to model a volume with perpendicular axes. - If the 3 input matrix columns are not even linearly independent, you'll just have to take your luck, won't you? \see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h \see nifti_quatern_to_mat44, nifti_make_orthog_mat44, nifti_mat44_to_orientation *//*-------------------------------------------------------------------------*/ void nifti_mat44_to_quatern( mat44 R , float *qb, float *qc, float *qd, float *qx, float *qy, float *qz, float *dx, float *dy, float *dz, float *qfac ) { double r11,r12,r13 , r21,r22,r23 , r31,r32,r33 ; double xd,yd,zd , a,b,c,d ; mat33 P,Q ; /* offset outputs are read write out of input matrix */ ASSIF(qx,R.m[0][3]) ; ASSIF(qy,R.m[1][3]) ; ASSIF(qz,R.m[2][3]) ; /* load 3x3 matrix into local variables */ r11 = R.m[0][0] ; r12 = R.m[0][1] ; r13 = R.m[0][2] ; r21 = R.m[1][0] ; r22 = R.m[1][1] ; r23 = R.m[1][2] ; r31 = R.m[2][0] ; r32 = R.m[2][1] ; r33 = R.m[2][2] ; /* compute lengths of each column; these determine grid spacings */ xd = sqrt( r11*r11 + r21*r21 + r31*r31 ) ; yd = sqrt( r12*r12 + r22*r22 + r32*r32 ) ; zd = sqrt( r13*r13 + r23*r23 + r33*r33 ) ; /* if a column length is zero, patch the trouble */ if( xd == 0.0l ){ r11 = 1.0l ; r21 = r31 = 0.0l ; xd = 1.0l ; } if( yd == 0.0l ){ r22 = 1.0l ; r12 = r32 = 0.0l ; yd = 1.0l ; } if( zd == 0.0l ){ r33 = 1.0l ; r13 = r23 = 0.0l ; zd = 1.0l ; } /* assign the output lengths */ ASSIF(dx,xd) ; ASSIF(dy,yd) ; ASSIF(dz,zd) ; /* normalize the columns */ r11 /= xd ; r21 /= xd ; r31 /= xd ; r12 /= yd ; r22 /= yd ; r32 /= yd ; r13 /= zd ; r23 /= zd ; r33 /= zd ; /* At this point, the matrix has normal columns, but we have to allow for the fact that the hideous user may not have given us a matrix with orthogonal columns. So, now find the orthogonal matrix closest to the current matrix. One reason for using the polar decomposition to get this orthogonal matrix, rather than just directly orthogonalizing the columns, is so that inputting the inverse matrix to R will result in the inverse orthogonal matrix at this point. If we just orthogonalized the columns, this wouldn't necessarily hold. */ Q.m[0][0] = r11 ; Q.m[0][1] = r12 ; Q.m[0][2] = r13 ; /* load Q */ Q.m[1][0] = r21 ; Q.m[1][1] = r22 ; Q.m[1][2] = r23 ; Q.m[2][0] = r31 ; Q.m[2][1] = r32 ; Q.m[2][2] = r33 ; P = nifti_mat33_polar(Q) ; /* P is orthog matrix closest to Q */ r11 = P.m[0][0] ; r12 = P.m[0][1] ; r13 = P.m[0][2] ; /* unload */ r21 = P.m[1][0] ; r22 = P.m[1][1] ; r23 = P.m[1][2] ; r31 = P.m[2][0] ; r32 = P.m[2][1] ; r33 = P.m[2][2] ; /* [ r11 r12 r13 ] */ /* at this point, the matrix [ r21 r22 r23 ] is orthogonal */ /* [ r31 r32 r33 ] */ /* compute the determinant to determine if it is proper */ zd = r11*r22*r33-r11*r32*r23-r21*r12*r33 +r21*r32*r13+r31*r12*r23-r31*r22*r13 ; /* should be -1 or 1 */ if( zd > 0 ){ /* proper */ ASSIF(qfac,1.0) ; } else { /* improper ==> flip 3rd column */ ASSIF(qfac,-1.0) ; r13 = -r13 ; r23 = -r23 ; r33 = -r33 ; } /* now, compute quaternion parameters */ a = r11 + r22 + r33 + 1.0l ; if( a > 0.5l ){ /* simplest case */ a = 0.5l * sqrt(a) ; b = 0.25l * (r32-r23) / a ; c = 0.25l * (r13-r31) / a ; d = 0.25l * (r21-r12) / a ; } else { /* trickier case */ xd = 1.0 + r11 - (r22+r33) ; /* 4*b*b */ yd = 1.0 + r22 - (r11+r33) ; /* 4*c*c */ zd = 1.0 + r33 - (r11+r22) ; /* 4*d*d */ if( xd > 1.0 ){ b = 0.5l * sqrt(xd) ; c = 0.25l* (r12+r21) / b ; d = 0.25l* (r13+r31) / b ; a = 0.25l* (r32-r23) / b ; } else if( yd > 1.0 ){ c = 0.5l * sqrt(yd) ; b = 0.25l* (r12+r21) / c ; d = 0.25l* (r23+r32) / c ; a = 0.25l* (r13-r31) / c ; } else { d = 0.5l * sqrt(zd) ; b = 0.25l* (r13+r31) / d ; c = 0.25l* (r23+r32) / d ; a = 0.25l* (r21-r12) / d ; } if( a < 0.0l ){ b=-b ; c=-c ; d=-d; a=-a; } } ASSIF(qb,b) ; ASSIF(qc,c) ; ASSIF(qd,d) ; return ; } /*---------------------------------------------------------------------------*/ /*! Compute the inverse of a bordered 4x4 matrix.
   - 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 ]
     
*//*-------------------------------------------------------------------------*/ mat44 nifti_mat44_inverse( mat44 R ) { double r11,r12,r13,r21,r22,r23,r31,r32,r33,v1,v2,v3 , deti ; mat44 Q ; /* INPUT MATRIX IS: */ r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 v1 ] */ r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 v2 ] */ r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 v3 ] */ v1 = R.m[0][3]; v2 = R.m[1][3]; v3 = R.m[2][3]; /* [ 0 0 0 1 ] */ deti = r11*r22*r33-r11*r32*r23-r21*r12*r33 +r21*r32*r13+r31*r12*r23-r31*r22*r13 ; if( deti != 0.0l ) deti = 1.0l / deti ; Q.m[0][0] = deti*( r22*r33-r32*r23) ; Q.m[0][1] = deti*(-r12*r33+r32*r13) ; Q.m[0][2] = deti*( r12*r23-r22*r13) ; Q.m[0][3] = deti*(-r12*r23*v3+r12*v2*r33+r22*r13*v3 -r22*v1*r33-r32*r13*v2+r32*v1*r23) ; Q.m[1][0] = deti*(-r21*r33+r31*r23) ; Q.m[1][1] = deti*( r11*r33-r31*r13) ; Q.m[1][2] = deti*(-r11*r23+r21*r13) ; Q.m[1][3] = deti*( r11*r23*v3-r11*v2*r33-r21*r13*v3 +r21*v1*r33+r31*r13*v2-r31*v1*r23) ; Q.m[2][0] = deti*( r21*r32-r31*r22) ; Q.m[2][1] = deti*(-r11*r32+r31*r12) ; Q.m[2][2] = deti*( r11*r22-r21*r12) ; Q.m[2][3] = deti*(-r11*r22*v3+r11*r32*v2+r21*r12*v3 -r21*r32*v1-r31*r12*v2+r31*r22*v1) ; Q.m[3][0] = Q.m[3][1] = Q.m[3][2] = 0.0l ; Q.m[3][3] = (deti == 0.0l) ? 0.0l : 1.0l ; /* failure flag if deti == 0 */ return Q ; } /*---------------------------------------------------------------------------*/ /*! Input 9 floats and make an orthgonal mat44 out of them. Each row is normalized, then nifti_mat33_polar() is used to orthogonalize them. If row #3 (r31,r32,r33) is input as zero, then it will be taken to be the cross product of rows #1 and #2. This function can be used to create a rotation matrix for transforming an oblique volume to anatomical coordinates. For this application: - row #1 (r11,r12,r13) is the direction vector along the image i-axis - row #2 (r21,r22,r23) is the direction vector along the image j-axis - row #3 (r31,r32,r33) is the direction vector along the slice direction (if available; otherwise enter it as 0's) The first 2 rows can be taken from the DICOM attribute (0020,0037) "Image Orientation (Patient)". After forming the rotation matrix, the complete affine transformation from (i,j,k) grid indexes to (x,y,z) spatial coordinates can be computed by multiplying each column by the appropriate grid spacing: - column #1 (R.m[0][0],R.m[1][0],R.m[2][0]) by delta-x - column #2 (R.m[0][1],R.m[1][1],R.m[2][1]) by delta-y - column #3 (R.m[0][2],R.m[1][2],R.m[2][2]) by delta-z and by then placing the center (x,y,z) coordinates of voxel (0,0,0) into the column #4 (R.m[0][3],R.m[1][3],R.m[2][3]). \sa nifti_quatern_to_mat44, nifti_mat44_to_quatern, nifti_mat44_to_orientation *//*-------------------------------------------------------------------------*/ mat44 nifti_make_orthog_mat44( float r11, float r12, float r13 , float r21, float r22, float r23 , float r31, float r32, float r33 ) { mat44 R ; mat33 Q , P ; double val ; R.m[3][0] = R.m[3][1] = R.m[3][2] = 0.0l ; R.m[3][3] = 1.0l ; Q.m[0][0] = r11 ; Q.m[0][1] = r12 ; Q.m[0][2] = r13 ; /* load Q */ Q.m[1][0] = r21 ; Q.m[1][1] = r22 ; Q.m[1][2] = r23 ; Q.m[2][0] = r31 ; Q.m[2][1] = r32 ; Q.m[2][2] = r33 ; /* normalize row 1 */ val = Q.m[0][0]*Q.m[0][0] + Q.m[0][1]*Q.m[0][1] + Q.m[0][2]*Q.m[0][2] ; if( val > 0.0l ){ val = 1.0l / sqrt(val) ; Q.m[0][0] *= val ; Q.m[0][1] *= val ; Q.m[0][2] *= val ; } else { Q.m[0][0] = 1.0l ; Q.m[0][1] = 0.0l ; Q.m[0][2] = 0.0l ; } /* normalize row 2 */ val = Q.m[1][0]*Q.m[1][0] + Q.m[1][1]*Q.m[1][1] + Q.m[1][2]*Q.m[1][2] ; if( val > 0.0l ){ val = 1.0l / sqrt(val) ; Q.m[1][0] *= val ; Q.m[1][1] *= val ; Q.m[1][2] *= val ; } else { Q.m[1][0] = 0.0l ; Q.m[1][1] = 1.0l ; Q.m[1][2] = 0.0l ; } /* normalize row 3 */ val = Q.m[2][0]*Q.m[2][0] + Q.m[2][1]*Q.m[2][1] + Q.m[2][2]*Q.m[2][2] ; if( val > 0.0l ){ val = 1.0l / sqrt(val) ; Q.m[2][0] *= val ; Q.m[2][1] *= val ; Q.m[2][2] *= val ; } else { Q.m[2][0] = Q.m[0][1]*Q.m[1][2] - Q.m[0][2]*Q.m[1][1] ; /* cross */ Q.m[2][1] = Q.m[0][2]*Q.m[1][0] - Q.m[0][0]*Q.m[1][2] ; /* product */ Q.m[2][2] = Q.m[0][0]*Q.m[1][1] - Q.m[0][1]*Q.m[1][0] ; } P = nifti_mat33_polar(Q) ; /* P is orthog matrix closest to Q */ R.m[0][0] = P.m[0][0] ; R.m[0][1] = P.m[0][1] ; R.m[0][2] = P.m[0][2] ; R.m[1][0] = P.m[1][0] ; R.m[1][1] = P.m[1][1] ; R.m[1][2] = P.m[1][2] ; R.m[2][0] = P.m[2][0] ; R.m[2][1] = P.m[2][1] ; R.m[2][2] = P.m[2][2] ; R.m[0][3] = R.m[1][3] = R.m[2][3] = 0.0 ; return R ; } /*----------------------------------------------------------------------*/ /*! compute the inverse of a 3x3 matrix *//*--------------------------------------------------------------------*/ mat33 nifti_mat33_inverse( mat33 R ) /* inverse of 3x3 matrix */ { double r11,r12,r13,r21,r22,r23,r31,r32,r33 , deti ; mat33 Q ; /* INPUT MATRIX: */ r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 ] */ r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 ] */ r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 ] */ deti = r11*r22*r33-r11*r32*r23-r21*r12*r33 +r21*r32*r13+r31*r12*r23-r31*r22*r13 ; if( deti != 0.0l ) deti = 1.0l / deti ; Q.m[0][0] = deti*( r22*r33-r32*r23) ; Q.m[0][1] = deti*(-r12*r33+r32*r13) ; Q.m[0][2] = deti*( r12*r23-r22*r13) ; Q.m[1][0] = deti*(-r21*r33+r31*r23) ; Q.m[1][1] = deti*( r11*r33-r31*r13) ; Q.m[1][2] = deti*(-r11*r23+r21*r13) ; Q.m[2][0] = deti*( r21*r32-r31*r22) ; Q.m[2][1] = deti*(-r11*r32+r31*r12) ; Q.m[2][2] = deti*( r11*r22-r21*r12) ; return Q ; } /*----------------------------------------------------------------------*/ /*! compute the determinant of a 3x3 matrix *//*--------------------------------------------------------------------*/ float nifti_mat33_determ( mat33 R ) /* determinant of 3x3 matrix */ { double r11,r12,r13,r21,r22,r23,r31,r32,r33 ; /* INPUT MATRIX: */ r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 ] */ r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 ] */ r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 ] */ return r11*r22*r33-r11*r32*r23-r21*r12*r33 +r21*r32*r13+r31*r12*r23-r31*r22*r13 ; } /*----------------------------------------------------------------------*/ /*! compute the max row norm of a 3x3 matrix *//*--------------------------------------------------------------------*/ float nifti_mat33_rownorm( mat33 A ) /* max row norm of 3x3 matrix */ { float r1,r2,r3 ; r1 = fabs(A.m[0][0])+fabs(A.m[0][1])+fabs(A.m[0][2]) ; r2 = fabs(A.m[1][0])+fabs(A.m[1][1])+fabs(A.m[1][2]) ; r3 = fabs(A.m[2][0])+fabs(A.m[2][1])+fabs(A.m[2][2]) ; if( r1 < r2 ) r1 = r2 ; if( r1 < r3 ) r1 = r3 ; return r1 ; } /*----------------------------------------------------------------------*/ /*! compute the max column norm of a 3x3 matrix *//*--------------------------------------------------------------------*/ float nifti_mat33_colnorm( mat33 A ) /* max column norm of 3x3 matrix */ { float r1,r2,r3 ; r1 = fabs(A.m[0][0])+fabs(A.m[1][0])+fabs(A.m[2][0]) ; r2 = fabs(A.m[0][1])+fabs(A.m[1][1])+fabs(A.m[2][1]) ; r3 = fabs(A.m[0][2])+fabs(A.m[1][2])+fabs(A.m[2][2]) ; if( r1 < r2 ) r1 = r2 ; if( r1 < r3 ) r1 = r3 ; return r1 ; } /*----------------------------------------------------------------------*/ /*! multiply 2 3x3 matrices *//*--------------------------------------------------------------------*/ mat33 nifti_mat33_mul( mat33 A , mat33 B ) /* multiply 2 3x3 matrices */ { mat33 C ; int i,j ; for( i=0 ; i < 3 ; i++ ) for( j=0 ; j < 3 ; j++ ) C.m[i][j] = A.m[i][0] * B.m[0][j] + A.m[i][1] * B.m[1][j] + A.m[i][2] * B.m[2][j] ; return C ; } /*---------------------------------------------------------------------------*/ /*! polar decomposition of a 3x3 matrix This finds the closest orthogonal matrix to input A (in both the Frobenius and L2 norms). Algorithm is that from NJ Higham, SIAM J Sci Stat Comput, 7:1160-1174. *//*-------------------------------------------------------------------------*/ mat33 nifti_mat33_polar( mat33 A ) { mat33 X , Y , Z ; float alp,bet,gam,gmi , dif=1.0 ; int k=0 ; X = A ; /* force matrix to be nonsingular */ gam = nifti_mat33_determ(X) ; while( gam == 0.0 ){ /* perturb matrix */ gam = 0.00001 * ( 0.001 + nifti_mat33_rownorm(X) ) ; X.m[0][0] += gam ; X.m[1][1] += gam ; X.m[2][2] += gam ; gam = nifti_mat33_determ(X) ; } while(1){ Y = nifti_mat33_inverse(X) ; if( dif > 0.3 ){ /* far from convergence */ alp = sqrt( nifti_mat33_rownorm(X) * nifti_mat33_colnorm(X) ) ; bet = sqrt( nifti_mat33_rownorm(Y) * nifti_mat33_colnorm(Y) ) ; gam = sqrt( bet / alp ) ; gmi = 1.0 / gam ; } else { gam = gmi = 1.0 ; /* close to convergence */ } Z.m[0][0] = 0.5 * ( gam*X.m[0][0] + gmi*Y.m[0][0] ) ; Z.m[0][1] = 0.5 * ( gam*X.m[0][1] + gmi*Y.m[1][0] ) ; Z.m[0][2] = 0.5 * ( gam*X.m[0][2] + gmi*Y.m[2][0] ) ; Z.m[1][0] = 0.5 * ( gam*X.m[1][0] + gmi*Y.m[0][1] ) ; Z.m[1][1] = 0.5 * ( gam*X.m[1][1] + gmi*Y.m[1][1] ) ; Z.m[1][2] = 0.5 * ( gam*X.m[1][2] + gmi*Y.m[2][1] ) ; Z.m[2][0] = 0.5 * ( gam*X.m[2][0] + gmi*Y.m[0][2] ) ; Z.m[2][1] = 0.5 * ( gam*X.m[2][1] + gmi*Y.m[1][2] ) ; Z.m[2][2] = 0.5 * ( gam*X.m[2][2] + gmi*Y.m[2][2] ) ; dif = fabs(Z.m[0][0]-X.m[0][0])+fabs(Z.m[0][1]-X.m[0][1]) +fabs(Z.m[0][2]-X.m[0][2])+fabs(Z.m[1][0]-X.m[1][0]) +fabs(Z.m[1][1]-X.m[1][1])+fabs(Z.m[1][2]-X.m[1][2]) +fabs(Z.m[2][0]-X.m[2][0])+fabs(Z.m[2][1]-X.m[2][1]) +fabs(Z.m[2][2]-X.m[2][2]) ; k = k+1 ; if( k > 100 || dif < 3.e-6 ) break ; /* convergence or exhaustion */ X = Z ; } return Z ; } /*---------------------------------------------------------------------------*/ /*! compute the (closest) orientation from a 4x4 ijk->xyz tranformation matrix
   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)
   
\see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h \see nifti_quatern_to_mat44, nifti_mat44_to_quatern, nifti_make_orthog_mat44 *//*-------------------------------------------------------------------------*/ void nifti_mat44_to_orientation( mat44 R , int *icod, int *jcod, int *kcod ) { float xi,xj,xk , yi,yj,yk , zi,zj,zk , val,detQ,detP ; mat33 P , Q , M ; int i,j,k=0,p,q,r , ibest,jbest,kbest,pbest,qbest,rbest ; float vbest ; if( icod == NULL || jcod == NULL || kcod == NULL ) return ; /* bad */ *icod = *jcod = *kcod = 0 ; /* error returns, if sh*t happens */ /* load column vectors for each (i,j,k) direction from matrix */ /*-- i axis --*/ /*-- j axis --*/ /*-- k axis --*/ xi = R.m[0][0] ; xj = R.m[0][1] ; xk = R.m[0][2] ; yi = R.m[1][0] ; yj = R.m[1][1] ; yk = R.m[1][2] ; zi = R.m[2][0] ; zj = R.m[2][1] ; zk = R.m[2][2] ; /* normalize column vectors to get unit vectors along each ijk-axis */ /* normalize i axis */ val = sqrt( xi*xi + yi*yi + zi*zi ) ; if( val == 0.0 ) return ; /* stupid input */ xi /= val ; yi /= val ; zi /= val ; /* normalize j axis */ val = sqrt( xj*xj + yj*yj + zj*zj ) ; if( val == 0.0 ) return ; /* stupid input */ xj /= val ; yj /= val ; zj /= val ; /* orthogonalize j axis to i axis, if needed */ val = xi*xj + yi*yj + zi*zj ; /* dot product between i and j */ if( fabs(val) > 1.e-4 ){ xj -= val*xi ; yj -= val*yi ; zj -= val*zi ; val = sqrt( xj*xj + yj*yj + zj*zj ) ; /* must renormalize */ if( val == 0.0 ) return ; /* j was parallel to i? */ xj /= val ; yj /= val ; zj /= val ; } /* normalize k axis; if it is zero, make it the cross product i x j */ val = sqrt( xk*xk + yk*yk + zk*zk ) ; if( val == 0.0 ){ xk = yi*zj-zi*yj; yk = zi*xj-zj*xi ; zk=xi*yj-yi*xj ; } else { xk /= val ; yk /= val ; zk /= val ; } /* orthogonalize k to i */ val = xi*xk + yi*yk + zi*zk ; /* dot product between i and k */ if( fabs(val) > 1.e-4 ){ xk -= val*xi ; yk -= val*yi ; zk -= val*zi ; val = sqrt( xk*xk + yk*yk + zk*zk ) ; if( val == 0.0 ) return ; /* bad */ xk /= val ; yk /= val ; zk /= val ; } /* orthogonalize k to j */ val = xj*xk + yj*yk + zj*zk ; /* dot product between j and k */ if( fabs(val) > 1.e-4 ){ xk -= val*xj ; yk -= val*yj ; zk -= val*zj ; val = sqrt( xk*xk + yk*yk + zk*zk ) ; if( val == 0.0 ) return ; /* bad */ xk /= val ; yk /= val ; zk /= val ; } Q.m[0][0] = xi ; Q.m[0][1] = xj ; Q.m[0][2] = xk ; Q.m[1][0] = yi ; Q.m[1][1] = yj ; Q.m[1][2] = yk ; Q.m[2][0] = zi ; Q.m[2][1] = zj ; Q.m[2][2] = zk ; /* at this point, Q is the rotation matrix from the (i,j,k) to (x,y,z) axes */ detQ = nifti_mat33_determ( Q ) ; if( detQ == 0.0 ) return ; /* shouldn't happen unless user is a DUFIS */ /* Build and test all possible +1/-1 coordinate permutation matrices P; then find the P such that the rotation matrix M=PQ is closest to the identity, in the sense of M having the smallest total rotation angle. */ /* Despite the formidable looking 6 nested loops, there are only 3*3*3*2*2*2 = 216 passes, which will run very quickly. */ vbest = -666.0 ; ibest=pbest=qbest=rbest=1 ; jbest=2 ; kbest=3 ; for( i=1 ; i <= 3 ; i++ ){ /* i = column number to use for row #1 */ for( j=1 ; j <= 3 ; j++ ){ /* j = column number to use for row #2 */ if( i == j ) continue ; for( k=1 ; k <= 3 ; k++ ){ /* k = column number to use for row #3 */ if( i == k || j == k ) continue ; P.m[0][0] = P.m[0][1] = P.m[0][2] = P.m[1][0] = P.m[1][1] = P.m[1][2] = P.m[2][0] = P.m[2][1] = P.m[2][2] = 0.0 ; for( p=-1 ; p <= 1 ; p+=2 ){ /* p,q,r are -1 or +1 */ for( q=-1 ; q <= 1 ; q+=2 ){ /* and go into rows #1,2,3 */ for( r=-1 ; r <= 1 ; r+=2 ){ P.m[0][i-1] = p ; P.m[1][j-1] = q ; P.m[2][k-1] = r ; detP = nifti_mat33_determ(P) ; /* sign of permutation */ if( detP * detQ <= 0.0 ) continue ; /* doesn't match sign of Q */ M = nifti_mat33_mul(P,Q) ; /* angle of M rotation = 2.0*acos(0.5*sqrt(1.0+trace(M))) */ /* we want largest trace(M) == smallest angle == M nearest to I */ val = M.m[0][0] + M.m[1][1] + M.m[2][2] ; /* trace */ if( val > vbest ){ vbest = val ; ibest = i ; jbest = j ; kbest = k ; pbest = p ; qbest = q ; rbest = r ; } }}}}}} /* At this point ibest is 1 or 2 or 3; pbest is -1 or +1; etc. The matrix P that corresponds is the best permutation approximation to Q-inverse; that is, P (approximately) takes (x,y,z) coordinates to the (i,j,k) axes. For example, the first row of P (which contains pbest in column ibest) determines the way the i axis points relative to the anatomical (x,y,z) axes. If ibest is 2, then the i axis is along the y axis, which is direction P2A (if pbest > 0) or A2P (if pbest < 0). So, using ibest and pbest, we can assign the output code for the i axis. Mutatis mutandis for the j and k axes, of course. */ switch( ibest*pbest ){ case 1: i = NIFTI_L2R ; break ; case -1: i = NIFTI_R2L ; break ; case 2: i = NIFTI_P2A ; break ; case -2: i = NIFTI_A2P ; break ; case 3: i = NIFTI_I2S ; break ; case -3: i = NIFTI_S2I ; break ; } switch( jbest*qbest ){ case 1: j = NIFTI_L2R ; break ; case -1: j = NIFTI_R2L ; break ; case 2: j = NIFTI_P2A ; break ; case -2: j = NIFTI_A2P ; break ; case 3: j = NIFTI_I2S ; break ; case -3: j = NIFTI_S2I ; break ; } switch( kbest*rbest ){ case 1: k = NIFTI_L2R ; break ; case -1: k = NIFTI_R2L ; break ; case 2: k = NIFTI_P2A ; break ; case -2: k = NIFTI_A2P ; break ; case 3: k = NIFTI_I2S ; break ; case -3: k = NIFTI_S2I ; break ; } *icod = i ; *jcod = j ; *kcod = k ; return ; } /*---------------------------------------------------------------------------*/ /* Routines to swap byte arrays in various ways: - 2 at a time: ab -> ba [short] - 4 at a time: abcd -> dcba [int, float] - 8 at a time: abcdDCBA -> ABCDdcba [long long, double] - 16 at a time: abcdefghHGFEDCBA -> ABCDEFGHhgfedcba [long double] -----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /*! swap each byte pair from the given list of n pairs * * Due to alignment of structures at some architectures (e.g. on ARM), * stick to char varaibles. * Fixes http://bugs.debian.org/446893 Yaroslav * *//*--------------------------------------------------------------------*/ void nifti_swap_2bytes( size_t n , void *ar ) /* 2 bytes at a time */ { register size_t ii ; unsigned char * cp1 = (unsigned char *)ar, * cp2 ; unsigned char tval; for( ii=0 ; ii < n ; ii++ ){ cp2 = cp1 + 1; tval = *cp1; *cp1 = *cp2; *cp2 = tval; cp1 += 2; } return ; } /*----------------------------------------------------------------------*/ /*! swap 4 bytes at a time from the given list of n sets of 4 bytes *//*--------------------------------------------------------------------*/ void nifti_swap_4bytes( size_t n , void *ar ) /* 4 bytes at a time */ { register size_t ii ; unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ; register unsigned char tval ; for( ii=0 ; ii < n ; ii++ ){ cp1 = cp0; cp2 = cp0+3; tval = *cp1; *cp1 = *cp2; *cp2 = tval; cp1++; cp2--; tval = *cp1; *cp1 = *cp2; *cp2 = tval; cp0 += 4; } return ; } /*----------------------------------------------------------------------*/ /*! swap 8 bytes at a time from the given list of n sets of 8 bytes * * perhaps use this style for the general Nbytes, as Yaroslav suggests *//*--------------------------------------------------------------------*/ void nifti_swap_8bytes( size_t n , void *ar ) /* 8 bytes at a time */ { register size_t ii ; unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ; register unsigned char tval ; for( ii=0 ; ii < n ; ii++ ){ cp1 = cp0; cp2 = cp0+7; while ( cp2 > cp1 ) /* unroll? */ { tval = *cp1 ; *cp1 = *cp2 ; *cp2 = tval ; cp1++; cp2--; } cp0 += 8; } return ; } /*----------------------------------------------------------------------*/ /*! swap 16 bytes at a time from the given list of n sets of 16 bytes *//*--------------------------------------------------------------------*/ void nifti_swap_16bytes( size_t n , void *ar ) /* 16 bytes at a time */ { register size_t ii ; unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ; register unsigned char tval ; for( ii=0 ; ii < n ; ii++ ){ cp1 = cp0; cp2 = cp0+15; while ( cp2 > cp1 ) { tval = *cp1 ; *cp1 = *cp2 ; *cp2 = tval ; cp1++; cp2--; } cp0 += 16; } return ; } #if 0 /* not important: save for version update 6 Jul 2010 [rickr] */ /*----------------------------------------------------------------------*/ /*! generic: swap siz bytes at a time from the given list of n sets *//*--------------------------------------------------------------------*/ void nifti_swap_bytes( size_t n , int siz , void *ar ) { register size_t ii ; unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ; register unsigned char tval ; for( ii=0 ; ii < n ; ii++ ){ cp1 = cp0; cp2 = cp0+(siz-1); while ( cp2 > cp1 ) { tval = *cp1 ; *cp1 = *cp2 ; *cp2 = tval ; cp1++; cp2--; } cp0 += siz; } return ; } #endif /*---------------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /*! based on siz, call the appropriate nifti_swap_Nbytes() function *//*--------------------------------------------------------------------*/ void nifti_swap_Nbytes( size_t n , int size , void *ar ) /* subsuming case */ { switch( size ){ case 2: nifti_swap_2bytes ( n , ar ) ; break ; case 4: nifti_swap_4bytes ( n , ar ) ; break ; case 8: nifti_swap_8bytes ( n , ar ) ; break ; case 16: nifti_swap_16bytes( n , ar ) ; break ; default: /* nifti_swap_bytes ( n , size, ar ) ; */ REprintf("** nifti_swap_Nbytes: cannot swap in %d byte blocks\n", size); break ; } return ; } /*-------------------------------------------------------------------------*/ /*! Byte swap NIFTI-1 file header in various places and ways. If is_nifti, swap all (even UNUSED) fields of NIfTI header. Else, swap as a nifti_analyze75 struct. *//*---------------------------------------------------------------------- */ void swap_nifti_header( struct nifti_1_header *h , int is_nifti ) { /* if ANALYZE, swap as such and return */ if( ! is_nifti ) { nifti_swap_as_analyze((nifti_analyze75 *)h); return; } /* otherwise, swap all NIFTI fields */ nifti_swap_4bytes(1, &h->sizeof_hdr); nifti_swap_4bytes(1, &h->extents); nifti_swap_2bytes(1, &h->session_error); nifti_swap_2bytes(8, h->dim); nifti_swap_4bytes(1, &h->intent_p1); nifti_swap_4bytes(1, &h->intent_p2); nifti_swap_4bytes(1, &h->intent_p3); nifti_swap_2bytes(1, &h->intent_code); nifti_swap_2bytes(1, &h->datatype); nifti_swap_2bytes(1, &h->bitpix); nifti_swap_2bytes(1, &h->slice_start); nifti_swap_4bytes(8, h->pixdim); nifti_swap_4bytes(1, &h->vox_offset); nifti_swap_4bytes(1, &h->scl_slope); nifti_swap_4bytes(1, &h->scl_inter); nifti_swap_2bytes(1, &h->slice_end); nifti_swap_4bytes(1, &h->cal_max); nifti_swap_4bytes(1, &h->cal_min); nifti_swap_4bytes(1, &h->slice_duration); nifti_swap_4bytes(1, &h->toffset); nifti_swap_4bytes(1, &h->glmax); nifti_swap_4bytes(1, &h->glmin); nifti_swap_2bytes(1, &h->qform_code); nifti_swap_2bytes(1, &h->sform_code); nifti_swap_4bytes(1, &h->quatern_b); nifti_swap_4bytes(1, &h->quatern_c); nifti_swap_4bytes(1, &h->quatern_d); nifti_swap_4bytes(1, &h->qoffset_x); nifti_swap_4bytes(1, &h->qoffset_y); nifti_swap_4bytes(1, &h->qoffset_z); nifti_swap_4bytes(4, h->srow_x); nifti_swap_4bytes(4, h->srow_y); nifti_swap_4bytes(4, h->srow_z); return ; } /*-------------------------------------------------------------------------*/ /*! Byte swap as an ANALYZE 7.5 header * * return non-zero on failure *//*---------------------------------------------------------------------- */ int nifti_swap_as_analyze( nifti_analyze75 * h ) { if( !h ) return 1; nifti_swap_4bytes(1, &h->sizeof_hdr); nifti_swap_4bytes(1, &h->extents); nifti_swap_2bytes(1, &h->session_error); nifti_swap_2bytes(8, h->dim); nifti_swap_2bytes(1, &h->unused8); nifti_swap_2bytes(1, &h->unused9); nifti_swap_2bytes(1, &h->unused10); nifti_swap_2bytes(1, &h->unused11); nifti_swap_2bytes(1, &h->unused12); nifti_swap_2bytes(1, &h->unused13); nifti_swap_2bytes(1, &h->unused14); nifti_swap_2bytes(1, &h->datatype); nifti_swap_2bytes(1, &h->bitpix); nifti_swap_2bytes(1, &h->dim_un0); nifti_swap_4bytes(8, h->pixdim); nifti_swap_4bytes(1, &h->vox_offset); nifti_swap_4bytes(1, &h->funused1); nifti_swap_4bytes(1, &h->funused2); nifti_swap_4bytes(1, &h->funused3); nifti_swap_4bytes(1, &h->cal_max); nifti_swap_4bytes(1, &h->cal_min); nifti_swap_4bytes(1, &h->compressed); nifti_swap_4bytes(1, &h->verified); nifti_swap_4bytes(1, &h->glmax); nifti_swap_4bytes(1, &h->glmin); nifti_swap_4bytes(1, &h->views); nifti_swap_4bytes(1, &h->vols_added); nifti_swap_4bytes(1, &h->start_field); nifti_swap_4bytes(1, &h->field_skip); nifti_swap_4bytes(1, &h->omax); nifti_swap_4bytes(1, &h->omin); nifti_swap_4bytes(1, &h->smax); nifti_swap_4bytes(1, &h->smin); return 0; } /*-------------------------------------------------------------------------*/ /*! OLD VERSION of swap_nifti_header (left for undo/compare operations) Byte swap NIFTI-1 file header in various places and ways. If is_nifti is nonzero, will also swap the NIFTI-specific components of the header; otherwise, only the components common to NIFTI and ANALYZE will be swapped. *//*---------------------------------------------------------------------- */ void old_swap_nifti_header( struct nifti_1_header *h , int is_nifti ) { /* this stuff is always present, for ANALYZE and NIFTI */ swap_4(h->sizeof_hdr) ; nifti_swap_2bytes( 8 , h->dim ) ; nifti_swap_4bytes( 8 , h->pixdim ) ; swap_2(h->datatype) ; swap_2(h->bitpix) ; swap_4(h->vox_offset); swap_4(h->cal_max); swap_4(h->cal_min); /* this stuff is NIFTI specific */ if( is_nifti ){ swap_4(h->intent_p1); swap_4(h->intent_p2); swap_4(h->intent_p3); swap_2(h->intent_code); swap_2(h->slice_start); swap_2(h->slice_end); swap_4(h->scl_slope); swap_4(h->scl_inter); swap_4(h->slice_duration); swap_4(h->toffset); swap_2(h->qform_code); swap_2(h->sform_code); swap_4(h->quatern_b); swap_4(h->quatern_c); swap_4(h->quatern_d); swap_4(h->qoffset_x); swap_4(h->qoffset_y); swap_4(h->qoffset_z); nifti_swap_4bytes(4,h->srow_x); nifti_swap_4bytes(4,h->srow_y); nifti_swap_4bytes(4,h->srow_z); } return ; } #define USE_STAT #ifdef USE_STAT /*---------------------------------------------------------------------------*/ /* Return the file length (0 if file not found or has no contents). This is a Unix-specific function, since it uses stat(). -----------------------------------------------------------------------------*/ #include #include /*---------------------------------------------------------------------------*/ /*! return the size of a file, in bytes \return size of file on success, -1 on error or no file changed to return int, -1 means no file or error 20 Dec 2004 [rickr] *//*-------------------------------------------------------------------------*/ int nifti_get_filesize( const char *pathname ) { struct stat buf ; int ii ; if( pathname == NULL || *pathname == '\0' ) return -1 ; ii = stat( pathname , &buf ); if( ii != 0 ) return -1 ; return (unsigned int)buf.st_size ; } #else /*---------- non-Unix version of the above, less efficient -----------*/ int nifti_get_filesize( const char *pathname ) { znzFile fp ; int len ; if( pathname == NULL || *pathname == '\0' ) return -1 ; fp = znzopen(pathname,"rb",0); if( znz_isnull(fp) ) return -1 ; znzseek(fp,0L,SEEK_END) ; len = znztell(fp) ; znzclose(fp) ; return len ; } #endif /* USE_STAT */ /*----------------------------------------------------------------------*/ /*! return the total volume size, in bytes This is computed as nvox * nbyper. *//*--------------------------------------------------------------------*/ size_t nifti_get_volsize(const nifti_image *nim) { return nim->nbyper * nim->nvox ; /* total bytes */ } /*--------------------------------------------------------------------------*/ /* Support functions for filenames in read and write - allows for gzipped files */ /*----------------------------------------------------------------------*/ /*! simple check for file existence \return 1 on existence, 0 otherwise *//*--------------------------------------------------------------------*/ int nifti_fileexists(const char* fname) { znzFile fp; fp = znzopen( fname , "rb" , 1 ) ; if( !znz_isnull(fp) ) { znzclose(fp); return 1; } return 0; /* fp is NULL */ } /*----------------------------------------------------------------------*/ /*! return whether the filename is valid Note: uppercase extensions are now valid. 27 Apr 2009 [rickr] The name is considered valid if the file basename has length greater than zero, AND one of the valid nifti extensions is provided. fname input | return | =============================== "myimage" | 0 | "myimage.tif" | 0 | "myimage.tif.gz" | 0 | "myimage.nii" | 1 | ".nii" | 0 | ".myhiddenimage" | 0 | ".myhiddenimage.nii" | 1 | *//*--------------------------------------------------------------------*/ int nifti_is_complete_filename(const char* fname) { char * ext; /* check input file(s) for sanity */ if( fname == NULL || *fname == '\0' ){ if ( g_opts.debug > 1 ) REprintf("-- empty filename in nifti_validfilename()\n"); return 0; } ext = nifti_find_file_extension(fname); if ( ext == NULL ) { /*Invalid extension given */ if ( g_opts.debug > 0 ) REprintf("-- no nifti valid extension for filename '%s'\n", fname); return 0; } if ( ext && ext == fname ) { /* then no filename prefix */ if ( g_opts.debug > 0 ) REprintf("-- no prefix for filename '%s'\n", fname); return 0; } return 1; } /*----------------------------------------------------------------------*/ /*! return whether the filename is valid Allow uppercase extensions as valid. 27 Apr 2009 [rickr] Any .gz extension case must match the base extension case. The name is considered valid if its length is positive, excluding any nifti filename extension. fname input | return | result of nifti_makebasename ==================================================================== "myimage" | 1 | "myimage" "myimage.tif" | 1 | "myimage.tif" "myimage.tif.gz" | 1 | "myimage.tif" "myimage.nii" | 1 | "myimage" ".nii" | 0 | ".myhiddenimage" | 1 | ".myhiddenimage" ".myhiddenimage.nii | 1 | ".myhiddenimage" *//*--------------------------------------------------------------------*/ int nifti_validfilename(const char* fname) { char * ext; /* check input file(s) for sanity */ if( fname == NULL || *fname == '\0' ){ if ( g_opts.debug > 1 ) REprintf("-- empty filename in nifti_validfilename()\n"); return 0; } ext = nifti_find_file_extension(fname); if ( ext && ext == fname ) { /* then no filename prefix */ if ( g_opts.debug > 0 ) REprintf("-- no prefix for filename '%s'\n", fname); return 0; } return 1; } /*----------------------------------------------------------------------*/ /*! check the end of the filename for a valid nifti extension Valid extensions are currently .nii, .hdr, .img, .nia, or any of them followed by .gz. Note that '.' is part of the extension. Uppercase extensions are also valid, but not mixed case. \return a pointer to the extension (within the filename), or NULL *//*--------------------------------------------------------------------*/ char * nifti_find_file_extension( const char * name ) { char * ext, extcopy[8]; int len; char extnii[8] = ".nii"; /* modifiable, for possible uppercase */ char exthdr[8] = ".hdr"; /* (leave space for .gz) */ char extimg[8] = ".img"; char extnia[8] = ".nia"; char extgz[4] = ".gz"; char * elist[4] = { NULL, NULL, NULL, NULL}; /* stupid compiler... */ elist[0] = extnii; elist[1] = exthdr; elist[2] = extimg; elist[3] = extnia; if ( ! name ) return NULL; len = (int)strlen(name); if ( len < 4 ) return NULL; ext = (char *)name + len - 4; /* make manipulation copy, and possibly convert to lowercase */ strcpy(extcopy, ext); if( g_opts.allow_upper_fext ) make_lowercase(extcopy); /* if it look like a basic extension, fail or return it */ if( compare_strlist(extcopy, elist, 4) >= 0 ) { if( is_mixedcase(ext) ) { REprintf("** mixed case extension '%s' is not valid\n", ext); return NULL; } else return ext; } #ifdef HAVE_LIBZ if ( len < 7 ) return NULL; ext = (char *)name + len - 7; /* make manipulation copy, and possibly convert to lowercase */ strcpy(extcopy, ext); if( g_opts.allow_upper_fext ) make_lowercase(extcopy); /* go after .gz extensions using the modifiable strings */ strcat(elist[0], extgz); strcat(elist[1], extgz); strcat(elist[2], extgz); if( compare_strlist(extcopy, elist, 3) >= 0 ) { if( is_mixedcase(ext) ) { REprintf("** mixed case extension '%s' is not valid\n", ext); return NULL; } else return ext; } #endif if( g_opts.debug > 1 ) REprintf("** find_file_ext: failed for name '%s'\n", name); return NULL; } /*----------------------------------------------------------------------*/ /*! return whether the filename ends in ".gz" *//*--------------------------------------------------------------------*/ int nifti_is_gzfile(const char* fname) { /* return true if the filename ends with .gz */ if (fname == NULL) { return 0; } #ifdef HAVE_LIBZ { /* just so len doesn't generate compile warning */ int len; len = (int)strlen(fname); if (len < 3) return 0; /* so we don't search before the name */ if (fileext_compare(fname + strlen(fname) - 3,".gz")==0) { return 1; } } #endif return 0; } /*----------------------------------------------------------------------*/ /*! return whether the given library was compiled with HAVE_LIBZ set *//*--------------------------------------------------------------------*/ int nifti_compiled_with_zlib(void) { #ifdef HAVE_LIBZ return 1; #else return 0; #endif } /*----------------------------------------------------------------------*/ /*! duplicate the filename, while clearing any extension This allocates memory for basename which should eventually be freed. *//*--------------------------------------------------------------------*/ char * nifti_makebasename(const char* fname) { char *basename, *ext; basename=nifti_strdup(fname); ext = nifti_find_file_extension(basename); if ( ext ) *ext = '\0'; /* clear out extension */ return basename; /* in either case */ } /*----------------------------------------------------------------------*/ /*! set nifti's global debug level, for status reporting - 0 : quiet, nothing is printed to the terminal, but errors - 1 : normal execution (the default) - 2, 3 : more details *//*--------------------------------------------------------------------*/ void nifti_set_debug_level( int level ) { g_opts.debug = level; } /*----------------------------------------------------------------------*/ /*! set nifti's global skip_blank_ext flag 5 Sep 2006 [rickr] explicitly set to 0 or 1 *//*--------------------------------------------------------------------*/ void nifti_set_skip_blank_ext( int skip ) { g_opts.skip_blank_ext = skip ? 1 : 0; } /*----------------------------------------------------------------------*/ /*! set nifti's global allow_upper_fext flag 28 Apr 2009 [rickr] explicitly set to 0 or 1 *//*--------------------------------------------------------------------*/ void nifti_set_allow_upper_fext( int allow ) { g_opts.allow_upper_fext = allow ? 1 : 0; } /*----------------------------------------------------------------------*/ /*! check current directory for existing header file \return filename of header on success and NULL if no appropriate file could be found If fname has an uppercase extension, check for uppercase files. NB: it allocates memory for hdrname which should be freed when no longer required *//*-------------------------------------------------------------------*/ char * nifti_findhdrname(const char* fname) { char *basename, *hdrname, *ext; char elist[2][5] = { ".hdr", ".nii" }; char extzip[4] = ".gz"; int efirst = 1; /* init to .nii extension */ int eisupper = 0; /* init to lowercase extensions */ /**- check input file(s) for sanity */ if( !nifti_validfilename(fname) ) return NULL; basename = nifti_makebasename(fname); if( !basename ) return NULL; /* only on string alloc failure */ /**- return filename if it has a valid extension and exists (except if it is an .img file (and maybe .gz)) */ ext = nifti_find_file_extension(fname); if( ext ) eisupper = is_uppercase(ext); /* do we look for uppercase? */ /* if the file exists and is a valid header name (not .img), return it */ if ( ext && nifti_fileexists(fname) ) { /* allow for uppercase extension */ if ( fileext_n_compare(ext,".img",4) != 0 ){ hdrname = nifti_strdup(fname); free(basename); return hdrname; } else efirst = 0; /* note for below */ } /* So the requested name is a basename, contains .img, or does not exist. */ /* In any case, use basename. */ /**- if .img, look for .hdr, .hdr.gz, .nii, .nii.gz, in that order */ /**- else, look for .nii, .nii.gz, .hdr, .hdr.gz, in that order */ /* if we get more extension choices, this could be a loop */ /* note: efirst is 0 in the case of ".img" */ /* if the user passed an uppercase entension (.IMG), search for uppercase */ if( eisupper ) { make_uppercase(elist[0]); make_uppercase(elist[1]); make_uppercase(extzip); } hdrname = (char *)calloc(sizeof(char),strlen(basename)+8); if( !hdrname ){ REprintf("** nifti_findhdrname: failed to alloc hdrname\n"); free(basename); return NULL; } strcpy(hdrname,basename); strcat(hdrname,elist[efirst]); if (nifti_fileexists(hdrname)) { free(basename); return hdrname; } #ifdef HAVE_LIBZ strcat(hdrname,extzip); if (nifti_fileexists(hdrname)) { free(basename); return hdrname; } #endif /* okay, try the other possibility */ efirst = 1 - efirst; strcpy(hdrname,basename); strcat(hdrname,elist[efirst]); if (nifti_fileexists(hdrname)) { free(basename); return hdrname; } #ifdef HAVE_LIBZ strcat(hdrname,extzip); if (nifti_fileexists(hdrname)) { free(basename); return hdrname; } #endif /**- if nothing has been found, return NULL */ free(basename); free(hdrname); return NULL; } /*------------------------------------------------------------------------*/ /*! check current directory for existing image file \param fname filename to check for \nifti_type nifti_type for dataset - this determines whether to first check for ".nii" or ".img" (since both may exist) \return filename of data/img file on success and NULL if no appropriate file could be found If fname has a valid, uppercase extension, apply all extensions as uppercase. NB: it allocates memory for the image filename, which should be freed when no longer required *//*---------------------------------------------------------------------*/ char * nifti_findimgname(const char* fname , int nifti_type) { /* store all extensions as strings, in case we need to go uppercase */ char *basename, *imgname, elist[2][5] = { ".nii", ".img" }; char extzip[4] = ".gz"; char extnia[5] = ".nia"; char *ext; int first; /* first extension to use */ /* check input file(s) for sanity */ if( !nifti_validfilename(fname) ) return NULL; basename = nifti_makebasename(fname); imgname = (char *)calloc(sizeof(char),strlen(basename)+8); if( !imgname ){ REprintf("** nifti_findimgname: failed to alloc imgname\n"); free(basename); return NULL; } /* if we are looking for uppercase, apply the fact now */ ext = nifti_find_file_extension(fname); if( ext && is_uppercase(ext) ) { make_uppercase(elist[0]); make_uppercase(elist[1]); make_uppercase(extzip); make_uppercase(extnia); } /* only valid extension for ASCII type is .nia, handle first */ if( nifti_type == NIFTI_FTYPE_ASCII ){ strcpy(imgname,basename); strcat(imgname,extnia); if (nifti_fileexists(imgname)) { free(basename); return imgname; } } else { /**- test for .nii and .img (don't assume input type from image type) */ /**- if nifti_type = 1, check for .nii first, else .img first */ /* if we get 3 or more extensions, can make a loop here... */ if (nifti_type == NIFTI_FTYPE_NIFTI1_1) first = 0; /* should match .nii */ else first = 1; /* should match .img */ strcpy(imgname,basename); strcat(imgname,elist[first]); if (nifti_fileexists(imgname)) { free(basename); return imgname; } #ifdef HAVE_LIBZ /* then also check for .gz */ strcat(imgname,extzip); if (nifti_fileexists(imgname)) { free(basename); return imgname; } #endif /* failed to find image file with expected extension, try the other */ strcpy(imgname,basename); strcat(imgname,elist[1-first]); /* can do this with only 2 choices */ if (nifti_fileexists(imgname)) { free(basename); return imgname; } #ifdef HAVE_LIBZ /* then also check for .gz */ strcat(imgname,extzip); if (nifti_fileexists(imgname)) { free(basename); return imgname; } #endif } /**- if nothing has been found, return NULL */ free(basename); free(imgname); return NULL; } /*----------------------------------------------------------------------*/ /*! creates a filename for storing the header, based on nifti_type \param prefix - this will be copied before the suffix is added \param nifti_type - determines the extension, unless one is in prefix \param check - check for existence (fail condition) \param comp - add .gz for compressed name Note that if prefix provides a file suffix, nifti_type is not used. NB: this allocates memory which should be freed \sa nifti_set_filenames *//*-------------------------------------------------------------------*/ char * nifti_makehdrname(const char * prefix, int nifti_type, int check, int comp) { char * iname, * ext; char extnii[5] = ".nii"; /* modifiable, for possible uppercase */ char exthdr[5] = ".hdr"; char extimg[5] = ".img"; char extnia[5] = ".nia"; char extgz[5] = ".gz"; if( !nifti_validfilename(prefix) ) return NULL; /* add space for extension, optional ".gz", and null char */ iname = (char *)calloc(sizeof(char),strlen(prefix)+8); if( !iname ){ REprintf("** small malloc failure!\n"); return NULL; } strcpy(iname, prefix); /* use any valid extension */ if( (ext = nifti_find_file_extension(iname)) != NULL ){ /* if uppercase, convert all extensions */ if( is_uppercase(ext) ) { make_uppercase(extnii); make_uppercase(exthdr); make_uppercase(extimg); make_uppercase(extnia); make_uppercase(extgz); } if( strncmp(ext,extimg,4) == 0 ) memcpy(ext,exthdr,4); /* then convert img name to hdr */ } /* otherwise, make one up */ else if( nifti_type == NIFTI_FTYPE_NIFTI1_1 ) strcat(iname, extnii); else if( nifti_type == NIFTI_FTYPE_ASCII ) strcat(iname, extnia); else strcat(iname, exthdr); #ifdef HAVE_LIBZ /* if compression is requested, make sure of suffix */ if( comp && (!ext || !strstr(iname,extgz)) ) strcat(iname,extgz); #endif /* check for existence failure */ if( check && nifti_fileexists(iname) ){ REprintf("** failure: header file '%s' already exists\n",iname); free(iname); return NULL; } if(g_opts.debug > 2) REprintf("+d made header filename '%s'\n", iname); return iname; } /*----------------------------------------------------------------------*/ /*! creates a filename for storing the image, based on nifti_type \param prefix - this will be copied before the suffix is added \param nifti_type - determines the extension, unless provided by prefix \param check - check for existence (fail condition) \param comp - add .gz for compressed name Note that if prefix provides a file suffix, nifti_type is not used. NB: it allocates memory which should be freed \sa nifti_set_filenames *//*-------------------------------------------------------------------*/ char * nifti_makeimgname(const char * prefix, int nifti_type, int check, int comp) { char * iname, * ext; char extnii[5] = ".nii"; /* modifiable, for possible uppercase */ char exthdr[5] = ".hdr"; char extimg[5] = ".img"; char extnia[5] = ".nia"; char extgz[5] = ".gz"; if( !nifti_validfilename(prefix) ) return NULL; /* add space for extension, optional ".gz", and null char */ iname = (char *)calloc(sizeof(char),strlen(prefix)+8); if( !iname ){ REprintf("** small malloc failure!\n"); return NULL; } strcpy(iname, prefix); /* use any valid extension */ if( (ext = nifti_find_file_extension(iname)) != NULL ){ /* if uppercase, convert all extensions */ if( is_uppercase(ext) ) { make_uppercase(extnii); make_uppercase(exthdr); make_uppercase(extimg); make_uppercase(extnia); make_uppercase(extgz); } if( strncmp(ext,exthdr,4) == 0 ) memcpy(ext,extimg,4); /* then convert hdr name to img */ } /* otherwise, make one up */ else if( nifti_type == NIFTI_FTYPE_NIFTI1_1 ) strcat(iname, extnii); else if( nifti_type == NIFTI_FTYPE_ASCII ) strcat(iname, extnia); else strcat(iname, extimg); #ifdef HAVE_LIBZ /* if compression is requested, make sure of suffix */ if( comp && (!ext || !strstr(iname,extgz)) ) strcat(iname,extgz); #endif /* check for existence failure */ if( check && nifti_fileexists(iname) ){ REprintf("** failure: image file '%s' already exists\n",iname); free(iname); return NULL; } if( g_opts.debug > 2 ) REprintf("+d made image filename '%s'\n",iname); return iname; } /*----------------------------------------------------------------------*/ /*! create and set new filenames, based on prefix and image type \param nim pointer to nifti_image in which to set filenames \param prefix (required) prefix for output filenames \param check check for previous existence of filename (existence is an error condition) \param set_byte_order flag to set nim->byteorder here (this is probably a logical place to do so) \return 0 on successful update \warning this will free() any existing names and create new ones \sa nifti_makeimgname, nifti_makehdrname, nifti_type_and_names_match *//*--------------------------------------------------------------------*/ int nifti_set_filenames( nifti_image * nim, const char * prefix, int check, int set_byte_order ) { int comp = nifti_is_gzfile(prefix); if( !nim || !prefix ){ REprintf("** nifti_set_filenames, bad params %p, %p\n", (void *)nim,prefix); return -1; } if( g_opts.debug > 1 ) REprintf("+d modifying output filenames using prefix %s\n", prefix); if( nim->fname ) free(nim->fname); if( nim->iname ) free(nim->iname); nim->fname = nifti_makehdrname(prefix, nim->nifti_type, check, comp); nim->iname = nifti_makeimgname(prefix, nim->nifti_type, check, comp); if( !nim->fname || !nim->iname ){ REprintf("nifti_set_filenames: failed to set prefix for %s.\n",prefix); return -1; } if( set_byte_order ) nim->byteorder = nifti_short_order() ; if( nifti_set_type_from_names(nim) < 0 ) return -1; if( g_opts.debug > 2 ) REprintf("+d have new filenames %s and %s\n",nim->fname,nim->iname); return 0; } /*--------------------------------------------------------------------------*/ /*! check whether nifti_type matches fname and iname for the nifti_image - if type 0 or 2, expect .hdr/.img pair - if type 1, expect .nii (and names must match) \param nim given nifti_image \param show_warn if set, print a warning message for any mis-match \return - 1 if the values seem to match - 0 if there is a mis-match - -1 if there is not sufficient information to create file(s) \sa NIFTI_FTYPE_* codes in nifti1_io.h \sa nifti_set_type_from_names, is_valid_nifti_type *//*------------------------------------------------------------------------*/ int nifti_type_and_names_match( nifti_image * nim, int show_warn ) { char func[] = "nifti_type_and_names_match"; char * ext_h, * ext_i; /* header and image filename extensions */ int errs = 0; /* error counter */ /* sanity checks */ if( !nim ){ if( show_warn ) REprintf("** %s: missing nifti_image\n", func); return -1; } if( !nim->fname ){ if( show_warn ) REprintf("** %s: missing header filename\n", func); errs++; } if( !nim->iname ){ if( show_warn ) REprintf("** %s: missing image filename\n", func); errs++; } if( !is_valid_nifti_type(nim->nifti_type) ){ if( show_warn ) REprintf("** %s: bad nifti_type %d\n", func, nim->nifti_type); errs++; } if( errs ) return -1; /* then do not proceed */ /* get pointers to extensions */ ext_h = nifti_find_file_extension( nim->fname ); ext_i = nifti_find_file_extension( nim->iname ); /* check for filename extensions */ if( !ext_h ){ if( show_warn ) REprintf("-d missing NIFTI extension in header filename, %s\n", nim->fname); errs++; } if( !ext_i ){ if( show_warn ) REprintf("-d missing NIFTI extension in image filename, %s\n", nim->iname); errs++; } if( errs ) return 0; /* do not proceed, but this is just a mis-match */ /* general tests */ if( nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ){ /* .nii */ if( fileext_n_compare(ext_h,".nii",4) ) { if( show_warn ) REprintf( "-d NIFTI_FTYPE 1, but no .nii extension in header filename, %s\n", nim->fname); errs++; } if( fileext_n_compare(ext_i,".nii",4) ) { if( show_warn ) REprintf( "-d NIFTI_FTYPE 1, but no .nii extension in image filename, %s\n", nim->iname); errs++; } if( strcmp(nim->fname, nim->iname) != 0 ){ if( show_warn ) REprintf( "-d NIFTI_FTYPE 1, but header and image filenames differ: %s, %s\n", nim->fname, nim->iname); errs++; } } else if( (nim->nifti_type == NIFTI_FTYPE_NIFTI1_2) || /* .hdr/.img */ (nim->nifti_type == NIFTI_FTYPE_ANALYZE) ) { if( fileext_n_compare(ext_h,".hdr",4) != 0 ){ if( show_warn ) REprintf("-d no '.hdr' extension, but NIFTI type is %d, %s\n", nim->nifti_type, nim->fname); errs++; } if( fileext_n_compare(ext_i,".img",4) != 0 ){ if( show_warn ) REprintf("-d no '.img' extension, but NIFTI type is %d, %s\n", nim->nifti_type, nim->iname); errs++; } } /* ignore any other nifti_type */ return 1; } /* like strcmp, but also check against capitalization of known_ext * (test as local string, with max length 7) */ static int fileext_compare(const char * test_ext, const char * known_ext) { char caps[8] = ""; int c, cmp, len; /* if equal, don't need to check case (store to avoid multiple calls) */ cmp = strcmp(test_ext, known_ext); if( cmp == 0 ) return cmp; /* if anything odd, use default */ if( !test_ext || !known_ext ) return cmp; len = strlen(known_ext); if( len > 7 ) return cmp; /* if here, strings are different but need to check upper-case */ for(c = 0; c < len; c++ ) caps[c] = toupper(known_ext[c]); caps[c] = '\0'; return strcmp(test_ext, caps); } /* like strncmp, but also check against capitalization of known_ext * (test as local string, with max length 7) */ static int fileext_n_compare(const char * test_ext, const char * known_ext, int maxlen) { char caps[8] = ""; int c, cmp, len; /* if equal, don't need to check case (store to avoid multiple calls) */ cmp = strncmp(test_ext, known_ext, maxlen); if( cmp == 0 ) return cmp; /* if anything odd, use default */ if( !test_ext || !known_ext ) return cmp; len = strlen(known_ext); if( len > maxlen ) len = maxlen; /* ignore anything past maxlen */ if( len > 7 ) return cmp; /* if here, strings are different but need to check upper-case */ for(c = 0; c < len; c++ ) caps[c] = toupper(known_ext[c]); caps[c] = '\0'; return strncmp(test_ext, caps, maxlen); } /* return 1 if there are uppercase but no lowercase */ static int is_uppercase(const char * str) { int c, hasupper = 0; if( !str || !*str ) return 0; for(c = 0; c < strlen(str); c++ ) { if( islower(str[c]) ) return 0; if( !hasupper && isupper(str[c]) ) hasupper = 1; } return hasupper; } /* return 1 if there are both uppercase and lowercase characters */ static int is_mixedcase(const char * str) { int c, hasupper = 0, haslower = 0; if( !str || !*str ) return 0; for(c = 0; c < strlen(str); c++ ) { if( !haslower && islower(str[c]) ) haslower = 1; if( !hasupper && isupper(str[c]) ) hasupper = 1; if( haslower && hasupper ) return 1; } return 0; } /* convert any lowercase chars to uppercase */ static int make_uppercase(char * str) { int c; if( !str || !*str ) return 0; for(c = 0; c < strlen(str); c++ ) if( islower(str[c]) ) str[c] = toupper(str[c]); return 0; } /* convert any uppercase chars to lowercase */ static int make_lowercase(char * str) { int c; if( !str || !*str ) return 0; for(c = 0; c < strlen(str); c++ ) if( isupper(str[c]) ) str[c] = tolower(str[c]); return 0; } /* run strcmp against of list of strings * return index of equality, if found * else return -1 */ static int compare_strlist(const char * str, char ** strlist, int len) { int c; if( len <= 0 || !str || !strlist ) return -1; for( c = 0; c < len; c++ ) if( strlist[c] && !strcmp(str, strlist[c]) ) return c; return -1; } /*--------------------------------------------------------------------------*/ /*! check whether the given type is on the "approved" list The code is valid if it is non-negative, and does not exceed NIFTI_MAX_FTYPE. \return 1 if nifti_type is valid, 0 otherwise \sa NIFTI_FTYPE_* codes in nifti1_io.h *//*------------------------------------------------------------------------*/ int is_valid_nifti_type( int nifti_type ) { if( nifti_type >= NIFTI_FTYPE_ANALYZE && /* smallest type, 0 */ nifti_type <= NIFTI_MAX_FTYPE ) return 1; return 0; } /*--------------------------------------------------------------------------*/ /*! check whether the given type is on the "approved" list The type is explicitly checked against the NIFTI_TYPE_* list in nifti1.h. \return 1 if dtype is valid, 0 otherwise \sa NIFTI_TYPE_* codes in nifti1.h *//*------------------------------------------------------------------------*/ int nifti_is_valid_datatype( int dtype ) { if( dtype == NIFTI_TYPE_UINT8 || dtype == NIFTI_TYPE_INT16 || dtype == NIFTI_TYPE_INT32 || dtype == NIFTI_TYPE_FLOAT32 || dtype == NIFTI_TYPE_COMPLEX64 || dtype == NIFTI_TYPE_FLOAT64 || dtype == NIFTI_TYPE_RGB24 || dtype == NIFTI_TYPE_RGBA32 || dtype == NIFTI_TYPE_INT8 || dtype == NIFTI_TYPE_UINT16 || dtype == NIFTI_TYPE_UINT32 || dtype == NIFTI_TYPE_INT64 || dtype == NIFTI_TYPE_UINT64 || dtype == NIFTI_TYPE_FLOAT128 || dtype == NIFTI_TYPE_COMPLEX128 || dtype == NIFTI_TYPE_COMPLEX256 ) return 1; return 0; } /*--------------------------------------------------------------------------*/ /*! set the nifti_type field based on fname and iname Note that nifti_type is changed only when it does not match the filenames. \return 0 on success, -1 on error \sa is_valid_nifti_type, nifti_type_and_names_match *//*------------------------------------------------------------------------*/ int nifti_set_type_from_names( nifti_image * nim ) { /* error checking first */ if( !nim ){ REprintf("** NSTFN: no nifti_image\n"); return -1; } if( !nim->fname || !nim->iname ){ REprintf("** NSTFN: missing filename(s) fname @ %p, iname @ %p\n", nim->fname, nim->iname); return -1; } if( ! nifti_validfilename ( nim->fname ) || ! nifti_validfilename ( nim->iname ) || ! nifti_find_file_extension( nim->fname ) || ! nifti_find_file_extension( nim->iname ) ) { REprintf("** NSTFN: invalid filename(s) fname='%s', iname='%s'\n", nim->fname, nim->iname); return -1; } if( g_opts.debug > 2 ) REprintf("-d verify nifti_type from filenames: %d",nim->nifti_type); /* type should be NIFTI_FTYPE_ASCII if extension is .nia */ if( (fileext_compare(nifti_find_file_extension(nim->fname),".nia")==0)){ nim->nifti_type = NIFTI_FTYPE_ASCII; } else { /* not too picky here, do what must be done, and then verify */ if( strcmp(nim->fname, nim->iname) == 0 ) /* one file, type 1 */ nim->nifti_type = NIFTI_FTYPE_NIFTI1_1; else if( nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ) /* cannot be type 1 */ nim->nifti_type = NIFTI_FTYPE_NIFTI1_2; } if( g_opts.debug > 2 ) REprintf(" -> %d\n",nim->nifti_type); if( g_opts.debug > 1 ) /* warn user about anything strange */ nifti_type_and_names_match(nim, 1); if( is_valid_nifti_type(nim->nifti_type) ) return 0; /* success! */ REprintf("** NSTFN: bad nifti_type %d, for '%s' and '%s'\n", nim->nifti_type, nim->fname, nim->iname); return -1; } /*--------------------------------------------------------------------------*/ /*! Determine if this is a NIFTI-formatted file.
   \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.
   
*//*------------------------------------------------------------------------*/ int is_nifti_file( const char *hname ) { struct nifti_1_header nhdr ; znzFile fp ; int ii ; char *tmpname; /* bad input name? */ if( !nifti_validfilename(hname) ) return -1 ; /* open file */ tmpname = nifti_findhdrname(hname); if( tmpname == NULL ){ if( g_opts.debug > 0 ) REprintf("** no header file found for '%s'\n",hname); return -1; } fp = znzopen( tmpname , "rb" , nifti_is_gzfile(tmpname) ) ; free(tmpname); if (znz_isnull(fp)) return -1 ; /* bad open? */ /* read header, close file */ ii = (int)znzread( &nhdr , 1 , sizeof(nhdr) , fp ) ; znzclose( fp ) ; if( ii < (int) sizeof(nhdr) ) return -1 ; /* bad read? */ /* check for NIFTI-ness */ if( NIFTI_VERSION(nhdr) != 0 ){ return ( NIFTI_ONEFILE(nhdr) ) ? 1 : 2 ; } /* check for ANALYZE-ness (sizeof_hdr field == 348) */ ii = nhdr.sizeof_hdr ; if( ii == (int)sizeof(nhdr) ) return 0 ; /* matches */ /* try byte-swapping header */ swap_4(ii) ; if( ii == (int)sizeof(nhdr) ) return 0 ; /* matches */ return -1 ; /* not good */ } static int print_hex_vals( const char * data, int nbytes) { int c; if ( !data || nbytes < 1 ) return -1; Rprintf("0x"); for ( c = 0; c < nbytes; c++ ) Rprintf(" %x", data[c]); return 0; } /*----------------------------------------------------------------------*/ /*! display the contents of the nifti_1_header (send to stdout) \param info if non-NULL, print this character string \param hp pointer to nifti_1_header *//*--------------------------------------------------------------------*/ int disp_nifti_1_header( const char * info, const nifti_1_header * hp ) { int c; Rprintf( "-------------------------------------------------------\n"); if ( info ) Rprintf( info ); if ( !hp ){ Rprintf(" ** no nifti_1_header to display!\n"); return 1; } Rprintf(" nifti_1_header :\n" " sizeof_hdr = %d\n" " data_type[10] = ", hp->sizeof_hdr); print_hex_vals(hp->data_type, 10); Rprintf( "\n" " db_name[18] = "); print_hex_vals(hp->db_name, 18); Rprintf( "\n" " extents = %d\n" " session_error = %d\n" " regular = 0x%x\n" " dim_info = 0x%x\n", hp->extents, hp->session_error, hp->regular, hp->dim_info ); Rprintf( " dim[8] ="); for ( c = 0; c < 8; c++ ) Rprintf(" %d", hp->dim[c]); Rprintf( "\n" " intent_p1 = %f\n" " intent_p2 = %f\n" " intent_p3 = %f\n" " intent_code = %d\n" " datatype = %d\n" " bitpix = %d\n" " slice_start = %d\n" " pixdim[8] =", hp->intent_p1, hp->intent_p2, hp->intent_p3, hp->intent_code, hp->datatype, hp->bitpix, hp->slice_start); /* break pixdim over 2 lines */ for ( c = 0; c < 4; c++ ) Rprintf(" %f", hp->pixdim[c]); Rprintf( "\n "); for ( c = 4; c < 8; c++ ) Rprintf(" %f", hp->pixdim[c]); Rprintf( "\n" " vox_offset = %f\n" " scl_slope = %f\n" " scl_inter = %f\n" " slice_end = %d\n" " slice_code = %d\n" " xyzt_units = 0x%x\n" " cal_max = %f\n" " cal_min = %f\n" " slice_duration = %f\n" " toffset = %f\n" " glmax = %d\n" " glmin = %d\n", hp->vox_offset, hp->scl_slope, hp->scl_inter, hp->slice_end, hp->slice_code, hp->xyzt_units, hp->cal_max, hp->cal_min, hp->slice_duration, hp->toffset, hp->glmax, hp->glmin); Rprintf( " descrip = '%.80s'\n" " aux_file = '%.24s'\n" " qform_code = %d\n" " sform_code = %d\n" " quatern_b = %f\n" " quatern_c = %f\n" " quatern_d = %f\n" " qoffset_x = %f\n" " qoffset_y = %f\n" " qoffset_z = %f\n" " srow_x[4] = %f, %f, %f, %f\n" " srow_y[4] = %f, %f, %f, %f\n" " srow_z[4] = %f, %f, %f, %f\n" " intent_name = '%-.16s'\n" " magic = '%-.4s'\n", hp->descrip, hp->aux_file, hp->qform_code, hp->sform_code, hp->quatern_b, hp->quatern_c, hp->quatern_d, hp->qoffset_x, hp->qoffset_y, hp->qoffset_z, hp->srow_x[0], hp->srow_x[1], hp->srow_x[2], hp->srow_x[3], hp->srow_y[0], hp->srow_y[1], hp->srow_y[2], hp->srow_y[3], hp->srow_z[0], hp->srow_z[1], hp->srow_z[2], hp->srow_z[3], hp->intent_name, hp->magic); Rprintf( "-------------------------------------------------------\n"); /*fflush(stdout);*/ return 0; } #undef ERREX #define ERREX(msg) \ do{ REprintf("** ERROR: nifti_convert_nhdr2nim: %s\n", (msg) ) ; \ return NULL ; } while(0) /*----------------------------------------------------------------------*/ /*! convert a nifti_1_header into a nift1_image \return an allocated nifti_image, or NULL on failure *//*--------------------------------------------------------------------*/ nifti_image* nifti_convert_nhdr2nim(struct nifti_1_header nhdr, const char * fname) { int ii , doswap , ioff ; int is_nifti , is_onefile ; nifti_image *nim; nim = (nifti_image *)calloc( 1 , sizeof(nifti_image) ) ; if( !nim ) ERREX("failed to allocate nifti image"); /* be explicit with pointers */ nim->fname = NULL; nim->iname = NULL; nim->data = NULL; /**- check if we must swap bytes */ doswap = need_nhdr_swap(nhdr.dim[0], nhdr.sizeof_hdr); /* swap data flag */ if( doswap < 0 ){ if( doswap == -1 ) ERREX("bad dim[0]") ; ERREX("bad sizeof_hdr") ; /* else */ } /**- determine if this is a NIFTI-1 compliant header */ is_nifti = NIFTI_VERSION(nhdr) ; /* * before swapping header, record the Analyze75 orient code */ if(!is_nifti) { /**- in analyze75, the orient code is at the same address as * qform_code, but it's just one byte * the qform_code will be zero, at which point you can check * analyze75_orient if you care to. */ unsigned char c = *((char *)(&nhdr.qform_code)); nim->analyze75_orient = (analyze_75_orient_code)c; } if( doswap ) { if ( g_opts.debug > 3 ) disp_nifti_1_header("-d ni1 pre-swap: ", &nhdr); swap_nifti_header( &nhdr , is_nifti ) ; } if ( g_opts.debug > 2 ) disp_nifti_1_header("-d nhdr2nim : ", &nhdr); if( nhdr.datatype == DT_BINARY || nhdr.datatype == DT_UNKNOWN ) ERREX("bad datatype") ; if( nhdr.dim[1] <= 0 ) ERREX("bad dim[1]") ; /* fix bad dim[] values in the defined dimension range */ for( ii=2 ; ii <= nhdr.dim[0] ; ii++ ) if( nhdr.dim[ii] <= 0 ) nhdr.dim[ii] = 1 ; /* fix any remaining bad dim[] values, so garbage does not propagate */ /* (only values 0 or 1 seem rational, otherwise set to arbirary 1) */ for( ii=nhdr.dim[0]+1 ; ii <= 7 ; ii++ ) if( nhdr.dim[ii] != 1 && nhdr.dim[ii] != 0) nhdr.dim[ii] = 1 ; #if 0 /* rely on dim[0], do not attempt to modify it 16 Nov 2005 [rickr] */ /**- get number of dimensions (ignoring dim[0] now) */ for( ii=7 ; ii >= 2 ; ii-- ) /* loop backwards until we */ if( nhdr.dim[ii] > 1 ) break ; /* find a dim bigger than 1 */ ndim = ii ; #endif /**- set bad grid spacings to 1.0 */ for( ii=1 ; ii <= nhdr.dim[0] ; ii++ ){ if( nhdr.pixdim[ii] == 0.0 || !IS_GOOD_FLOAT(nhdr.pixdim[ii]) ) nhdr.pixdim[ii] = 1.0 ; } is_onefile = is_nifti && NIFTI_ONEFILE(nhdr) ; if( is_nifti ) nim->nifti_type = (is_onefile) ? NIFTI_FTYPE_NIFTI1_1 : NIFTI_FTYPE_NIFTI1_2 ; else nim->nifti_type = NIFTI_FTYPE_ANALYZE ; ii = nifti_short_order() ; if( doswap ) nim->byteorder = REVERSE_ORDER(ii) ; else nim->byteorder = ii ; /**- set dimensions of data array */ nim->ndim = nim->dim[0] = nhdr.dim[0]; nim->nx = nim->dim[1] = nhdr.dim[1]; nim->ny = nim->dim[2] = nhdr.dim[2]; nim->nz = nim->dim[3] = nhdr.dim[3]; nim->nt = nim->dim[4] = nhdr.dim[4]; nim->nu = nim->dim[5] = nhdr.dim[5]; nim->nv = nim->dim[6] = nhdr.dim[6]; nim->nw = nim->dim[7] = nhdr.dim[7]; for( ii=1, nim->nvox=1; ii <= nhdr.dim[0]; ii++ ) nim->nvox *= nhdr.dim[ii]; /**- set the type of data in voxels and how many bytes per voxel */ nim->datatype = nhdr.datatype ; nifti_datatype_sizes( nim->datatype , &(nim->nbyper) , &(nim->swapsize) ) ; if( nim->nbyper == 0 ){ free(nim); ERREX("bad datatype"); } /**- set the grid spacings */ nim->dx = nim->pixdim[1] = nhdr.pixdim[1] ; nim->dy = nim->pixdim[2] = nhdr.pixdim[2] ; nim->dz = nim->pixdim[3] = nhdr.pixdim[3] ; nim->dt = nim->pixdim[4] = nhdr.pixdim[4] ; nim->du = nim->pixdim[5] = nhdr.pixdim[5] ; nim->dv = nim->pixdim[6] = nhdr.pixdim[6] ; nim->dw = nim->pixdim[7] = nhdr.pixdim[7] ; /**- compute qto_xyz transformation from pixel indexes (i,j,k) to (x,y,z) */ if( !is_nifti || nhdr.qform_code <= 0 ){ /**- if not nifti or qform_code <= 0, use grid spacing for qto_xyz */ nim->qto_xyz.m[0][0] = nim->dx ; /* grid spacings */ nim->qto_xyz.m[1][1] = nim->dy ; /* along diagonal */ nim->qto_xyz.m[2][2] = nim->dz ; /* off diagonal is zero */ nim->qto_xyz.m[0][1]=nim->qto_xyz.m[0][2]=nim->qto_xyz.m[0][3] = 0.0; nim->qto_xyz.m[1][0]=nim->qto_xyz.m[1][2]=nim->qto_xyz.m[1][3] = 0.0; nim->qto_xyz.m[2][0]=nim->qto_xyz.m[2][1]=nim->qto_xyz.m[2][3] = 0.0; /* last row is always [ 0 0 0 1 ] */ nim->qto_xyz.m[3][0]=nim->qto_xyz.m[3][1]=nim->qto_xyz.m[3][2] = 0.0; nim->qto_xyz.m[3][3]= 1.0 ; nim->qform_code = NIFTI_XFORM_UNKNOWN ; if( g_opts.debug > 1 ) REprintf("-d no qform provided\n"); } else { /**- else NIFTI: use the quaternion-specified transformation */ nim->quatern_b = FIXED_FLOAT( nhdr.quatern_b ) ; nim->quatern_c = FIXED_FLOAT( nhdr.quatern_c ) ; nim->quatern_d = FIXED_FLOAT( nhdr.quatern_d ) ; nim->qoffset_x = FIXED_FLOAT(nhdr.qoffset_x) ; nim->qoffset_y = FIXED_FLOAT(nhdr.qoffset_y) ; nim->qoffset_z = FIXED_FLOAT(nhdr.qoffset_z) ; nim->qfac = (nhdr.pixdim[0] < 0.0) ? -1.0 : 1.0 ; /* left-handedness? */ nim->qto_xyz = nifti_quatern_to_mat44( nim->quatern_b, nim->quatern_c, nim->quatern_d, nim->qoffset_x, nim->qoffset_y, nim->qoffset_z, nim->dx , nim->dy , nim->dz , nim->qfac ) ; nim->qform_code = nhdr.qform_code ; if( g_opts.debug > 1 ) nifti_disp_matrix_orient("-d qform orientations:\n", nim->qto_xyz); } /**- load inverse transformation (x,y,z) -> (i,j,k) */ nim->qto_ijk = nifti_mat44_inverse( nim->qto_xyz ) ; /**- load sto_xyz affine transformation, if present */ if( !is_nifti || nhdr.sform_code <= 0 ){ /**- if not nifti or sform_code <= 0, then no sto transformation */ nim->sform_code = NIFTI_XFORM_UNKNOWN ; if( g_opts.debug > 1 ) REprintf("-d no sform provided\n"); } else { /**- else set the sto transformation from srow_*[] */ nim->sto_xyz.m[0][0] = nhdr.srow_x[0] ; nim->sto_xyz.m[0][1] = nhdr.srow_x[1] ; nim->sto_xyz.m[0][2] = nhdr.srow_x[2] ; nim->sto_xyz.m[0][3] = nhdr.srow_x[3] ; nim->sto_xyz.m[1][0] = nhdr.srow_y[0] ; nim->sto_xyz.m[1][1] = nhdr.srow_y[1] ; nim->sto_xyz.m[1][2] = nhdr.srow_y[2] ; nim->sto_xyz.m[1][3] = nhdr.srow_y[3] ; nim->sto_xyz.m[2][0] = nhdr.srow_z[0] ; nim->sto_xyz.m[2][1] = nhdr.srow_z[1] ; nim->sto_xyz.m[2][2] = nhdr.srow_z[2] ; nim->sto_xyz.m[2][3] = nhdr.srow_z[3] ; /* last row is always [ 0 0 0 1 ] */ nim->sto_xyz.m[3][0]=nim->sto_xyz.m[3][1]=nim->sto_xyz.m[3][2] = 0.0; nim->sto_xyz.m[3][3]= 1.0 ; nim->sto_ijk = nifti_mat44_inverse( nim->sto_xyz ) ; nim->sform_code = nhdr.sform_code ; if( g_opts.debug > 1 ) nifti_disp_matrix_orient("-d sform orientations:\n", nim->sto_xyz); } /**- set miscellaneous NIFTI stuff */ if( is_nifti ){ nim->scl_slope = FIXED_FLOAT( nhdr.scl_slope ) ; nim->scl_inter = FIXED_FLOAT( nhdr.scl_inter ) ; nim->intent_code = nhdr.intent_code ; nim->intent_p1 = FIXED_FLOAT( nhdr.intent_p1 ) ; nim->intent_p2 = FIXED_FLOAT( nhdr.intent_p2 ) ; nim->intent_p3 = FIXED_FLOAT( nhdr.intent_p3 ) ; nim->toffset = FIXED_FLOAT( nhdr.toffset ) ; memcpy(nim->intent_name,nhdr.intent_name,15); nim->intent_name[15] = '\0'; nim->xyz_units = XYZT_TO_SPACE(nhdr.xyzt_units) ; nim->time_units = XYZT_TO_TIME (nhdr.xyzt_units) ; nim->freq_dim = DIM_INFO_TO_FREQ_DIM ( nhdr.dim_info ) ; nim->phase_dim = DIM_INFO_TO_PHASE_DIM( nhdr.dim_info ) ; nim->slice_dim = DIM_INFO_TO_SLICE_DIM( nhdr.dim_info ) ; nim->slice_code = nhdr.slice_code ; nim->slice_start = nhdr.slice_start ; nim->slice_end = nhdr.slice_end ; nim->slice_duration = FIXED_FLOAT(nhdr.slice_duration) ; } /**- set Miscellaneous ANALYZE stuff */ nim->cal_min = FIXED_FLOAT(nhdr.cal_min) ; nim->cal_max = FIXED_FLOAT(nhdr.cal_max) ; memcpy(nim->descrip ,nhdr.descrip ,79) ; nim->descrip [79] = '\0' ; memcpy(nim->aux_file,nhdr.aux_file,23) ; nim->aux_file[23] = '\0' ; /**- set ioff from vox_offset (but at least sizeof(header)) */ is_onefile = is_nifti && NIFTI_ONEFILE(nhdr) ; if( is_onefile ){ ioff = (int)nhdr.vox_offset ; if( ioff < (int) sizeof(nhdr) ) ioff = (int) sizeof(nhdr) ; } else { ioff = (int)nhdr.vox_offset ; } nim->iname_offset = ioff ; /**- deal with file names if set */ if (fname!=NULL) { nifti_set_filenames(nim,fname,0,0); if (nim->iname==NULL) { ERREX("bad filename"); } } else { nim->fname = NULL; nim->iname = NULL; } /* clear extension fields */ nim->num_ext = 0; nim->ext_list = NULL; return nim; } #undef ERREX #define ERREX(msg) \ do{ REprintf("** ERROR: nifti_image_open(%s): %s\n", \ (hname != NULL) ? hname : "(null)" , (msg) ) ; \ return fptr ; } while(0) /*************************************************************** * nifti_image_open ***************************************************************/ /*! znzFile nifti_image_open( char *hname, char *opts , nifti_image **nim) \brief Read in NIFTI-1 or ANALYZE-7.5 file (pair) header information into a nifti_image struct. - The image data is not read from disk (it may be read later using nifti_image_load(), for example). - The image data will be stored in whatever data format the input data is; no scaling will be applied. - DT_BINARY data is not supported. - nifti_image_free() can be used to delete the returned struct, when you are done with it. \param hname filename of dataset .hdr or .nii file \param opts options string for opening the header file \param nim pointer to pointer to nifti_image struct (this routine allocates the nifti_image struct) \return file pointer (gzippable) to the file with the image data, ready for reading.
NULL if something fails badly. \sa nifti_image_load, nifti_image_free */ znzFile nifti_image_open(const char * hname, char * opts, nifti_image ** nim) { znzFile fptr=NULL; /* open the hdr and reading it in, but do not load the data */ *nim = nifti_image_read(hname,0); /* open the image file, ready for reading (compressed works for all reads) */ if( ((*nim) == NULL) || ((*nim)->iname == NULL) || ((*nim)->nbyper <= 0) || ((*nim)->nvox <= 0) ) ERREX("bad header info") ; /* open image data file */ fptr = znzopen( (*nim)->iname, opts, nifti_is_gzfile((*nim)->iname) ); if( znz_isnull(fptr) ) ERREX("Can't open data file") ; return fptr; } /*----------------------------------------------------------------------*/ /*! return an allocated and filled nifti_1_header struct Read the binary header from disk, and swap bytes if necessary. \return an allocated nifti_1_header struct, or NULL on failure \param hname name of file containing header \param swapped if not NULL, return whether header bytes were swapped \param check flag to check for invalid nifti_1_header \warning ASCII header type is not supported \sa nifti_image_read, nifti_image_free, nifti_image_read_bricks *//*--------------------------------------------------------------------*/ nifti_1_header * nifti_read_header(const char * hname, int * swapped, int check) { nifti_1_header nhdr, * hptr; znzFile fp; int bytes, lswap; char * hfile; char fname[] = { "nifti_read_header" }; /* determine file name to use for header */ hfile = nifti_findhdrname(hname); if( hfile == NULL ){ if( g_opts.debug > 0 ) LNI_FERR(fname,"failed to find header file for", hname); return NULL; } else if( g_opts.debug > 1 ) REprintf("-d %s: found header filename '%s'\n",fname,hfile); fp = znzopen( hfile, "rb", nifti_is_gzfile(hfile) ); if( znz_isnull(fp) ){ if( g_opts.debug > 0 ) LNI_FERR(fname,"failed to open header file",hfile); free(hfile); return NULL; } free(hfile); /* done with filename */ if( has_ascii_header(fp) == 1 ){ znzclose( fp ); if( g_opts.debug > 0 ) LNI_FERR(fname,"ASCII header type not supported",hname); return NULL; } /* read the binary header */ bytes = (int)znzread( &nhdr, 1, sizeof(nhdr), fp ); znzclose( fp ); /* we are done with the file now */ if( bytes < (int)sizeof(nhdr) ){ if( g_opts.debug > 0 ){ LNI_FERR(fname,"bad binary header read for file", hname); REprintf(" - read %d of %d bytes\n",bytes, (int)sizeof(nhdr)); } return NULL; } /* now just decide on byte swapping */ lswap = need_nhdr_swap(nhdr.dim[0], nhdr.sizeof_hdr); /* swap data flag */ if( check && lswap < 0 ){ LNI_FERR(fname,"bad nifti_1_header for file", hname); return NULL; } else if ( lswap < 0 ) { lswap = 0; /* if swapping does not help, don't do it */ if(g_opts.debug > 1) REprintf("-- swap failure, none applied\n"); } if( lswap ) { if ( g_opts.debug > 3 ) disp_nifti_1_header("-d nhdr pre-swap: ", &nhdr); swap_nifti_header( &nhdr , NIFTI_VERSION(nhdr) ) ; } if ( g_opts.debug > 2 ) disp_nifti_1_header("-d nhdr post-swap: ", &nhdr); if ( check && ! nifti_hdr_looks_good(&nhdr) ){ LNI_FERR(fname,"nifti_1_header looks bad for file", hname); return NULL; } /* all looks good, so allocate memory for and return the header */ hptr = (nifti_1_header *)malloc(sizeof(nifti_1_header)); if( ! hptr ){ REprintf("** nifti_read_hdr: failed to alloc nifti_1_header\n"); return NULL; } if( swapped ) *swapped = lswap; /* only if they care */ memcpy(hptr, &nhdr, sizeof(nifti_1_header)); return hptr; } /*----------------------------------------------------------------------*/ /*! decide if this nifti_1_header structure looks reasonable Check dim[0], dim[1], sizeof_hdr, and datatype. Check magic string for "n+1". Maybe more tests will follow. \return 1 if the header seems valid, 0 otherwise \sa nifti_nim_is_valid, valid_nifti_extensions *//*--------------------------------------------------------------------*/ int nifti_hdr_looks_good(const nifti_1_header * hdr) { int is_nifti, c, errs = 0; /* check dim[0] and sizeof_hdr */ if( need_nhdr_swap(hdr->dim[0], hdr->sizeof_hdr) < 0 ){ if( g_opts.debug > 0 ) REprintf("** bad nhdr fields: dim0, sizeof_hdr = %d, %d\n", hdr->dim[0], hdr->sizeof_hdr); errs++; } /* check the valid dimension sizes (maybe dim[0] is bad) */ for( c = 1; c <= hdr->dim[0] && c <= 7; c++ ) if( hdr->dim[c] <= 0 ){ if( g_opts.debug > 0 ) REprintf("** bad nhdr field: dim[%d] = %d\n",c,hdr->dim[c]); errs++; } is_nifti = NIFTI_VERSION(*hdr); /* determine header type */ if( is_nifti ){ /* NIFTI */ if( ! nifti_datatype_is_valid(hdr->datatype, 1) ){ if( g_opts.debug > 0 ) REprintf("** bad NIFTI datatype in hdr, %d\n",hdr->datatype); errs++; } } else { /* ANALYZE 7.5 */ if( g_opts.debug > 1 ) /* maybe tell user it's an ANALYZE hdr */ REprintf( "-- nhdr magic field implies ANALYZE: magic = '%.4s'\n",hdr->magic); if( ! nifti_datatype_is_valid(hdr->datatype, 0) ){ if( g_opts.debug > 0 ) REprintf("** bad ANALYZE datatype in hdr, %d\n",hdr->datatype); errs++; } } if( errs ) return 0; /* problems */ if( g_opts.debug > 2 ) REprintf("-d nifti header looks good\n"); return 1; /* looks good */ } /*---------------------------------------------------------------------- * check whether byte swapping is needed * * dim[0] should be in [0,7], and sizeof_hdr should be accurate * * \returns > 0 : needs swap * 0 : does not need swap * < 0 : error condition *----------------------------------------------------------------------*/ static int need_nhdr_swap( short dim0, int hdrsize ) { short d0 = dim0; /* so we won't have to swap them on the stack */ int hsize = hdrsize; if( d0 != 0 ){ /* then use it for the check */ if( d0 > 0 && d0 <= 7 ) return 0; nifti_swap_2bytes(1, &d0); /* swap? */ if( d0 > 0 && d0 <= 7 ) return 1; if( g_opts.debug > 1 ){ REprintf("** NIFTI: bad swapped d0 = %d, unswapped = ", d0); nifti_swap_2bytes(1, &d0); /* swap? */ REprintf("%d\n", d0); } return -1; /* bad, naughty d0 */ } /* dim[0] == 0 should not happen, but could, so try hdrsize */ if( hsize == sizeof(nifti_1_header) ) return 0; nifti_swap_4bytes(1, &hsize); /* swap? */ if( hsize == sizeof(nifti_1_header) ) return 1; if( g_opts.debug > 1 ){ REprintf("** NIFTI: bad swapped hsize = %d, unswapped = ", hsize); nifti_swap_4bytes(1, &hsize); /* swap? */ REprintf("%d\n", hsize); } return -2; /* bad, naughty hsize */ } /* use macro LNI_FILE_ERROR instead of ERREX() #undef ERREX #define ERREX(msg) \ do{ fprintf(stderr,"** ERROR: nifti_image_read(%s): %s\n", \ (hname != NULL) ? hname : "(null)" , (msg) ) ; \ return NULL ; } while(0) */ /*************************************************************** * nifti_image_read ***************************************************************/ /*! \brief Read a nifti header and optionally the data, creating a nifti_image. - The data buffer will be byteswapped if necessary. - The data buffer will not be scaled. - The data buffer is allocated with calloc(). \param hname filename of the nifti dataset \param read_data Flag, true=read data blob, false=don't read blob. \return A pointer to the nifti_image data structure. \sa nifti_image_free, nifti_free_extensions, nifti_image_read_bricks */ nifti_image *nifti_image_read_NaN( const char *hname , int read_data , int rmNaN) { struct nifti_1_header nhdr ; nifti_image *nim ; znzFile fp ; int rv, ii , filesize, remaining; char fname[] = { "nifti_image_read_NaN" }; char *hfile=NULL; if( g_opts.debug > 1 ){ REprintf("-d image_read from '%s', read_data = %d",hname,read_data); #ifdef HAVE_LIBZ REprintf(", HAVE_LIBZ = 1\n"); #else REprintf(", HAVE_LIBZ = 0\n"); #endif } /**- determine filename to use for header */ hfile = nifti_findhdrname(hname); if( hfile == NULL ){ if(g_opts.debug > 0) LNI_FERR(fname,"failed to find header file for", hname); return NULL; /* check return */ } else if( g_opts.debug > 1 ) REprintf("-d %s: found header filename '%s'\n",fname,hfile); if( nifti_is_gzfile(hfile) ) filesize = -1; /* unknown */ else filesize = nifti_get_filesize(hfile); fp = znzopen(hfile, "rb", nifti_is_gzfile(hfile)); if( znz_isnull(fp) ){ if( g_opts.debug > 0 ) LNI_FERR(fname,"failed to open header file",hfile); free(hfile); return NULL; } rv = has_ascii_header( fp ); if( rv < 0 ){ if( g_opts.debug > 0 ) LNI_FERR(fname,"short header read",hfile); znzclose( fp ); free(hfile); return NULL; } else if ( rv == 1 ) /* process special file type */ return nifti_read_ascii_image( fp, hfile, filesize, read_data ); /* else, just process normally */ /**- read binary header */ ii = (int)znzread( &nhdr , 1 , sizeof(nhdr) , fp ) ; /* read the thing */ /* keep file open so we can check for exts. after nifti_convert_nhdr2nim() */ if( ii < (int) sizeof(nhdr) ){ if( g_opts.debug > 0 ){ LNI_FERR(fname,"bad binary header read for file", hfile); REprintf(" - read %d of %d bytes\n",ii, (int)sizeof(nhdr)); } znzclose(fp) ; free(hfile); return NULL; } /* create output image struct and set it up */ /**- convert all nhdr fields to nifti_image fields */ nim = nifti_convert_nhdr2nim(nhdr,hfile); if( nim == NULL ){ znzclose( fp ) ; /* close the file */ if( g_opts.debug > 0 ) LNI_FERR(fname,"cannot create nifti image from header",hfile); free(hfile); /* had to save this for debug message */ return NULL; } if( g_opts.debug > 3 ){ REprintf("+d nifti_image_read(), have nifti image:\n"); if( g_opts.debug > 2 ) nifti_image_infodump(nim); } /**- check for extensions (any errors here means no extensions) */ if( NIFTI_ONEFILE(nhdr) ) remaining = nim->iname_offset - sizeof(nhdr); else remaining = filesize - sizeof(nhdr); (void)nifti_read_extensions(nim, fp, remaining); znzclose( fp ) ; /* close the file */ free(hfile); /**- read the data if desired, then bug out */ if( read_data ){ if( nifti_image_load_NaN( nim , rmNaN) < 0 ){ nifti_image_free(nim); /* take ball, go home. */ return NULL; } } else nim->data = NULL ; return nim ; } /*************************************************************** * nifti_image_read ***************************************************************/ /*! \brief Read a nifti header and optionally the data, creating a nifti_image. - The data buffer will be byteswapped if necessary. - The data buffer will not be scaled. - The data buffer is allocated with calloc(). \param hname filename of the nifti dataset \param read_data Flag, true=read data blob, false=don't read blob. \return A pointer to the nifti_image data structure. \sa nifti_image_free, nifti_free_extensions, nifti_image_read_bricks */ nifti_image *nifti_image_read( const char *hname , int read_data) { return nifti_image_read_NaN( hname , read_data, 1); } /*---------------------------------------------------------------------- * has_ascii_header - see if the NIFTI header is an ASCII format * * If the file starts with the ASCII string " 1 ) REprintf("-d %s: have ASCII NIFTI file of size %d\n",fname,slen); if( slen > 65530 ) slen = 65530 ; sbuf = (char *)calloc(sizeof(char),slen+1) ; if( !sbuf ){ REprintf("** %s: failed to alloc %d bytes for sbuf",lfunc,65530); free(fname); znzclose(fp); return NULL; } znzread( sbuf , 1 , slen , fp ) ; nim = nifti_image_from_ascii( sbuf, &txt_size ) ; free( sbuf ) ; if( nim == NULL ){ LNI_FERR(lfunc,"failed nifti_image_from_ascii()",fname); free(fname); znzclose(fp); return NULL; } nim->nifti_type = NIFTI_FTYPE_ASCII ; /* compute remaining space for extensions */ remain = flen - txt_size - (int)nifti_get_volsize(nim); if( remain > 4 ){ /* read extensions (reposition file pointer, first) */ znzseek(fp, txt_size, SEEK_SET); (void) nifti_read_extensions(nim, fp, remain); } free(fname); znzclose( fp ) ; nim->iname_offset = -1 ; /* check from the end of the file */ if( read_data ) rv = nifti_image_load( nim ) ; else nim->data = NULL ; /* check for nifti_image_load() failure, maybe bail out */ if( read_data && rv != 0 ){ if( g_opts.debug > 1 ) REprintf("-d failed image_load, free nifti image struct\n"); free(nim); return NULL; } return nim ; } /*---------------------------------------------------------------------- * Read the extensions into the nifti_image struct 08 Dec 2004 [rickr] * * This function is called just after the header struct is read in, and * it is assumed the file pointer has not moved. The value in remain * is assumed to be accurate, reflecting the bytes of space for potential * extensions. * * return the number of extensions read in, or < 0 on error *----------------------------------------------------------------------*/ static int nifti_read_extensions( nifti_image *nim, znzFile fp, int remain ) { nifti1_extender extdr; /* defines extension existence */ nifti1_extension extn; /* single extension to process */ nifti1_extension * Elist; /* list of processed extensions */ int posn, count; if( !nim || znz_isnull(fp) ) { if( g_opts.debug > 0 ) REprintf("** nifti_read_extensions: bad inputs (%p,%p)\n", (void *)nim, (void *)fp); return -1; } posn = znztell(fp); if( (posn != sizeof(nifti_1_header)) && (nim->nifti_type != NIFTI_FTYPE_ASCII) ) REprintf("** WARNING: posn not header size (%d, %d)\n", posn, (int)sizeof(nifti_1_header)); if( g_opts.debug > 2 ) REprintf("-d nre: posn = %d, offset = %d, type = %d, remain = %d\n", posn, nim->iname_offset, nim->nifti_type, remain); if( remain < 16 ){ if( g_opts.debug > 2 ){ if( g_opts.skip_blank_ext ) REprintf("-d no extender in '%s' is okay, as " "skip_blank_ext is set\n",nim->fname); else REprintf("-d remain=%d, no space for extensions\n",remain); } return 0; } count = (int)znzread( extdr.extension, 1, 4, fp ); /* get extender */ if( count < 4 ){ if( g_opts.debug > 1 ) REprintf("-d file '%s' is too short for an extender\n", nim->fname); return 0; } if( extdr.extension[0] != 1 ){ if( g_opts.debug > 2 ) REprintf("-d extender[0] (%d) shows no extensions for '%s'\n", extdr.extension[0], nim->fname); return 0; } remain -= 4; if( g_opts.debug > 2 ) REprintf("-d found valid 4-byte extender, remain = %d\n", remain); /* so we expect extensions, but have no idea of how many there may be */ count = 0; Elist = NULL; while (nifti_read_next_extension(&extn, nim, remain, fp) > 0) { if( nifti_add_exten_to_list(&extn, &Elist, count+1) < 0 ){ if( g_opts.debug > 0 ) REprintf("** failed adding ext %d to list\n", count); return -1; } /* we have a new extension */ if( g_opts.debug > 1 ){ REprintf("+d found extension #%d, code = 0x%x, size = %d\n", count, extn.ecode, extn.esize); if( extn.ecode == NIFTI_ECODE_AFNI && g_opts.debug > 2 ) /* ~XML */ REprintf(" AFNI extension: %.*s\n", extn.esize-8,extn.edata); else if( extn.ecode == NIFTI_ECODE_COMMENT && g_opts.debug > 2 ) REprintf(" COMMENT extension: %.*s\n", /* TEXT */ extn.esize-8,extn.edata); } remain -= extn.esize; count++; } if( g_opts.debug > 2 ) REprintf("+d found %d extension(s)\n", count); nim->num_ext = count; nim->ext_list = Elist; return count; } /*----------------------------------------------------------------------*/ /*! nifti_add_extension - add an extension, with a copy of the data Add an extension to the nim->ext_list array. Fill this extension with a copy of the data, noting the length and extension code. \param nim - nifti_image to add extension to \param data - raw extension data \param length - length of raw extension data \param ecode - extension code \sa extension codes NIFTI_ECODE_* in nifti1_io.h \sa nifti_free_extensions, valid_nifti_extensions, nifti_copy_extensions \return 0 on success, -1 on error (and free the entire list) *//*--------------------------------------------------------------------*/ int nifti_add_extension(nifti_image *nim, const char * data, int len, int ecode) { nifti1_extension ext; /* error are printed in functions */ if( nifti_fill_extension(&ext, data, len, ecode) ) return -1; if( nifti_add_exten_to_list(&ext, &nim->ext_list, nim->num_ext+1)) return -1; nim->num_ext++; /* success, so increment */ return 0; } /*----------------------------------------------------------------------*/ /* nifti_add_exten_to_list - add a new nifti1_extension to the list We will append via "malloc, copy and free", because on an error, the list will revert to the previous one (sorry realloc(), only quality dolphins get to become part of St@rk!st brand tunafish). return 0 on success, -1 on error (and free the entire list) *//*--------------------------------------------------------------------*/ static int nifti_add_exten_to_list( nifti1_extension * new_ext, nifti1_extension ** list, int new_length ) { nifti1_extension * tmplist; tmplist = *list; *list = (nifti1_extension *)malloc(new_length * sizeof(nifti1_extension)); /* check for failure first */ if( ! *list ){ REprintf("** failed to alloc %d extension structs (%d bytes)\n", new_length, new_length*(int)sizeof(nifti1_extension)); if( !tmplist ) return -1; /* no old list to lose */ *list = tmplist; /* reset list to old one */ return -1; } /* if an old list exists, copy the pointers and free the list */ if( tmplist ){ memcpy(*list, tmplist, (new_length-1)*sizeof(nifti1_extension)); free(tmplist); } /* for some reason, I just don't like struct copy... */ (*list)[new_length-1].esize = new_ext->esize; (*list)[new_length-1].ecode = new_ext->ecode; (*list)[new_length-1].edata = new_ext->edata; if( g_opts.debug > 2 ) REprintf("+d allocated and appended extension #%d to list\n", new_length); return 0; } /*----------------------------------------------------------------------*/ /* nifti_fill_extension - given data and length, fill an extension struct Allocate memory for data, copy data, set the size and code. return 0 on success, -1 on error (and free the entire list) *//*--------------------------------------------------------------------*/ static int nifti_fill_extension( nifti1_extension *ext, const char * data, int len, int ecode) { int esize; if( !ext || !data || len < 0 ){ REprintf("** fill_ext: bad params (%p,%p,%d)\n", (void *)ext, data, len); return -1; } else if( ! nifti_is_valid_ecode(ecode) ){ REprintf("** fill_ext: invalid ecode %d\n", ecode); return -1; } /* compute esize, first : len+8, and take ceiling up to a mult of 16 */ esize = len+8; if( esize & 0xf ) esize = (esize + 0xf) & ~0xf; ext->esize = esize; /* allocate esize-8 (maybe more than len), using calloc for fill */ ext->edata = (char *)calloc(esize-8, sizeof(char)); if( !ext->edata ){ REprintf("** NFE: failed to alloc %d bytes for extension\n",len); return -1; } memcpy(ext->edata, data, len); /* copy the data, using len */ ext->ecode = ecode; /* set the ecode */ if( g_opts.debug > 2 ) REprintf("+d alloc %d bytes for ext len %d, ecode %d, esize %d\n", esize-8, len, ecode, esize); return 0; } /*---------------------------------------------------------------------- * nifti_read_next_extension - read a single extension from the file * * return (>= 0 is okay): * * success : esize * no extension : 0 * error : -1 *----------------------------------------------------------------------*/ static int nifti_read_next_extension( nifti1_extension * nex, nifti_image *nim, int remain, znzFile fp ) { int swap = nim->byteorder != nifti_short_order(); int count, size, code; /* first clear nex */ nex->esize = nex->ecode = 0; nex->edata = NULL; if( remain < 16 ){ if( g_opts.debug > 2 ) REprintf("-d only %d bytes remain, so no extension\n", remain); return 0; } /* must start with 4-byte size and code */ count = (int)znzread( &size, 4, 1, fp ); if( count == 1 ) count += (int)znzread( &code, 4, 1, fp ); if( count != 2 ){ if( g_opts.debug > 2 ) REprintf("-d current extension read failed\n"); znzseek(fp, -4*count, SEEK_CUR); /* back up past any read */ return 0; /* no extension, no error condition */ } if( swap ){ if( g_opts.debug > 2 ) REprintf("-d pre-swap exts: code %d, size %d\n", code, size); nifti_swap_4bytes(1, &size); nifti_swap_4bytes(1, &code); } if( g_opts.debug > 2 ) REprintf("-d potential extension: code %d, size %d\n", code, size); if( !nifti_check_extension(nim, size, code, remain) ){ if( znzseek(fp, -8, SEEK_CUR) < 0 ){ /* back up past any read */ REprintf("** failure to back out of extension read!\n"); return -1; } return 0; } /* now get the actual data */ nex->esize = size; nex->ecode = code; size -= 8; /* subtract space for size and code in extension */ nex->edata = (char *)malloc(size * sizeof(char)); if( !nex->edata ){ REprintf("** failed to allocate %d bytes for extension\n",size); return -1; } count = (int)znzread(nex->edata, 1, size, fp); if( count < size ){ if( g_opts.debug > 0 ) REprintf("-d read only %d (of %d) bytes for extension\n", count, size); free(nex->edata); nex->edata = NULL; return -1; } /* success! */ if( g_opts.debug > 2 ) REprintf("+d successfully read extension, code %d, size %d\n", nex->ecode, nex->esize); return nex->esize; } /*----------------------------------------------------------------------*/ /*! for each extension, check code, size and data pointer *//*--------------------------------------------------------------------*/ int valid_nifti_extensions(const nifti_image * nim) { nifti1_extension * ext; int c, errs; if( nim->num_ext <= 0 || nim->ext_list == NULL ){ if( g_opts.debug > 2 ) REprintf("-d empty extension list\n"); return 0; } /* for each extension, check code, size and data pointer */ ext = nim->ext_list; errs = 0; for ( c = 0; c < nim->num_ext; c++ ){ if( ! nifti_is_valid_ecode(ext->ecode) ) { if( g_opts.debug > 1 ) REprintf("-d ext %d, invalid code %d\n", c, ext->ecode); errs++; } if( ext->esize <= 0 ){ if( g_opts.debug > 1 ) REprintf("-d ext %d, bad size = %d\n", c, ext->esize); errs++; } else if( ext->esize & 0xf ){ if( g_opts.debug > 1 ) REprintf("-d ext %d, size %d not multiple of 16\n", c, ext->esize); errs++; } if( ext->edata == NULL ){ if( g_opts.debug > 1 ) REprintf("-d ext %d, missing data\n", c); errs++; } ext++; } if( errs > 0 ){ if( g_opts.debug > 0 ) REprintf("-d had %d extension errors, none will be written\n", errs); return 0; } /* if we're here, we're good */ return 1; } /*----------------------------------------------------------------------*/ /*! check whether the extension code is valid \return 1 if valid, 0 otherwise *//*--------------------------------------------------------------------*/ int nifti_is_valid_ecode( int ecode ) { if( ecode < NIFTI_ECODE_IGNORE || /* minimum code number (0) */ ecode > NIFTI_MAX_ECODE || /* maximum code number */ ecode & 1 ) /* cannot be odd */ return 0; return 1; } /*---------------------------------------------------------------------- * check for valid size and code, as well as can be done *----------------------------------------------------------------------*/ static int nifti_check_extension(nifti_image *nim, int size, int code, int rem) { /* check for bad code before bad size */ if( ! nifti_is_valid_ecode(code) ) { if( g_opts.debug > 2 ) REprintf("-d invalid extension code %d\n",code); return 0; } if( size < 16 ){ if( g_opts.debug > 2 ) REprintf("-d ext size %d, no extension\n",size); return 0; } if( size > rem ){ if( g_opts.debug > 2 ) REprintf("-d ext size %d, space %d, no extension\n", size, rem); return 0; } if( size & 0xf ){ if( g_opts.debug > 2 ) REprintf("-d nifti extension size %d not multiple of 16\n",size); return 0; } if( nim->nifti_type == NIFTI_FTYPE_ASCII && size > LNI_MAX_NIA_EXT_LEN ){ if( g_opts.debug > 2 ) REprintf("-d NVE, bad nifti_type 3 size %d\n", size); return 0; } return 1; } /*---------------------------------------------------------------------- * nifti_image_load_prep - prepare to read data * * Check nifti_image fields, open the file and seek to the appropriate * offset for reading. * * return NULL on failure *----------------------------------------------------------------------*/ static znzFile nifti_image_load_prep( nifti_image *nim ) { /* set up data space, open data file and seek, then call nifti_read_buffer */ size_t ntot , ii , ioff; znzFile fp; char *tmpimgname; char fname[] = { "nifti_image_load_prep" }; /**- perform sanity checks */ if( nim == NULL || nim->iname == NULL || nim->nbyper <= 0 || nim->nvox <= 0 ) { if ( g_opts.debug > 0 ){ if( !nim ) REprintf("** ERROR: N_image_load: no nifti image\n"); else REprintf("** ERROR: N_image_load: bad params (%p,%d,%u)\n", nim->iname, nim->nbyper, (unsigned)nim->nvox); } return NULL; } ntot = nifti_get_volsize(nim) ; /* total bytes to read */ /**- open image data file */ tmpimgname = nifti_findimgname(nim->iname , nim->nifti_type); if( tmpimgname == NULL ){ if( g_opts.debug > 0 ) REprintf("** no image file found for '%s'\n",nim->iname); return NULL; } fp = znzopen(tmpimgname, "rb", nifti_is_gzfile(tmpimgname)); if (znz_isnull(fp)){ if(g_opts.debug > 0) LNI_FERR(fname,"cannot open data file",tmpimgname); free(tmpimgname); return NULL; /* bad open? */ } free(tmpimgname); /**- get image offset: a negative offset means to figure from end of file */ if( nim->iname_offset < 0 ){ if( nifti_is_gzfile(nim->iname) ){ if( g_opts.debug > 0 ) LNI_FERR(fname,"negative offset for compressed file",nim->iname); znzclose(fp); return NULL; } ii = nifti_get_filesize( nim->iname ) ; if( ii <= 0 ){ if( g_opts.debug > 0 ) LNI_FERR(fname,"empty data file",nim->iname); znzclose(fp); return NULL; } ioff = (ii > ntot) ? ii-ntot : 0 ; } else { /* non-negative offset */ ioff = nim->iname_offset ; /* means use it directly */ } /**- seek to the appropriate read position */ if( znzseek(fp , (long)ioff , SEEK_SET) < 0 ){ REprintf("** could not seek to offset %u in file '%s'\n", (unsigned)ioff, nim->iname); znzclose(fp); return NULL; } /**- and return the File pointer */ return fp; } /*---------------------------------------------------------------------- * nifti_image_load *----------------------------------------------------------------------*/ /*! \fn int nifti_image_load( nifti_image *nim ) \brief Load the image blob into a previously initialized nifti_image. - If not yet set, the data buffer is allocated with calloc(). - The data buffer will be byteswapped if necessary. - The data buffer will not be scaled. This function is used to read the image from disk. It should be used after a function such as nifti_image_read(), so that the nifti_image structure is already initialized. \param nim pointer to a nifti_image (previously initialized) \return 0 on success, -1 on failure \sa nifti_image_read, nifti_image_free, nifti_image_unload */ int nifti_image_load_NaN( nifti_image *nim , int rmNaN) { /* set up data space, open data file and seek, then call nifti_read_buffer */ size_t ntot , ii ; znzFile fp ; /**- open the file and position the FILE pointer */ fp = nifti_image_load_prep( nim ); if( fp == NULL ){ if( g_opts.debug > 0 ) REprintf("** nifti_image_load, failed load_prep\n"); return -1; } ntot = nifti_get_volsize(nim); /**- if the data pointer is not yet set, get memory space for the image */ if( nim->data == NULL ) { nim->data = (void *)calloc(1,ntot) ; /* create image memory */ if( nim->data == NULL ){ if( g_opts.debug > 0 ) REprintf("** failed to alloc %d bytes for image data\n", (int)ntot); znzclose(fp); return -1; } } /**- now that everything is set up, do the reading */ ii = nifti_read_buffer_NaN(fp,nim->data,ntot,nim, rmNaN); if( ii < ntot ){ znzclose(fp) ; free(nim->data) ; nim->data = NULL ; return -1 ; /* errors were printed in nifti_read_buffer() */ } /**- close the file */ znzclose( fp ) ; return 0 ; } /*---------------------------------------------------------------------- * nifti_image_load *----------------------------------------------------------------------*/ /*! \fn int nifti_image_load( nifti_image *nim ) \brief Load the image blob into a previously initialized nifti_image. - If not yet set, the data buffer is allocated with calloc(). - The data buffer will be byteswapped if necessary. - The data buffer will not be scaled. This function is used to read the image from disk. It should be used after a function such as nifti_image_read(), so that the nifti_image structure is already initialized. \param nim pointer to a nifti_image (previously initialized) \return 0 on success, -1 on failure \sa nifti_image_read, nifti_image_free, nifti_image_unload */ int nifti_image_load( nifti_image *nim) { return nifti_image_load_NaN( nim , 1); } /*----------------------------------------------------------------------*/ /*! read ntot bytes of data from an open file and byte swaps if necessary note that nifti_image is required for information on datatype, bsize (for any needed byte swapping), etc. This function does not allocate memory, so dataptr must be valid. *//*--------------------------------------------------------------------*/ size_t nifti_read_buffer_NaN(znzFile fp, void* dataptr, size_t ntot, nifti_image *nim, int rmNaN) { size_t ii; if( dataptr == NULL ){ if( g_opts.debug > 0 ) REprintf("** ERROR: nifti_read_buffer: NULL dataptr\n"); return -1; } ii = znzread( dataptr , 1 , ntot , fp ) ; /* data input */ /* if read was short, fail */ if( ii < ntot ){ if( g_opts.debug > 0 ) REprintf("++ WARNING: nifti_read_buffer(%s):\n" " data bytes needed = %u\n" " data bytes input = %u\n" " number missing = %u (set to 0)\n", nim->iname , (unsigned int)ntot , (unsigned int)ii , (unsigned int)(ntot-ii) ) ; /* memset( (char *)(dataptr)+ii , 0 , ntot-ii ) ; now failure [rickr] */ return -1 ; } if( g_opts.debug > 2 ) REprintf("+d nifti_read_buffer: read %u bytes\n", (unsigned)ii); /* byte swap array if needed */ /* ntot/swapsize might not fit as int, use size_t 6 Jul 2010 [rickr] */ if( nim->swapsize > 1 && nim->byteorder != nifti_short_order() ) { if( g_opts.debug > 1 ) REprintf("+d nifti_read_buffer: swapping data bytes...\n"); nifti_swap_Nbytes( ntot / nim->swapsize, nim->swapsize , dataptr ) ; } #ifdef isfinite if(rmNaN) { /* check input float arrays for goodness, and fix bad floats */ int fix_count = 0 ; switch( nim->datatype ){ case NIFTI_TYPE_FLOAT32: case NIFTI_TYPE_COMPLEX64:{ register float *far = (float *)dataptr ; register size_t jj,nj ; nj = ntot / sizeof(float) ; for( jj=0 ; jj < nj ; jj++ ) /* count fixes 30 Nov 2004 [rickr] */ if( !IS_GOOD_FLOAT(far[jj]) ){ far[jj] = 0 ; fix_count++ ; } } break ; case NIFTI_TYPE_FLOAT64: case NIFTI_TYPE_COMPLEX128:{ register double *far = (double *)dataptr ; register size_t jj,nj ; nj = ntot / sizeof(double) ; for( jj=0 ; jj < nj ; jj++ ) /* count fixes 30 Nov 2004 [rickr] */ if( !IS_GOOD_FLOAT(far[jj]) ){ far[jj] = 0 ; fix_count++ ; } } break ; } if( g_opts.debug > 1 ) REprintf("+d in image, %d bad floats were set to 0\n", fix_count); } #endif return ii; } size_t nifti_read_buffer(znzFile fp, void* dataptr, size_t ntot, nifti_image *nim) { return nifti_read_buffer_NaN(fp, dataptr, ntot, nim, 1); // call new function with NaN flag support! } /*--------------------------------------------------------------------------*/ /*! Unload the data in a nifti_image struct, but keep the metadata. *//*------------------------------------------------------------------------*/ void nifti_image_unload( nifti_image *nim ) { if( nim != NULL && nim->data != NULL ){ free(nim->data) ; nim->data = NULL ; } return ; } /*--------------------------------------------------------------------------*/ /*! free 'everything' about a nifti_image struct (including the passed struct) free (only fields which are not NULL): - fname and iname - data - any ext_list[i].edata - ext_list - nim *//*------------------------------------------------------------------------*/ void nifti_image_free( nifti_image *nim ) { if( nim == NULL ) return ; if( nim->fname != NULL ) free(nim->fname) ; if( nim->iname != NULL ) free(nim->iname) ; if( nim->data != NULL ) free(nim->data ) ; (void)nifti_free_extensions( nim ) ; free(nim) ; return ; } /*--------------------------------------------------------------------------*/ /*! free the nifti extensions - If any edata pointer is set in the extension list, free() it. - Free ext_list, if it is set. - Clear num_ext and ext_list from nim. \return 0 on success, -1 on error \sa nifti_add_extension, nifti_copy_extensions *//*------------------------------------------------------------------------*/ int nifti_free_extensions( nifti_image *nim ) { int c ; if( nim == NULL ) return -1; if( nim->num_ext > 0 && nim->ext_list ){ for( c = 0; c < nim->num_ext; c++ ) if ( nim->ext_list[c].edata ) free(nim->ext_list[c].edata); free(nim->ext_list); } /* or if it is inconsistent, warn the user (if we are not in quiet mode) */ else if ( (nim->num_ext > 0 || nim->ext_list != NULL) && (g_opts.debug > 0) ) REprintf("** warning: nifti extension num/ptr mismatch (%d,%p)\n", nim->num_ext, (void *)nim->ext_list); if( g_opts.debug > 2 ) REprintf("+d free'd %d extension(s)\n", nim->num_ext); nim->num_ext = 0; nim->ext_list = NULL; return 0; } /*--------------------------------------------------------------------------*/ /*! Print to stdout some info about a nifti_image struct. *//*------------------------------------------------------------------------*/ void nifti_image_infodump( const nifti_image *nim ) { char *str = nifti_image_to_ascii( nim ) ; /* stdout -> stderr 2 Dec 2004 [rickr] */ if( str != NULL ){ REprintf(str); /*fputs(str,stderr)*/ ; free(str) ; } return ; } /*-------------------------------------------------------------------------- * nifti_write_buffer just check for a null znzFile and call znzwrite *--------------------------------------------------------------------------*/ /*! \fn size_t nifti_write_buffer(znzFile fp, void *buffer, size_t numbytes) \brief write numbytes of buffer to file, fp \param fp File pointer (from znzopen) to gzippable nifti datafile \param buffer data buffer to be written \param numbytes number of bytes in buffer to write \return number of bytes successfully written */ size_t nifti_write_buffer(znzFile fp, const void *buffer, size_t numbytes) { /* Write all the image data at once (no swapping here) */ size_t ss; if (znz_isnull(fp)){ REprintf("** ERROR: nifti_write_buffer: null file pointer\n"); return 0; } ss = znzwrite( (void*)buffer , 1 , numbytes , fp ) ; return ss; } /*----------------------------------------------------------------------*/ /*! write the nifti_image data to file (from nim->data or from NBL) If NBL is not NULL, write the data from that structure. Otherwise, write it out from nim->data. No swapping is done here. \param fp : File pointer \param nim : nifti_image corresponding to the data \param NBL : optional source of write data (if NULL use nim->data) \return 0 on success, -1 on failure Note: the nifti_image byte_order is set as that of the current CPU. This is because such a conversion was made to the data upon reading, while byte_order was not set (so the programs would know what format the data was on disk). Effectively, since byte_order should match what is on disk, it should bet set to that of the current CPU whenever new filenames are assigned. *//*--------------------------------------------------------------------*/ int nifti_write_all_data(znzFile fp, nifti_image * nim, const nifti_brick_list * NBL) { size_t ss; int bnum; if( !NBL ){ /* just write one buffer and get out of here */ if( nim->data == NULL ){ REprintf("** NWAD: no image data to write\n"); return -1; } ss = nifti_write_buffer(fp,nim->data,nim->nbyper * nim->nvox); if (ss < nim->nbyper * nim->nvox){ REprintf( "** ERROR: NWAD: wrote only %u of %u bytes to file\n", (unsigned)ss, (unsigned)(nim->nbyper * nim->nvox)); return -1; } if( g_opts.debug > 1 ) REprintf("+d wrote single image of %u bytes\n", (unsigned)ss); } else { if( ! NBL->bricks || NBL->nbricks <= 0 || NBL->bsize <= 0 ){ REprintf("** NWAD: no brick data to write (%p,%d,%u)\n", (void *)NBL->bricks, NBL->nbricks, (unsigned)NBL->bsize); return -1; } for( bnum = 0; bnum < NBL->nbricks; bnum++ ){ ss = nifti_write_buffer(fp, NBL->bricks[bnum], NBL->bsize); if( ss < NBL->bsize ){ REprintf( "** NWAD ERROR: wrote %u of %u bytes of brick %d of %d to file", (unsigned)ss, (unsigned)NBL->bsize, bnum+1, NBL->nbricks); return -1; } } if( g_opts.debug > 1 ) REprintf("+d wrote image of %d brick(s), each of %u bytes\n", NBL->nbricks, (unsigned int)NBL->bsize); } /* mark as being in this CPU byte order */ nim->byteorder = nifti_short_order() ; return 0; } /* return number of extensions written, or -1 on error */ static int nifti_write_extensions(znzFile fp, nifti_image *nim) { nifti1_extension * list; char extdr[4] = { 0, 0, 0, 0 }; int c, size, ok = 1; if( znz_isnull(fp) || !nim || nim->num_ext < 0 ){ if( g_opts.debug > 0 ) REprintf("** nifti_write_extensions, bad params\n"); return -1; } /* if no extensions and user requests it, skip extender */ if( g_opts.skip_blank_ext && (nim->num_ext == 0 || ! nim->ext_list ) ){ if( g_opts.debug > 1 ) REprintf("-d no exts and skip_blank_ext set, " "so skipping 4-byte extender\n"); return 0; } /* if invalid extension list, clear num_ext */ if( ! valid_nifti_extensions(nim) ) nim->num_ext = 0; /* write out extender block */ if( nim->num_ext > 0 ) extdr[0] = 1; if( nifti_write_buffer(fp, extdr, 4) != 4 ){ REprintf("** failed to write extender\n"); return -1; } list = nim->ext_list; for ( c = 0; c < nim->num_ext; c++ ){ size = (int)nifti_write_buffer(fp, &list->esize, sizeof(int)); ok = (size == (int)sizeof(int)); if( ok ){ size = (int)nifti_write_buffer(fp, &list->ecode, sizeof(int)); ok = (size == (int)sizeof(int)); } if( ok ){ size = (int)nifti_write_buffer(fp, list->edata, list->esize - 8); ok = (size == list->esize - 8); } if( !ok ){ REprintf("** failed while writing extension #%d\n",c); return -1; } else if ( g_opts.debug > 2 ) REprintf("+d wrote extension %d of %d bytes\n", c, size); list++; } if( g_opts.debug > 1 ) REprintf("+d wrote out %d extension(s)\n", nim->num_ext); return nim->num_ext; } /*----------------------------------------------------------------------*/ /*! basic initialization of a nifti_image struct (to a 1x1x1 image) *//*--------------------------------------------------------------------*/ nifti_image* nifti_simple_init_nim(void) { nifti_image *nim; struct nifti_1_header nhdr; int nbyper, swapsize; memset(&nhdr,0,sizeof(nhdr)) ; /* zero out header, to be safe */ nhdr.sizeof_hdr = sizeof(nhdr) ; nhdr.regular = 'r' ; /* for some stupid reason */ nhdr.dim[0] = 3 ; nhdr.dim[1] = 1 ; nhdr.dim[2] = 1 ; nhdr.dim[3] = 1 ; nhdr.dim[4] = 0 ; nhdr.pixdim[0] = 0.0 ; nhdr.pixdim[1] = 1.0 ; nhdr.pixdim[2] = 1.0 ; nhdr.pixdim[3] = 1.0 ; nhdr.datatype = DT_FLOAT32 ; nifti_datatype_sizes( nhdr.datatype , &nbyper, &swapsize ); nhdr.bitpix = 8 * nbyper ; strcpy(nhdr.magic, "n+1"); /* init to single file */ nim = nifti_convert_nhdr2nim(nhdr,NULL); nim->fname = NULL; nim->iname = NULL; return nim; } /*----------------------------------------------------------------------*/ /*! basic initialization of a nifti_1_header struct (with given dimensions) Return an allocated nifti_1_header struct, based on the given dimensions and datatype. \param arg_dims : optional dim[8] array (default {3,1,1,1,0,0,0,0}) \param arg_dtype : optional datatype (default DT_FLOAT32) \return pointer to allocated nifti_1_header struct *//*--------------------------------------------------------------------*/ nifti_1_header * nifti_make_new_header(const int arg_dims[], int arg_dtype) { nifti_1_header * nhdr; const int default_dims[8] = { 3, 1, 1, 1, 0, 0, 0, 0 }; const int * dim; /* either passed or default dims */ int dtype; /* either passed or default dtype */ int c, nbyper, swapsize; /* if arg_dims is passed, apply it */ if( arg_dims ) dim = arg_dims; else dim = default_dims; /* validate dim: if there is any problem, apply default_dims */ if( dim[0] < 1 || dim[0] > 7 ) { REprintf("** nifti_simple_hdr_with_dims: bad dim[0]=%d\n",dim[0]); dim = default_dims; } else { for( c = 1; c <= dim[0]; c++ ) if( dim[c] < 1 ) { REprintf( "** nifti_simple_hdr_with_dims: bad dim[%d]=%d\n",c,dim[c]); dim = default_dims; break; } } /* validate dtype, too */ dtype = arg_dtype; if( ! nifti_is_valid_datatype(dtype) ) { REprintf("** nifti_simple_hdr_with_dims: bad dtype %d\n",dtype); dtype = DT_FLOAT32; } /* now populate the header struct */ if( g_opts.debug > 1 ) REprintf("+d nifti_make_new_header, dim[0] = %d, datatype = %d\n", dim[0], dtype); nhdr = (nifti_1_header *)calloc(1,sizeof(nifti_1_header)); if( !nhdr ){ REprintf("** nifti_make_new_header: failed to alloc hdr\n"); return NULL; } nhdr->sizeof_hdr = sizeof(nifti_1_header) ; nhdr->regular = 'r' ; /* for some stupid reason */ /* init dim and pixdim */ nhdr->dim[0] = dim[0] ; nhdr->pixdim[0] = 0.0; for( c = 1; c <= dim[0]; c++ ) { nhdr->dim[c] = dim[c]; nhdr->pixdim[c] = 1.0; } nhdr->datatype = dtype ; nifti_datatype_sizes( nhdr->datatype , &nbyper, &swapsize ); nhdr->bitpix = 8 * nbyper ; strcpy(nhdr->magic, "n+1"); /* init to single file */ return nhdr; } /*----------------------------------------------------------------------*/ /*! basic creation of a nifti_image struct Create a nifti_image from the given dimensions and data type. Optinally, allocate zero-filled data. \param dims : optional dim[8] (default {3,1,1,1,0,0,0,0}) \param datatype : optional datatype (default DT_FLOAT32) \param data_fill : if flag is set, allocate zero-filled data for image \return pointer to allocated nifti_image struct *//*--------------------------------------------------------------------*/ nifti_image * nifti_make_new_nim(const int dims[], int datatype, int data_fill) { nifti_image * nim; nifti_1_header * nhdr; nhdr = nifti_make_new_header(dims, datatype); if( !nhdr ) return NULL; /* error already printed */ nim = nifti_convert_nhdr2nim(*nhdr,NULL); free(nhdr); /* in any case, we are done with this */ if( !nim ){ REprintf("** NMNN: nifti_convert_nhdr2nim failure\n"); return NULL; } if( g_opts.debug > 1 ) REprintf("+d nifti_make_new_nim, data_fill = %d\n",data_fill); if( data_fill ) { nim->data = calloc(nim->nvox, nim->nbyper); /* if we cannot allocate data, take ball and go home */ if( !nim->data ) { REprintf("** NMNN: failed to alloc %u bytes for data\n", (unsigned)(nim->nvox*nim->nbyper)); nifti_image_free(nim); nim = NULL; } } return nim; } /*----------------------------------------------------------------------*/ /*! convert a nifti_image structure to a nifti_1_header struct No allocation is done, this should be used via structure copy. As in:
    nifti_1_header my_header;
    my_header = nifti_convert_nim2nhdr(my_nim_pointer);
    
*//*--------------------------------------------------------------------*/ struct nifti_1_header nifti_convert_nim2nhdr(const nifti_image * nim) { struct nifti_1_header nhdr; memset(&nhdr,0,sizeof(nhdr)) ; /* zero out header, to be safe */ /**- load the ANALYZE-7.5 generic parts of the header struct */ nhdr.sizeof_hdr = sizeof(nhdr) ; nhdr.regular = 'r' ; /* for some stupid reason */ nhdr.dim[0] = nim->ndim ; nhdr.dim[1] = nim->nx ; nhdr.dim[2] = nim->ny ; nhdr.dim[3] = nim->nz ; nhdr.dim[4] = nim->nt ; nhdr.dim[5] = nim->nu ; nhdr.dim[6] = nim->nv ; nhdr.dim[7] = nim->nw ; nhdr.pixdim[0] = 0.0 ; nhdr.pixdim[1] = nim->dx ; nhdr.pixdim[2] = nim->dy ; nhdr.pixdim[3] = nim->dz ; nhdr.pixdim[4] = nim->dt ; nhdr.pixdim[5] = nim->du ; nhdr.pixdim[6] = nim->dv ; nhdr.pixdim[7] = nim->dw ; nhdr.datatype = nim->datatype ; nhdr.bitpix = 8 * nim->nbyper ; if( nim->cal_max > nim->cal_min ){ nhdr.cal_max = nim->cal_max ; nhdr.cal_min = nim->cal_min ; } if( nim->scl_slope != 0.0 ){ nhdr.scl_slope = nim->scl_slope ; nhdr.scl_inter = nim->scl_inter ; } if( nim->descrip[0] != '\0' ){ memcpy(nhdr.descrip ,nim->descrip ,79) ; nhdr.descrip[79] = '\0' ; } if( nim->aux_file[0] != '\0' ){ memcpy(nhdr.aux_file ,nim->aux_file ,23) ; nhdr.aux_file[23] = '\0' ; } /**- Load NIFTI specific stuff into the header */ if( nim->nifti_type > NIFTI_FTYPE_ANALYZE ){ /* then not ANALYZE */ if( nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ) strcpy(nhdr.magic,"n+1") ; else strcpy(nhdr.magic,"ni1") ; nhdr.pixdim[1] = fabs(nhdr.pixdim[1]) ; nhdr.pixdim[2] = fabs(nhdr.pixdim[2]) ; nhdr.pixdim[3] = fabs(nhdr.pixdim[3]) ; nhdr.pixdim[4] = fabs(nhdr.pixdim[4]) ; nhdr.pixdim[5] = fabs(nhdr.pixdim[5]) ; nhdr.pixdim[6] = fabs(nhdr.pixdim[6]) ; nhdr.pixdim[7] = fabs(nhdr.pixdim[7]) ; nhdr.intent_code = nim->intent_code ; nhdr.intent_p1 = nim->intent_p1 ; nhdr.intent_p2 = nim->intent_p2 ; nhdr.intent_p3 = nim->intent_p3 ; if( nim->intent_name[0] != '\0' ){ memcpy(nhdr.intent_name,nim->intent_name,15) ; nhdr.intent_name[15] = '\0' ; } nhdr.vox_offset = (float) nim->iname_offset ; nhdr.xyzt_units = SPACE_TIME_TO_XYZT( nim->xyz_units, nim->time_units ) ; nhdr.toffset = nim->toffset ; if( nim->qform_code > 0 ){ nhdr.qform_code = nim->qform_code ; nhdr.quatern_b = nim->quatern_b ; nhdr.quatern_c = nim->quatern_c ; nhdr.quatern_d = nim->quatern_d ; nhdr.qoffset_x = nim->qoffset_x ; nhdr.qoffset_y = nim->qoffset_y ; nhdr.qoffset_z = nim->qoffset_z ; nhdr.pixdim[0] = (nim->qfac >= 0.0) ? 1.0 : -1.0 ; } if( nim->sform_code > 0 ){ nhdr.sform_code = nim->sform_code ; nhdr.srow_x[0] = nim->sto_xyz.m[0][0] ; nhdr.srow_x[1] = nim->sto_xyz.m[0][1] ; nhdr.srow_x[2] = nim->sto_xyz.m[0][2] ; nhdr.srow_x[3] = nim->sto_xyz.m[0][3] ; nhdr.srow_y[0] = nim->sto_xyz.m[1][0] ; nhdr.srow_y[1] = nim->sto_xyz.m[1][1] ; nhdr.srow_y[2] = nim->sto_xyz.m[1][2] ; nhdr.srow_y[3] = nim->sto_xyz.m[1][3] ; nhdr.srow_z[0] = nim->sto_xyz.m[2][0] ; nhdr.srow_z[1] = nim->sto_xyz.m[2][1] ; nhdr.srow_z[2] = nim->sto_xyz.m[2][2] ; nhdr.srow_z[3] = nim->sto_xyz.m[2][3] ; } nhdr.dim_info = FPS_INTO_DIM_INFO( nim->freq_dim , nim->phase_dim , nim->slice_dim ) ; nhdr.slice_code = nim->slice_code ; nhdr.slice_start = nim->slice_start ; nhdr.slice_end = nim->slice_end ; nhdr.slice_duration = nim->slice_duration ; } return nhdr; } /*----------------------------------------------------------------------*/ /*! \fn int nifti_copy_extensions(nifti_image * nim_dest, nifti_image * nim_src) \brief copy the nifti1_extension list from src to dest Duplicate the list of nifti1_extensions. The dest structure must be clear of extensions. \return 0 on success, -1 on failure \sa nifti_add_extension, nifti_free_extensions */ int nifti_copy_extensions(nifti_image * nim_dest, const nifti_image * nim_src) { char * data; size_t bytes; int c, size, old_size; if( nim_dest->num_ext > 0 || nim_dest->ext_list != NULL ){ REprintf("** will not copy extensions over existing ones\n"); return -1; } if( g_opts.debug > 1 ) REprintf("+d duplicating %d extension(s)\n", nim_src->num_ext); if( nim_src->num_ext <= 0 ) return 0; bytes = nim_src->num_ext * sizeof(nifti1_extension); /* I'm lazy */ nim_dest->ext_list = (nifti1_extension *)malloc(bytes); if( !nim_dest->ext_list ){ REprintf("** failed to allocate %d nifti1_extension structs\n", nim_src->num_ext); return -1; } /* copy the extension data */ nim_dest->num_ext = 0; for( c = 0; c < nim_src->num_ext; c++ ){ size = old_size = nim_src->ext_list[c].esize; if( size & 0xf ) size = (size + 0xf) & ~0xf; /* make multiple of 16 */ if( g_opts.debug > 2 ) REprintf("+d dup'ing ext #%d of size %d (from size %d)\n", c, size, old_size); /* data length is size-8, as esize includes space for esize and ecode */ data = (char *)calloc(size-8,sizeof(char)); /* maybe size > old */ if( !data ){ REprintf("** failed to alloc %d bytes for extention\n", size); if( c == 0 ) { free(nim_dest->ext_list); nim_dest->ext_list = NULL; } /* otherwise, keep what we have (a.o.t. deleting them all) */ return -1; } /* finally, fill the new structure */ nim_dest->ext_list[c].esize = size; nim_dest->ext_list[c].ecode = nim_src->ext_list[c].ecode; nim_dest->ext_list[c].edata = data; memcpy(data, nim_src->ext_list[c].edata, old_size-8); nim_dest->num_ext++; } return 0; } /*----------------------------------------------------------------------*/ /*! compute the total size of all extensions \return the total of all esize fields Note that each esize includes 4 bytes for ecode, 4 bytes for esize, and the bytes used for the data. Each esize also needs to be a multiple of 16, so it may be greater than the sum of its 3 parts. *//*--------------------------------------------------------------------*/ int nifti_extension_size(nifti_image *nim) { int c, size = 0; if( !nim || nim->num_ext <= 0 ) return 0; if( g_opts.debug > 2 ) REprintf("-d ext sizes:"); for ( c = 0; c < nim->num_ext; c++ ){ size += nim->ext_list[c].esize; if( g_opts.debug > 2 ) REprintf(" %d",nim->ext_list[c].esize); } if( g_opts.debug > 2 ) REprintf(" (total = %d)\n",size); return size; } /*----------------------------------------------------------------------*/ /*! set the nifti_image iname_offset field, based on nifti_type - if writing to 2 files, set offset to 0 - if writing to a single NIFTI-1 file, set the offset to 352 + total extension size, then align to 16-byte boundary - if writing an ASCII header, set offset to -1 *//*--------------------------------------------------------------------*/ void nifti_set_iname_offset(nifti_image *nim) { int offset; switch( nim->nifti_type ){ default: /* writing into 2 files */ /* we only write files with 0 offset in the 2 file format */ nim->iname_offset = 0 ; break ; /* NIFTI-1 single binary file - always update */ case NIFTI_FTYPE_NIFTI1_1: offset = nifti_extension_size(nim)+sizeof(struct nifti_1_header)+4; /* be sure offset is aligned to a 16 byte boundary */ if ( ( offset % 16 ) != 0 ) offset = ((offset + 0xf) & ~0xf); if( nim->iname_offset != offset ){ if( g_opts.debug > 1 ) REprintf("+d changing offset from %d to %d\n", nim->iname_offset, offset); nim->iname_offset = offset; } break ; /* non-standard case: NIFTI-1 ASCII header + binary data (single file) */ case NIFTI_FTYPE_ASCII: nim->iname_offset = -1 ; /* compute offset from filesize */ break ; } } /*----------------------------------------------------------------------*/ /*! write the nifti_image dataset to disk, optionally including data This is just a front-end for nifti_image_write_hdr_img2. \param nim nifti_image to write to disk \param write_data write options (see nifti_image_write_hdr_img2) \param opts file open options ("wb" from nifti_image_write) \sa nifti_image_write, nifti_image_write_hdr_img2, nifti_image_free, nifti_set_filenames *//*--------------------------------------------------------------------*/ znzFile nifti_image_write_hdr_img( nifti_image *nim , int write_data , const char* opts ) { return nifti_image_write_hdr_img2(nim,write_data,opts,NULL,NULL); } #undef ERREX #define ERREX(msg) \ do{ REprintf("** ERROR: nifti_image_write_hdr_img: %s\n",(msg)) ; \ return fp ; } while(0) /* ----------------------------------------------------------------------*/ /*! This writes the header (and optionally the image data) to file * * If the image data file is left open it returns a valid znzFile handle. * It also uses imgfile as the open image file is not null, and modifies * it inside. * * \param nim nifti_image to write to disk * \param write_opts flags whether to write data and/or close file (see below) * \param opts file-open options, probably "wb" from nifti_image_write() * \param imgfile optional open znzFile struct, for writing image data (may be NULL) * \param NBL optional nifti_brick_list, containing the image data (may be NULL) * * Values for write_opts mode are based on two binary flags * ( 0/1 for no-write/write data, and 0/2 for close/leave-open files ) : * - 0 = do not write data and close (do not open data file) * - 1 = write data and close * - 2 = do not write data and leave data file open * - 3 = write data and leave data file open * * \sa nifti_image_write, nifti_image_write_hdr_img, nifti_image_free, * nifti_set_filenames *//*---------------------------------------------------------------------*/ znzFile nifti_image_write_hdr_img2(nifti_image *nim, int write_opts, const char * opts, znzFile imgfile, const nifti_brick_list * NBL) { struct nifti_1_header nhdr ; znzFile fp=NULL; size_t ss ; int write_data, leave_open; char func[] = { "nifti_image_write_hdr_img2" }; write_data = write_opts & 1; /* just separate the bits now */ leave_open = write_opts & 2; if( ! nim ) ERREX("NULL input") ; if( ! nifti_validfilename(nim->fname) ) ERREX("bad fname input") ; if( write_data && ! nim->data && ! NBL ) ERREX("no image data") ; if( write_data && NBL && ! nifti_NBL_matches_nim(nim, NBL) ) ERREX("NBL does not match nim"); nifti_set_iname_offset(nim); if( g_opts.debug > 1 ){ REprintf("-d writing nifti file '%s'...\n", nim->fname); if( g_opts.debug > 2 ) REprintf("-d nifti type %d, offset %d\n", nim->nifti_type, nim->iname_offset); } if( nim->nifti_type == NIFTI_FTYPE_ASCII ) /* non-standard case */ return nifti_write_ascii_image(nim,NBL,opts,write_data,leave_open); nhdr = nifti_convert_nim2nhdr(nim); /* create the nifti1_header struct */ /* if writing to 2 files, make sure iname is set and different from fname */ if( nim->nifti_type != NIFTI_FTYPE_NIFTI1_1 ){ if( nim->iname && strcmp(nim->iname,nim->fname) == 0 ){ free(nim->iname) ; nim->iname = NULL ; } if( nim->iname == NULL ){ /* then make a new one */ nim->iname = nifti_makeimgname(nim->fname,nim->nifti_type,0,0); if( nim->iname == NULL ) return NULL; } } /* if we have an imgfile and will write the header there, use it */ if( ! znz_isnull(imgfile) && nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ){ if( g_opts.debug > 2 ) REprintf("+d using passed file for hdr\n"); fp = imgfile; } else { if( g_opts.debug > 2 ) REprintf("+d opening output file %s [%s]\n",nim->fname,opts); fp = znzopen( nim->fname , opts , nifti_is_gzfile(nim->fname) ) ; if( znz_isnull(fp) ){ LNI_FERR(func,"cannot open output file",nim->fname); return fp; } } /* write the header and extensions */ ss = znzwrite(&nhdr , 1 , sizeof(nhdr) , fp); /* write header */ if( ss < sizeof(nhdr) ){ LNI_FERR(func,"bad header write to output file",nim->fname); znzclose(fp); return fp; } /* partial file exists, and errors have been printed, so ignore return */ if( nim->nifti_type != NIFTI_FTYPE_ANALYZE ) (void)nifti_write_extensions(fp,nim); /* if the header is all we want, we are done */ if( ! write_data && ! leave_open ){ if( g_opts.debug > 2 ) REprintf("-d header is all we want: done\n"); znzclose(fp); return(fp); } if( nim->nifti_type != NIFTI_FTYPE_NIFTI1_1 ){ /* get a new file pointer */ znzclose(fp); /* first, close header file */ if( ! znz_isnull(imgfile) ){ if(g_opts.debug > 2) REprintf("+d using passed file for img\n"); fp = imgfile; } else { if( g_opts.debug > 2 ) REprintf("+d opening img file '%s'\n", nim->iname); fp = znzopen( nim->iname , opts , nifti_is_gzfile(nim->iname) ) ; if( znz_isnull(fp) ) ERREX("cannot open image file") ; } } znzseek(fp, nim->iname_offset, SEEK_SET); /* in any case, seek to offset */ if( write_data ) nifti_write_all_data(fp,nim,NBL); if( ! leave_open ) znzclose(fp); return fp; } /*----------------------------------------------------------------------*/ /*! write a nifti_image to disk in ASCII format *//*--------------------------------------------------------------------*/ znzFile nifti_write_ascii_image(nifti_image *nim, const nifti_brick_list * NBL, const char *opts, int write_data, int leave_open) { znzFile fp; char * hstr; hstr = nifti_image_to_ascii( nim ) ; /* get header in ASCII form */ if( ! hstr ){ REprintf("** failed image_to_ascii()\n"); return NULL; } fp = znzopen( nim->fname , opts , nifti_is_gzfile(nim->fname) ) ; if( znz_isnull(fp) ){ free(hstr); REprintf("** failed to open '%s' for ascii write\n",nim->fname); return fp; } znzputs(hstr,fp); /* header */ nifti_write_extensions(fp,nim); /* extensions */ if ( write_data ) { nifti_write_all_data(fp,nim,NBL); } /* data */ if ( ! leave_open ) { znzclose(fp); } free(hstr); return fp; /* returned but may be closed */ } /*--------------------------------------------------------------------------*/ /*! Write a nifti_image to disk. Since data is properly byte-swapped upon reading, it is assumed to be in the byte-order of the current CPU at write time. Thus, nim->byte_order should match that of the current CPU. Note that the nifti_set_filenames() function takes the flag, set_byte_order. The following fields of nim affect how the output appears: - nifti_type = 0 ==> ANALYZE-7.5 format file pair will be written - nifti_type = 1 ==> NIFTI-1 format single file will be written (data offset will be 352+extensions) - nifti_type = 2 ==> NIFTI_1 format file pair will be written - nifti_type = 3 ==> NIFTI_1 ASCII single file will be written - fname is the name of the output file (header or header+data) - if a file pair is being written, iname is the name of the data file - existing files WILL be overwritten with extreme prejudice - if qform_code > 0, the quatern_*, qoffset_*, and qfac fields determine the qform output, NOT the qto_xyz matrix; if you want to compute these fields from the qto_xyz matrix, you can use the utility function nifti_mat44_to_quatern() \sa nifti_image_write_bricks, nifti_image_free, nifti_set_filenames, nifti_image_write_hdr_img *//*------------------------------------------------------------------------*/ void nifti_image_write( nifti_image *nim ) { znzFile fp = nifti_image_write_hdr_img(nim,1,"wb"); if( fp ){ if( g_opts.debug > 2 ) REprintf("-d niw: done with znzFile\n"); free(fp); } if( g_opts.debug > 1 ) REprintf("-d nifti_image_write: done\n"); } /*----------------------------------------------------------------------*/ /*! similar to nifti_image_write, but data is in NBL struct, not nim->data \sa nifti_image_write, nifti_image_free, nifti_set_filenames, nifti_free_NBL *//*--------------------------------------------------------------------*/ void nifti_image_write_bricks( nifti_image *nim, const nifti_brick_list * NBL ) { znzFile fp = nifti_image_write_hdr_img2(nim,1,"wb",NULL,NBL); if( fp ){ if( g_opts.debug > 2 ) REprintf("-d niwb: done with znzFile\n"); free(fp); } if( g_opts.debug > 1 ) REprintf("-d niwb: done writing bricks\n"); } /*----------------------------------------------------------------------*/ /*! copy the nifti_image structure, without data Duplicate the structure, including fname, iname and extensions. Leave the data pointer as NULL. *//*--------------------------------------------------------------------*/ nifti_image * nifti_copy_nim_info(const nifti_image * src) { nifti_image *dest; dest = (nifti_image *)calloc(1,sizeof(nifti_image)); if( !dest ){ REprintf("** NCNI: failed to alloc nifti_image\n"); return NULL; } memcpy(dest, src, sizeof(nifti_image)); if( src->fname ) dest->fname = nifti_strdup(src->fname); if( src->iname ) dest->iname = nifti_strdup(src->iname); dest->num_ext = 0; dest->ext_list = NULL; /* errors will be printed in NCE(), continue in either case */ (void)nifti_copy_extensions(dest, src); dest->data = NULL; return dest; } /*------------------------------------------------------------------------*/ /* Un-escape a C string in place -- that is, convert XML escape sequences back into their characters. (This can be done in place since the replacement is always smaller than the input.) Escapes recognized are: - < -> < - > -> > - " -> " - ' -> ' - & -> & Also replace CR LF pair (Microsoft), or CR alone (Macintosh) with LF (Unix), per the XML standard. Return value is number of replacements made (if you care). --------------------------------------------------------------------------*/ #undef CR #undef LF #define CR 0x0D #define LF 0x0A static int unescape_string( char *str ) { int ii,jj , nn,ll ; if( str == NULL ) return 0 ; /* no string? */ ll = (int)strlen(str) ; if( ll == 0 ) return 0 ; /* scan for escapes: &something; */ for( ii=jj=nn=0 ; ii': lout += 4 ; break ; /* replace '<' with "<" */ case '"' : case '\'': lout += 6 ; break ; /* replace '"' with """ */ case CR: case LF: lout += 6 ; break ; /* replace CR with " " LF with " " */ default: lout++ ; break ; /* copy all other chars */ } } out = (char *)calloc(1,lout) ; /* allocate output string */ if( !out ){ REprintf("** escapize_string: failed to alloc %d bytes\n",lout); return NULL; } out[0] = '\'' ; /* opening quote mark */ for( ii=0,jj=1 ; ii < lstr ; ii++ ){ switch( str[ii] ){ default: out[jj++] = str[ii] ; break ; /* normal characters */ case '&': memcpy(out+jj,"&",5) ; jj+=5 ; break ; case '<': memcpy(out+jj,"<",4) ; jj+=4 ; break ; case '>': memcpy(out+jj,">",4) ; jj+=4 ; break ; case '"' : memcpy(out+jj,""",6) ; jj+=6 ; break ; case '\'': memcpy(out+jj,"'",6) ; jj+=6 ; break ; case CR: memcpy(out+jj," ",6) ; jj+=6 ; break ; case LF: memcpy(out+jj," ",6) ; jj+=6 ; break ; } } out[jj++] = '\'' ; /* closing quote mark */ out[jj] = '\0' ; /* terminate the string */ return out ; } /*---------------------------------------------------------------------------*/ /*! Dump the information in a NIFTI image header to an XML-ish ASCII string that can later be converted back into a NIFTI header in nifti_image_from_ascii(). The resulting string can be free()-ed when you are done with it. *//*-------------------------------------------------------------------------*/ char *nifti_image_to_ascii( const nifti_image *nim ) { char *buf , *ebuf ; int nbuf ; if( nim == NULL ) return NULL ; /* stupid caller */ buf = (char *)calloc(1,65534); nbuf = 0; /* longer than needed, to be safe */ if( !buf ){ REprintf("** NITA: failed to alloc %d bytes\n",65534); return NULL; } sprintf( buf , "nifti_type == NIFTI_FTYPE_NIFTI1_1) ? "NIFTI-1+" :(nim->nifti_type == NIFTI_FTYPE_NIFTI1_2) ? "NIFTI-1" :(nim->nifti_type == NIFTI_FTYPE_ASCII ) ? "NIFTI-1A" : "ANALYZE-7.5" ) ; /** Strings that we don't control (filenames, etc.) that might contain "weird" characters (like quotes) are "escaped": - A few special characters are replaced by XML-style escapes, using the function escapize_string(). - On input, function unescape_string() reverses this process. - The result is that the NIFTI ASCII-format header is XML-compliant. */ ebuf = escapize_string(nim->fname) ; sprintf( buf+strlen(buf) , " header_filename = %s\n",ebuf); free(ebuf); ebuf = escapize_string(nim->iname) ; sprintf( buf+strlen(buf) , " image_filename = %s\n", ebuf); free(ebuf); sprintf( buf+strlen(buf) , " image_offset = '%d'\n" , nim->iname_offset ); sprintf( buf+strlen(buf), " ndim = '%d'\n", nim->ndim); sprintf( buf+strlen(buf), " nx = '%d'\n", nim->nx ); if( nim->ndim > 1 ) sprintf( buf+strlen(buf), " ny = '%d'\n", nim->ny ); if( nim->ndim > 2 ) sprintf( buf+strlen(buf), " nz = '%d'\n", nim->nz ); if( nim->ndim > 3 ) sprintf( buf+strlen(buf), " nt = '%d'\n", nim->nt ); if( nim->ndim > 4 ) sprintf( buf+strlen(buf), " nu = '%d'\n", nim->nu ); if( nim->ndim > 5 ) sprintf( buf+strlen(buf), " nv = '%d'\n", nim->nv ); if( nim->ndim > 6 ) sprintf( buf+strlen(buf), " nw = '%d'\n", nim->nw ); sprintf( buf+strlen(buf), " dx = '%g'\n", nim->dx ); if( nim->ndim > 1 ) sprintf( buf+strlen(buf), " dy = '%g'\n", nim->dy ); if( nim->ndim > 2 ) sprintf( buf+strlen(buf), " dz = '%g'\n", nim->dz ); if( nim->ndim > 3 ) sprintf( buf+strlen(buf), " dt = '%g'\n", nim->dt ); if( nim->ndim > 4 ) sprintf( buf+strlen(buf), " du = '%g'\n", nim->du ); if( nim->ndim > 5 ) sprintf( buf+strlen(buf), " dv = '%g'\n", nim->dv ); if( nim->ndim > 6 ) sprintf( buf+strlen(buf), " dw = '%g'\n", nim->dw ); sprintf( buf+strlen(buf) , " datatype = '%d'\n" , nim->datatype ) ; sprintf( buf+strlen(buf) , " datatype_name = '%s'\n" , nifti_datatype_string(nim->datatype) ) ; sprintf( buf+strlen(buf) , " nvox = '%u'\n" , (unsigned)nim->nvox ) ; sprintf( buf+strlen(buf) , " nbyper = '%d'\n" , nim->nbyper ) ; sprintf( buf+strlen(buf) , " byteorder = '%s'\n" , (nim->byteorder==MSB_FIRST) ? "MSB_FIRST" : "LSB_FIRST" ) ; if( nim->cal_min < nim->cal_max ){ sprintf( buf+strlen(buf) , " cal_min = '%g'\n", nim->cal_min ) ; sprintf( buf+strlen(buf) , " cal_max = '%g'\n", nim->cal_max ) ; } if( nim->scl_slope != 0.0 ){ sprintf( buf+strlen(buf) , " scl_slope = '%g'\n" , nim->scl_slope ) ; sprintf( buf+strlen(buf) , " scl_inter = '%g'\n" , nim->scl_inter ) ; } if( nim->intent_code > 0 ){ sprintf( buf+strlen(buf) , " intent_code = '%d'\n", nim->intent_code ) ; sprintf( buf+strlen(buf) , " intent_code_name = '%s'\n" , nifti_intent_string(nim->intent_code) ) ; sprintf( buf+strlen(buf) , " intent_p1 = '%g'\n" , nim->intent_p1 ) ; sprintf( buf+strlen(buf) , " intent_p2 = '%g'\n" , nim->intent_p2 ) ; sprintf( buf+strlen(buf) , " intent_p3 = '%g'\n" , nim->intent_p3 ) ; if( nim->intent_name[0] != '\0' ){ ebuf = escapize_string(nim->intent_name) ; sprintf( buf+strlen(buf) , " intent_name = %s\n",ebuf) ; free(ebuf) ; } } if( nim->toffset != 0.0 ) sprintf( buf+strlen(buf) , " toffset = '%g'\n",nim->toffset ) ; if( nim->xyz_units > 0 ) sprintf( buf+strlen(buf) , " xyz_units = '%d'\n" " xyz_units_name = '%s'\n" , nim->xyz_units , nifti_units_string(nim->xyz_units) ) ; if( nim->time_units > 0 ) sprintf( buf+strlen(buf) , " time_units = '%d'\n" " time_units_name = '%s'\n" , nim->time_units , nifti_units_string(nim->time_units) ) ; if( nim->freq_dim > 0 ) sprintf( buf+strlen(buf) , " freq_dim = '%d'\n",nim->freq_dim ) ; if( nim->phase_dim > 0 ) sprintf( buf+strlen(buf) , " phase_dim = '%d'\n",nim->phase_dim ) ; if( nim->slice_dim > 0 ) sprintf( buf+strlen(buf) , " slice_dim = '%d'\n",nim->slice_dim ) ; if( nim->slice_code > 0 ) sprintf( buf+strlen(buf) , " slice_code = '%d'\n" " slice_code_name = '%s'\n" , nim->slice_code , nifti_slice_string(nim->slice_code) ) ; if( nim->slice_start >= 0 && nim->slice_end > nim->slice_start ) sprintf( buf+strlen(buf) , " slice_start = '%d'\n" " slice_end = '%d'\n" , nim->slice_start , nim->slice_end ) ; if( nim->slice_duration != 0.0 ) sprintf( buf+strlen(buf) , " slice_duration = '%g'\n", nim->slice_duration ) ; if( nim->descrip[0] != '\0' ){ ebuf = escapize_string(nim->descrip) ; sprintf( buf+strlen(buf) , " descrip = %s\n",ebuf) ; free(ebuf) ; } if( nim->aux_file[0] != '\0' ){ ebuf = escapize_string(nim->aux_file) ; sprintf( buf+strlen(buf) , " aux_file = %s\n",ebuf) ; free(ebuf) ; } if( nim->qform_code > 0 ){ int i,j,k ; sprintf( buf+strlen(buf) , " qform_code = '%d'\n" " qform_code_name = '%s'\n" " qto_xyz_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" , nim->qform_code , nifti_xform_string(nim->qform_code) , nim->qto_xyz.m[0][0] , nim->qto_xyz.m[0][1] , nim->qto_xyz.m[0][2] , nim->qto_xyz.m[0][3] , nim->qto_xyz.m[1][0] , nim->qto_xyz.m[1][1] , nim->qto_xyz.m[1][2] , nim->qto_xyz.m[1][3] , nim->qto_xyz.m[2][0] , nim->qto_xyz.m[2][1] , nim->qto_xyz.m[2][2] , nim->qto_xyz.m[2][3] , nim->qto_xyz.m[3][0] , nim->qto_xyz.m[3][1] , nim->qto_xyz.m[3][2] , nim->qto_xyz.m[3][3] ) ; sprintf( buf+strlen(buf) , " qto_ijk_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" , nim->qto_ijk.m[0][0] , nim->qto_ijk.m[0][1] , nim->qto_ijk.m[0][2] , nim->qto_ijk.m[0][3] , nim->qto_ijk.m[1][0] , nim->qto_ijk.m[1][1] , nim->qto_ijk.m[1][2] , nim->qto_ijk.m[1][3] , nim->qto_ijk.m[2][0] , nim->qto_ijk.m[2][1] , nim->qto_ijk.m[2][2] , nim->qto_ijk.m[2][3] , nim->qto_ijk.m[3][0] , nim->qto_ijk.m[3][1] , nim->qto_ijk.m[3][2] , nim->qto_ijk.m[3][3] ) ; sprintf( buf+strlen(buf) , " quatern_b = '%g'\n" " quatern_c = '%g'\n" " quatern_d = '%g'\n" " qoffset_x = '%g'\n" " qoffset_y = '%g'\n" " qoffset_z = '%g'\n" " qfac = '%g'\n" , nim->quatern_b , nim->quatern_c , nim->quatern_d , nim->qoffset_x , nim->qoffset_y , nim->qoffset_z , nim->qfac ) ; nifti_mat44_to_orientation( nim->qto_xyz , &i,&j,&k ) ; if( i > 0 && j > 0 && k > 0 ) sprintf( buf+strlen(buf) , " qform_i_orientation = '%s'\n" " qform_j_orientation = '%s'\n" " qform_k_orientation = '%s'\n" , nifti_orientation_string(i) , nifti_orientation_string(j) , nifti_orientation_string(k) ) ; } if( nim->sform_code > 0 ){ int i,j,k ; sprintf( buf+strlen(buf) , " sform_code = '%d'\n" " sform_code_name = '%s'\n" " sto_xyz_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" , nim->sform_code , nifti_xform_string(nim->sform_code) , nim->sto_xyz.m[0][0] , nim->sto_xyz.m[0][1] , nim->sto_xyz.m[0][2] , nim->sto_xyz.m[0][3] , nim->sto_xyz.m[1][0] , nim->sto_xyz.m[1][1] , nim->sto_xyz.m[1][2] , nim->sto_xyz.m[1][3] , nim->sto_xyz.m[2][0] , nim->sto_xyz.m[2][1] , nim->sto_xyz.m[2][2] , nim->sto_xyz.m[2][3] , nim->sto_xyz.m[3][0] , nim->sto_xyz.m[3][1] , nim->sto_xyz.m[3][2] , nim->sto_xyz.m[3][3] ) ; sprintf( buf+strlen(buf) , " sto_ijk matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" , nim->sto_ijk.m[0][0] , nim->sto_ijk.m[0][1] , nim->sto_ijk.m[0][2] , nim->sto_ijk.m[0][3] , nim->sto_ijk.m[1][0] , nim->sto_ijk.m[1][1] , nim->sto_ijk.m[1][2] , nim->sto_ijk.m[1][3] , nim->sto_ijk.m[2][0] , nim->sto_ijk.m[2][1] , nim->sto_ijk.m[2][2] , nim->sto_ijk.m[2][3] , nim->sto_ijk.m[3][0] , nim->sto_ijk.m[3][1] , nim->sto_ijk.m[3][2] , nim->sto_ijk.m[3][3] ) ; nifti_mat44_to_orientation( nim->sto_xyz , &i,&j,&k ) ; if( i > 0 && j > 0 && k > 0 ) sprintf( buf+strlen(buf) , " sform_i_orientation = '%s'\n" " sform_j_orientation = '%s'\n" " sform_k_orientation = '%s'\n" , nifti_orientation_string(i) , nifti_orientation_string(j) , nifti_orientation_string(k) ) ; } sprintf( buf+strlen(buf) , " num_ext = '%d'\n", nim->num_ext ) ; sprintf( buf+strlen(buf) , "/>\n" ) ; /* XML-ish closer */ nbuf = (int)strlen(buf) ; buf = (char *)realloc((void *)buf, nbuf+1); /* cut back to proper length */ if( !buf ) REprintf("** NITA: failed to realloc %d bytes\n",nbuf+1); return buf ; } /*---------------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ /*! get the byte order for this CPU - LSB_FIRST means least significant byte, first (little endian) - MSB_FIRST means most significant byte, first (big endian) *//*--------------------------------------------------------------------*/ int nifti_short_order(void) /* determine this CPU's byte order */ { union { unsigned char bb[2] ; short ss ; } fred ; fred.bb[0] = 1 ; fred.bb[1] = 0 ; return (fred.ss == 1) ? LSB_FIRST : MSB_FIRST ; } /*---------------------------------------------------------------------------*/ #undef QQNUM #undef QNUM #undef QSTR /* macro to check lhs string against "n1"; if it matches, interpret rhs string as a number, and put it into nim->"n2" */ #define QQNUM(n1,n2) if( strcmp(lhs,#n1)==0 ) nim->n2=strtod(rhs,NULL) /* same, but where "n1" == "n2" */ #define QNUM(nam) QQNUM(nam,nam) /* macro to check lhs string against "nam"; if it matches, put rhs string into nim->"nam" string, with max length = "ml" */ #define QSTR(nam,ml) if( strcmp(lhs,#nam) == 0 ) \ strncpy(nim->nam,rhs,ml), nim->nam[ml]='\0' /*---------------------------------------------------------------------------*/ /*! Take an XML-ish ASCII string and create a NIFTI image header to match. NULL is returned if enough information isn't present in the input string. - The image data can later be loaded with nifti_image_load(). - The struct returned here can be liberated with nifti_image_free(). - Not a lot of error checking is done here to make sure that the input values are reasonable! *//*-------------------------------------------------------------------------*/ nifti_image *nifti_image_from_ascii( const char *str, int * bytes_read ) { char lhs[1024] , rhs[1024] ; int ii , spos, nn , slen ; nifti_image *nim ; /* will be output */ if( str == NULL || *str == '\0' ) return NULL ; /* bad input!? */ /* scan for opening string */ spos = 0 ; slen = (int)strlen(str) ; ii = sscanf( str+spos , "%1023s%n" , lhs , &nn ) ; spos += nn ; if( ii == 0 || strcmp(lhs,"nx = nim->ny = nim->nz = nim->nt = nim->nu = nim->nv = nim->nw = 1 ; nim->dx = nim->dy = nim->dz = nim->dt = nim->du = nim->dv = nim->dw = 0 ; nim->qfac = 1.0 ; nim->byteorder = nifti_short_order() ; /* starting at str[spos], scan for "equations" of the form lhs = 'rhs' and assign rhs values into the struct component named by lhs */ while(1){ while( isspace((int) str[spos]) ) spos++ ; /* skip whitespace */ if( str[spos] == '\0' ) break ; /* end of string? */ /* get lhs string */ ii = sscanf( str+spos , "%1023s%n" , lhs , &nn ) ; spos += nn ; if( ii == 0 || strcmp(lhs,"/>") == 0 ) break ; /* end of input? */ /* skip whitespace and the '=' marker */ while( isspace((int) str[spos]) || str[spos] == '=' ) spos++ ; if( str[spos] == '\0' ) break ; /* end of string? */ /* if next character is a quote ', copy everything up to next ' otherwise, copy everything up to next nonblank */ if( str[spos] == '\'' ){ ii = spos+1 ; while( str[ii] != '\0' && str[ii] != '\'' ) ii++ ; nn = ii-spos-1 ; if( nn > 1023 ) nn = 1023 ; memcpy(rhs,str+spos+1,nn) ; rhs[nn] = '\0' ; spos = (str[ii] == '\'') ? ii+1 : ii ; } else { ii = sscanf( str+spos , "%1023s%n" , rhs , &nn ) ; spos += nn ; if( ii == 0 ) break ; /* nothing found? */ } unescape_string(rhs) ; /* remove any XML escape sequences */ /* Now can do the assignment, based on lhs string. Start with special cases that don't fit the QNUM/QSTR macros. */ if( strcmp(lhs,"nifti_type") == 0 ){ if( strcmp(rhs,"ANALYZE-7.5") == 0 ) nim->nifti_type = NIFTI_FTYPE_ANALYZE ; else if( strcmp(rhs,"NIFTI-1+") == 0 ) nim->nifti_type = NIFTI_FTYPE_NIFTI1_1 ; else if( strcmp(rhs,"NIFTI-1") == 0 ) nim->nifti_type = NIFTI_FTYPE_NIFTI1_2 ; else if( strcmp(rhs,"NIFTI-1A") == 0 ) nim->nifti_type = NIFTI_FTYPE_ASCII ; } else if( strcmp(lhs,"header_filename") == 0 ){ nim->fname = nifti_strdup(rhs) ; } else if( strcmp(lhs,"image_filename") == 0 ){ nim->iname = nifti_strdup(rhs) ; } else if( strcmp(lhs,"sto_xyz_matrix") == 0 ){ sscanf( rhs , "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f" , &(nim->sto_xyz.m[0][0]) , &(nim->sto_xyz.m[0][1]) , &(nim->sto_xyz.m[0][2]) , &(nim->sto_xyz.m[0][3]) , &(nim->sto_xyz.m[1][0]) , &(nim->sto_xyz.m[1][1]) , &(nim->sto_xyz.m[1][2]) , &(nim->sto_xyz.m[1][3]) , &(nim->sto_xyz.m[2][0]) , &(nim->sto_xyz.m[2][1]) , &(nim->sto_xyz.m[2][2]) , &(nim->sto_xyz.m[2][3]) , &(nim->sto_xyz.m[3][0]) , &(nim->sto_xyz.m[3][1]) , &(nim->sto_xyz.m[3][2]) , &(nim->sto_xyz.m[3][3]) ) ; } else if( strcmp(lhs,"byteorder") == 0 ){ if( strcmp(rhs,"MSB_FIRST") == 0 ) nim->byteorder = MSB_FIRST ; if( strcmp(rhs,"LSB_FIRST") == 0 ) nim->byteorder = LSB_FIRST ; } else QQNUM(image_offset,iname_offset) ; else QNUM(datatype) ; else QNUM(ndim) ; else QNUM(nx) ; else QNUM(ny) ; else QNUM(nz) ; else QNUM(nt) ; else QNUM(nu) ; else QNUM(nv) ; else QNUM(nw) ; else QNUM(dx) ; else QNUM(dy) ; else QNUM(dz) ; else QNUM(dt) ; else QNUM(du) ; else QNUM(dv) ; else QNUM(dw) ; else QNUM(cal_min) ; else QNUM(cal_max) ; else QNUM(scl_slope) ; else QNUM(scl_inter) ; else QNUM(intent_code) ; else QNUM(intent_p1) ; else QNUM(intent_p2) ; else QNUM(intent_p3) ; else QSTR(intent_name,15) ; else QNUM(toffset) ; else QNUM(xyz_units) ; else QNUM(time_units) ; else QSTR(descrip,79) ; else QSTR(aux_file,23) ; else QNUM(qform_code) ; else QNUM(quatern_b) ; else QNUM(quatern_c) ; else QNUM(quatern_d) ; else QNUM(qoffset_x) ; else QNUM(qoffset_y) ; else QNUM(qoffset_z) ; else QNUM(qfac) ; else QNUM(sform_code) ; else QNUM(freq_dim) ; else QNUM(phase_dim) ; else QNUM(slice_dim) ; else QNUM(slice_code) ; else QNUM(slice_start) ; else QNUM(slice_end) ; else QNUM(slice_duration) ; else QNUM(num_ext) ; } /* end of while loop */ if( bytes_read ) *bytes_read = spos+1; /* "process" last '\n' */ /* do miscellaneous checking and cleanup */ if( nim->ndim <= 0 ){ nifti_image_free(nim); return NULL; } /* bad! */ nifti_datatype_sizes( nim->datatype, &(nim->nbyper), &(nim->swapsize) ); if( nim->nbyper == 0 ){ nifti_image_free(nim); return NULL; } /* bad! */ nim->dim[0] = nim->ndim ; nim->dim[1] = nim->nx ; nim->pixdim[1] = nim->dx ; nim->dim[2] = nim->ny ; nim->pixdim[2] = nim->dy ; nim->dim[3] = nim->nz ; nim->pixdim[3] = nim->dz ; nim->dim[4] = nim->nt ; nim->pixdim[4] = nim->dt ; nim->dim[5] = nim->nu ; nim->pixdim[5] = nim->du ; nim->dim[6] = nim->nv ; nim->pixdim[6] = nim->dv ; nim->dim[7] = nim->nw ; nim->pixdim[7] = nim->dw ; nim->nvox = (size_t)nim->nx * nim->ny * nim->nz * nim->nt * nim->nu * nim->nv * nim->nw ; if( nim->qform_code > 0 ) nim->qto_xyz = nifti_quatern_to_mat44( nim->quatern_b, nim->quatern_c, nim->quatern_d, nim->qoffset_x, nim->qoffset_y, nim->qoffset_z, nim->dx , nim->dy , nim->dz , nim->qfac ) ; else nim->qto_xyz = nifti_quatern_to_mat44( 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , nim->dx , nim->dy , nim->dz , 0.0 ) ; nim->qto_ijk = nifti_mat44_inverse( nim->qto_xyz ) ; if( nim->sform_code > 0 ) nim->sto_ijk = nifti_mat44_inverse( nim->sto_xyz ) ; return nim ; } /*---------------------------------------------------------------------------*/ /*! validate the nifti_image \return 1 if the structure seems valid, otherwise 0 \sa nifti_nim_has_valid_dims, nifti_hdr_looks_good *//*-------------------------------------------------------------------------*/ int nifti_nim_is_valid(nifti_image * nim, int complain) { int errs = 0; if( !nim ){ REprintf("** is_valid_nim: nim is NULL\n"); return 0; } if( g_opts.debug > 2 ) REprintf("-d nim_is_valid check...\n"); /**- check that dim[] matches the individual values ndim, nx, ny, ... */ if( ! nifti_nim_has_valid_dims(nim,complain) ){ if( !complain ) return 0; errs++; } /* might check nbyper, pixdim, q/sforms, swapsize, nifti_type, ... */ /**- be explicit in return of 0 or 1 */ if( errs > 0 ) return 0; else return 1; } /*---------------------------------------------------------------------------*/ /*! validate nifti dimensions \return 1 if valid, 0 if not \sa nifti_nim_is_valid, nifti_hdr_looks_good rely on dim[] as the master *//*-------------------------------------------------------------------------*/ int nifti_nim_has_valid_dims(nifti_image * nim, int complain) { size_t prod; int c, errs = 0; /**- start with dim[0]: failure here is considered terminal */ if( nim->dim[0] <= 0 || nim->dim[0] > 7 ){ errs++; if( complain ) REprintf("** NVd: dim[0] (%d) out of range [1,7]\n",nim->dim[0]); return 0; } /**- check whether ndim equals dim[0] */ if( nim->ndim != nim->dim[0] ){ errs++; if( ! complain ) return 0; REprintf("** NVd: ndim != dim[0] (%d,%d)\n",nim->ndim,nim->dim[0]); } /**- compare each dim[i] to the proper nx, ny, ... */ if( ( (nim->dim[0] >= 1) && (nim->dim[1] != nim->nx) ) || ( (nim->dim[0] >= 2) && (nim->dim[2] != nim->ny) ) || ( (nim->dim[0] >= 3) && (nim->dim[3] != nim->nz) ) || ( (nim->dim[0] >= 4) && (nim->dim[4] != nim->nt) ) || ( (nim->dim[0] >= 5) && (nim->dim[5] != nim->nu) ) || ( (nim->dim[0] >= 6) && (nim->dim[6] != nim->nv) ) || ( (nim->dim[0] >= 7) && (nim->dim[7] != nim->nw) ) ){ errs++; if( !complain ) return 0; REprintf("** NVd mismatch: dims = %d,%d,%d,%d,%d,%d,%d\n" " nxyz... = %d,%d,%d,%d,%d,%d,%d\n", nim->dim[1], nim->dim[2], nim->dim[3], nim->dim[4], nim->dim[5], nim->dim[6], nim->dim[7], nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw ); } if( g_opts.debug > 2 ){ REprintf("-d check dim[%d] =", nim->dim[0]); for( c = 0; c < 7; c++ ) REprintf(" %d", nim->dim[c]); REprintf("\n"); /*fputc('\n', stderr);*/ } /**- check the dimensions, and that their product matches nvox */ prod = 1; for( c = 1; c <= nim->dim[0]; c++ ){ if( nim->dim[c] > 0) prod *= nim->dim[c]; else if( nim->dim[c] <= 0 ){ if( !complain ) return 0; REprintf("** NVd: dim[%d] (=%d) <= 0\n",c, nim->dim[c]); errs++; } } if( prod != nim->nvox ){ if( ! complain ) return 0; REprintf("** NVd: nvox does not match %d-dim product (%u, %u)\n", nim->dim[0], (unsigned)nim->nvox, (unsigned)prod); errs++; } /**- if debug, warn about any remaining dim that is neither 0, nor 1 */ /* (values in dims above dim[0] are undefined, as reminded by Cinly Ooi and Alle Meije Wink) 16 Nov 2005 [rickr] */ if( g_opts.debug > 1 ) for( c = nim->dim[0]+1; c <= 7; c++ ) if( nim->dim[c] != 0 && nim->dim[c] != 1 ) REprintf("** NVd warning: dim[%d] = %d, but ndim = %d\n", c, nim->dim[c], nim->dim[0]); if( g_opts.debug > 2 ) REprintf("-d nim_has_valid_dims check, errs = %d\n", errs); /**- return invalid or valid */ if( errs > 0 ) return 0; else return 1; } /*---------------------------------------------------------------------------*/ /*! read a nifti image, collapsed across dimensions according to dims[8]

    This function may be used to read parts of a nifti dataset, such as
    the time series for a single voxel, or perhaps a slice.  It is similar
    to nifti_image_load(), though the passed 'data' parameter is used for
    returning the image, not nim->data.

    \param nim  given nifti_image struct, corresponding to the data file
    \param dims given list of dimensions (see below)
    \param data pointer to data pointer (if *data is NULL, data will be
                allocated, otherwise not)

    Here, dims is an array of 8 ints, similar to nim->dim[8].  While dims[0]
    is unused at this point, the other indices specify which dimensions to
    collapse (and at which index), and which not to collapse.  If dims[i] is
    set to -1, then that entire dimension will be read in, from index 0 to
    index (nim->dim[i] - 1).  If dims[i] >= 0, then only that index will be
    read in (so dims[i] must also be < nim->dim[i]).

    Example: given  nim->dim[8] = { 4, 64, 64, 21, 80, 1, 1, 1 } (4-D dataset)

      if dims[8] = { 0,  5,  4, 17, -1, -1, -1, -1 }
         -> read time series for voxel i,j,k = 5,4,17

      if dims[8] = { 0, -1, -1, -1, 17, -1, -1, -1 }
         -> read single volume at time point 17

    Example: given  nim->dim[8] = { 6, 64, 64, 21, 80, 4, 3, 1 } (6-D dataset)

      if dims[8] = { 0, 5, 4, 17, -1, 2, 1, 0 }
         -> read time series for the voxel i,j,k = 5,4,17, and dim 5,6 = 2,1

      if dims[8] = { 0, 5, 4, -1, -1, 0, 0, 0 }
         -> read time series for slice at i,j = 5,4, and dim 5,6,7 = 0,0,0
            (note that dims[7] is not relevant, but must be 0 or -1)

    If *data is NULL, then *data will be set as a pointer to new memory,
    allocated here for the resulting collapsed image data.

      e.g. { int    dims[8] = { 0,  5,  4, 17, -1, -1, -1, -1 };
             void * data    = NULL;
             ret_val = nifti_read_collapsed_image(nim, dims, &data);
             if( ret_val > 0 ){
                process_time_series(data);
                if( data != NULL ) free(data);
             }
           }

    NOTE: If *data is not NULL, then it will be assumed that it points to
          valid memory, sufficient to hold the results.  This is done for
          speed and possibly repeated calls to this function.

      e.g. { int    dims[8] = { 0,  -1, -1, -1, -1, -1, -1, -1 };
             void * data    = NULL;
             for( zslice = 0; zslice < nzslices; zslice++ ){
                dims[3] = zslice;
                ret_val = nifti_read_collapsed_image(nim, dims, &data);
                if( ret_val > 0 ) process_slice(zslice, data);
             }
             if( data != NULL ) free(data);
           }

    \return
        -  the total number of bytes read, or < 0 on failure
        -  the read and byte-swapped data, in 'data'            
\sa nifti_image_read, nifti_image_free, nifti_image_read_bricks nifti_image_load *//*-------------------------------------------------------------------------*/ int nifti_read_collapsed_image( nifti_image * nim, const int dims [8], void ** data ) { znzFile fp; int pivots[8], prods[8], nprods; /* sizes are bounded by dims[], so 8 */ int c, bytes; /** - check pointers for sanity */ if( !nim || !dims || !data ){ REprintf("** nifti_RCI: bad params %p, %p, %p\n", (void *)nim, (void *)dims, (void *)data); return -1; } if( g_opts.debug > 2 ){ REprintf("-d read_collapsed_image:\n dims ="); for(c = 0; c < 8; c++) REprintf(" %3d", dims[c]); REprintf("\n nim->dims ="); for(c = 0; c < 8; c++) REprintf(" %3d", nim->dim[c]); REprintf("\n"); /*fputc('\n', stderr);*/ } /** - verify that dim[] makes sense */ if( ! nifti_nim_is_valid(nim, g_opts.debug > 0) ){ REprintf("** invalid nim (file is '%s')\n", nim->fname ); return -1; } /** - verify that dims[] makes sense for this dataset */ for( c = 1; c <= nim->dim[0]; c++ ){ if( dims[c] >= nim->dim[c] ){ REprintf("** nifti_RCI: dims[%d] >= nim->dim[%d] (%d,%d)\n", c, c, dims[c], nim->dim[c]); return -1; } } /** - prepare pivot list - pivots are fixed indices */ if( make_pivot_list(nim, dims, pivots, prods, &nprods) < 0 ) return -1; bytes = rci_alloc_mem(data, prods, nprods, nim->nbyper); if( bytes < 0 ) return -1; /** - open the image file for reading at the appropriate offset */ fp = nifti_image_load_prep( nim ); if( ! fp ){ free(*data); *data = NULL; return -1; } /* failure */ /** - call the recursive reading function, passing nim, the pivot info, location to store memory, and file pointer and position */ c = rci_read_data(nim, pivots,prods,nprods,dims, (char *)*data, fp, znztell(fp)); znzclose(fp); /* in any case, close the file */ if( c < 0 ){ free(*data); *data = NULL; return -1; } /* failure */ if( g_opts.debug > 1 ) REprintf("+d read %d bytes of collapsed image from %s\n", bytes, nim->fname); return bytes; } /* local function to find strides per dimension. assumes 7D size and ** stride array. */ static void compute_strides(int *strides,const int *size,int nbyper) { int i; strides[0] = nbyper; for(i = 1; i < 7; i++) { strides[i] = size[i-1] * strides[i-1]; } } /*---------------------------------------------------------------------------*/ /*! read an arbitrary subregion from a nifti image This function may be used to read a single arbitary subregion of any rectangular size from a nifti dataset, such as a small 5x5x5 subregion around the center of a 3D image. \param nim given nifti_image struct, corresponding to the data file \param start_index the index location of the first voxel that will be returned \param region_size the size of the subregion to be returned \param data pointer to data pointer (if *data is NULL, data will be allocated, otherwise not) Example: given nim->dim[8] = {3, 64, 64, 64, 1, 1, 1, 1 } (3-D dataset) if start_index[7] = { 29, 29, 29, 0, 0, 0, 0 } and region_size[7] = { 5, 5, 5, 1, 1, 1, 1 } -> read 5x5x5 region starting with the first voxel location at (29,29,29) NOTE: If *data is not NULL, then it will be assumed that it points to valid memory, sufficient to hold the results. This is done for speed and possibly repeated calls to this function. \return - the total number of bytes read, or < 0 on failure - the read and byte-swapped data, in 'data' \sa nifti_image_read, nifti_image_free, nifti_image_read_bricks nifti_image_load, nifti_read_collapsed_image *//*-------------------------------------------------------------------------*/ int nifti_read_subregion_image( nifti_image * nim, int *start_index, int *region_size, void ** data ) { znzFile fp; /* file to read */ int i,j,k,l,m,n; /* indices for dims */ long int bytes = 0; /* total # bytes read */ int total_alloc_size; /* size of buffer allocation */ char *readptr; /* where in *data to read next */ int strides[7]; /* strides between dimensions */ int collapsed_dims[8]; /* for read_collapsed_image */ int *image_size; /* pointer to dimensions in header */ long int initial_offset; long int offset; /* seek offset for reading current row */ /* probably ignored, but set to ndim for consistency*/ collapsed_dims[0] = nim->ndim; /* build a dims array for collapsed image read */ for(i = 0; i < nim->ndim; i++) { /* if you take the whole extent in this dimension */ if(start_index[i] == 0 && region_size[i] == nim->dim[i+1]) { collapsed_dims[i+1] = -1; } /* if you specify a single element in this dimension */ else if(region_size[i] == 1) { collapsed_dims[i+1] = start_index[i]; } else { collapsed_dims[i+1] = -2; /* sentinel value */ } } /* fill out end of collapsed_dims */ for(i = nim->ndim ; i < 7; i++) { collapsed_dims[i+1] = -1; } /* check to see whether collapsed read is possible */ for(i = 1; i <= nim->ndim; i++) { if(collapsed_dims[i] == -2) { break; } } /* if you get through all the dimensions without hitting ** a subrange of size > 1, a collapsed read is possible */ if(i > nim->ndim) { return nifti_read_collapsed_image(nim, collapsed_dims, data); } /* point past first element of dim, which holds nim->ndim */ image_size = &(nim->dim[1]); /* check region sizes for sanity */ for(i = 0; i < nim->ndim; i++) { if(start_index[i] + region_size[i] > image_size[i]) { if(g_opts.debug > 1) { REprintf("region doesn't fit within image size\n"); } return -1; } } /* get the file open */ fp = nifti_image_load_prep( nim ); /* the current offset is just past the nifti header, save * location so that SEEK_SET can be used below */ initial_offset = znztell(fp); /* get strides*/ compute_strides(strides,image_size,nim->nbyper); total_alloc_size = nim->nbyper; /* size of pixel */ /* find alloc size */ for(i = 0; i < nim->ndim; i++) { total_alloc_size *= region_size[i]; } /* allocate buffer, if necessary */ if(*data == 0) { *data = (void *)malloc(total_alloc_size); } if(*data == 0) { if(g_opts.debug > 1) { REprintf("allocation of %d bytes failed\n",total_alloc_size); return -1; } } /* point to start of data buffer as char * */ readptr = *((char **)data); { /* can't assume that start_index and region_size have any more than ** nim->ndim elements so make local copies, filled out to seven elements */ int si[7], rs[7]; for(i = 0; i < nim->ndim; i++) { si[i] = start_index[i]; rs[i] = region_size[i]; } for(i = nim->ndim; i < 7; i++) { si[i] = 0; rs[i] = 1; } /* loop through subregion and read a row at a time */ for(i = si[6]; i < (si[6] + rs[6]); i++) { for(j = si[5]; j < (si[5] + rs[5]); j++) { for(k = si[4]; k < (si[4] + rs[4]); k++) { for(l = si[3]; l < (si[3] + rs[3]); l++) { for(m = si[2]; m < (si[2] + rs[2]); m++) { for(n = si[1]; n < (si[1] + rs[1]); n++) { int nread,read_amount; offset = initial_offset + (i * strides[6]) + (j * strides[5]) + (k * strides[4]) + (l * strides[3]) + (m * strides[2]) + (n * strides[1]) + (si[0] * strides[0]); znzseek(fp, offset, SEEK_SET); /* seek to current row */ read_amount = rs[0] * nim->nbyper; /* read a row of the subregion*/ nread = (int)nifti_read_buffer(fp, readptr, read_amount, nim); if(nread != read_amount) { if(g_opts.debug > 1) { REprintf("read of %d bytes failed\n",read_amount); return -1; } } bytes += nread; readptr += read_amount; } } } } } } } return bytes; } /* read the data from the file pointed to by fp - this a recursive function, so start with the base case - data is now (char *) for easy incrementing return 0 on success, < 0 on failure */ static int rci_read_data(nifti_image * nim, int * pivots, int * prods, int nprods, const int dims[], char * data, znzFile fp, size_t base_offset) { size_t sublen, offset, read_size; int c; /* bad check first - base_offset may not have been checked */ if( nprods <= 0 ){ REprintf("** rci_read_data, bad prods, %d\n", nprods); return -1; } /* base case: actually read the data */ if( nprods == 1 ){ size_t nread, bytes; /* make sure things look good here */ if( *pivots != 0 ){ REprintf("** rciRD: final pivot == %d!\n", *pivots); return -1; } /* so just seek and read (prods[0] * nbyper) bytes from the file */ znzseek(fp, (long)base_offset, SEEK_SET); bytes = (size_t)prods[0] * nim->nbyper; nread = nifti_read_buffer(fp, data, bytes, nim); if( nread != bytes ){ REprintf("** rciRD: read only %u of %u bytes from '%s'\n", (unsigned)nread, (unsigned)bytes, nim->fname); return -1; } else if( g_opts.debug > 3 ) REprintf("+d successful read of %u bytes at offset %u\n", (unsigned)bytes, (unsigned)base_offset); return 0; /* done with base case - return success */ } /* not the base case, so do a set of reduced reads */ /* compute size of sub-brick: all dimensions below pivot */ for( c = 1, sublen = 1; c < *pivots; c++ ) sublen *= nim->dim[c]; /* compute number of values to read, i.e. remaining prods */ for( c = 1, read_size = 1; c < nprods; c++ ) read_size *= prods[c]; read_size *= nim->nbyper; /* and multiply by bytes per voxel */ /* now repeatedly compute offsets, and recursively read */ for( c = 0; c < prods[0]; c++ ){ /* offset is (c * sub-block size (including pivot dim)) */ /* + (dims[] index into pivot sub-block) */ /* the unneeded multiplication is to make this more clear */ offset = (size_t)c * sublen * nim->dim[*pivots] + (size_t)sublen * dims[*pivots]; offset *= nim->nbyper; if( g_opts.debug > 3 ) REprintf("-d reading %u bytes, foff %u + %u, doff %u\n", (unsigned)read_size, (unsigned)base_offset, (unsigned)offset, (unsigned)(c*read_size)); /* now read the next level down, adding this offset */ if( rci_read_data(nim, pivots+1, prods+1, nprods-1, dims, data + c * read_size, fp, base_offset + offset) < 0 ) return -1; } return 0; } /* allocate memory for all collapsed image data If *data is already set, do not allocate, but still calculate size for debug report. return total size on success, and < 0 on failure */ static int rci_alloc_mem(void ** data, int prods[8], int nprods, int nbyper ) { int size, index; if( nbyper < 0 || nprods < 1 || nprods > 8 ){ REprintf("** rci_am: bad params, %d, %d\n", nbyper, nprods); return -1; } for( index = 0, size = 1; index < nprods; index++ ) size *= prods[index]; size *= nbyper; if( ! *data ){ /* then allocate what is needed */ if( g_opts.debug > 1 ) REprintf("+d alloc %d (= %d x %d) bytes for collapsed image\n", size, size/nbyper, nbyper); *data = malloc(size); /* actually allocate the memory */ if( ! *data ){ REprintf("** rci_am: failed to alloc %d bytes for data\n", size); return -1; } } else if( g_opts.debug > 1 ) REprintf("-d rci_am: *data already set, need %d (%d x %d) bytes\n", size, size/nbyper, nbyper); return size; } /* prepare a pivot list for reading The pivot points are the indices into dims where the calling function wants to collapse a dimension. The last pivot should always be zero (note that we have space for that in the lists). */ static int make_pivot_list(nifti_image * nim, const int dims[], int pivots[], int prods[], int * nprods ) { int len, index; len = 0; index = nim->dim[0]; while( index > 0 ){ prods[len] = 1; while( index > 0 && (nim->dim[index] == 1 || dims[index] == -1) ){ prods[len] *= nim->dim[index]; index--; } pivots[len] = index; len++; index--; /* fine, let it drop out at -1 */ } /* make sure to include 0 as a pivot (instead of just 1, if it is) */ if( pivots[len-1] != 0 ){ pivots[len] = 0; prods[len] = 1; len++; } *nprods = len; if( g_opts.debug > 2 ){ REprintf("+d pivot list created, pivots :"); for(index = 0; index < len; index++) REprintf(" %d", pivots[index]); REprintf(", prods :"); for(index = 0; index < len; index++) REprintf(" %d", prods[index]); REprintf("\n"); /*fputc('\n',stderr);*/ } return 0; } #undef ISEND #define ISEND(c) ( (c)==']' || (c)=='}' || (c)=='\0' ) /*---------------------------------------------------------------------*/ /*! Get an integer list in the range 0..(nvals-1), from the character string str. If we call the output pointer fred, then fred[0] = number of integers in the list (> 0), and fred[i] = i-th integer in the list for i=1..fred[0]. If on return, fred == NULL or fred[0] == 0, then something is wrong, and the caller must deal with that. Syntax of input string: - initial '{' or '[' is skipped, if present - ends when '}' or ']' or end of string is found - contains entries separated by commas - entries have one of these forms: - a single number - a dollar sign '$', which means nvals-1 - a sequence of consecutive numbers in the form "a..b" or "a-b", where "a" and "b" are single numbers (or '$') - a sequence of evenly spaced numbers in the form "a..b(c)" or "a-b(c)", where "c" encodes the step - Example: "[2,7..4,3..9(2)]" decodes to the list 2 7 6 5 4 3 5 7 9 - entries should be in the range 0..nvals-1 (borrowed, with permission, from thd_intlist.c) *//*-------------------------------------------------------------------*/ int * nifti_get_intlist( int nvals , const char * str ) { int *subv = NULL ; int ii , ipos , nout , slen ; int ibot,itop,istep , nused ; char *cpt ; /* Meaningless input? */ if( nvals < 1 ) return NULL ; /* No selection list? */ if( str == NULL || str[0] == '\0' ) return NULL ; /* skip initial '[' or '{' */ subv = (int *)malloc( sizeof(int) * 2 ) ; if( !subv ) { REprintf("** nifti_get_intlist: failed alloc of 2 ints\n"); return NULL; } subv[0] = nout = 0 ; ipos = 0 ; if( str[ipos] == '[' || str[ipos] == '{' ) ipos++ ; if( g_opts.debug > 1 ) REprintf("-d making int_list (vals = %d) from '%s'\n", nvals, str); /**- for each sub-selector until end of input... */ slen = (int)strlen(str) ; while( ipos < slen && !ISEND(str[ipos]) ){ while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */ if( ISEND(str[ipos]) ) break ; /* done */ /**- get starting value */ if( str[ipos] == '$' ){ /* special case */ ibot = nvals-1 ; ipos++ ; } else { /* decode an integer */ ibot = strtol( str+ipos , &cpt , 10 ) ; if( ibot < 0 ){ REprintf("** ERROR: list index %d is out of range 0..%d\n", ibot,nvals-1) ; free(subv) ; return NULL ; } if( ibot >= nvals ){ REprintf("** ERROR: list index %d is out of range 0..%d\n", ibot,nvals-1) ; free(subv) ; return NULL ; } nused = (cpt-(str+ipos)) ; if( ibot == 0 && nused == 0 ){ REprintf("** ERROR: list syntax error '%s'\n",str+ipos) ; free(subv) ; return NULL ; } ipos += nused ; } while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */ /**- if that's it for this sub-selector, add one value to list */ if( str[ipos] == ',' || ISEND(str[ipos]) ){ nout++ ; subv = (int *)realloc( (char *)subv , sizeof(int) * (nout+1) ) ; if( !subv ) { REprintf("** nifti_get_intlist: failed realloc of %d ints\n", nout+1); return NULL; } subv[0] = nout ; subv[nout] = ibot ; if( ISEND(str[ipos]) ) break ; /* done */ ipos++ ; continue ; /* re-start loop at next sub-selector */ } /**- otherwise, must have '..' or '-' as next inputs */ if( str[ipos] == '-' ){ ipos++ ; } else if( str[ipos] == '.' && str[ipos+1] == '.' ){ ipos++ ; ipos++ ; } else { REprintf("** ERROR: index list syntax is bad: '%s'\n", str+ipos) ; free(subv) ; return NULL ; } /**- get ending value for loop now */ if( str[ipos] == '$' ){ /* special case */ itop = nvals-1 ; ipos++ ; } else { /* decode an integer */ itop = strtol( str+ipos , &cpt , 10 ) ; if( itop < 0 ){ REprintf("** ERROR: index %d is out of range 0..%d\n", itop,nvals-1) ; free(subv) ; return NULL ; } if( itop >= nvals ){ REprintf("** ERROR: index %d is out of range 0..%d\n", itop,nvals-1) ; free(subv) ; return NULL ; } nused = (cpt-(str+ipos)) ; if( itop == 0 && nused == 0 ){ REprintf("** ERROR: index list syntax error '%s'\n",str+ipos) ; free(subv) ; return NULL ; } ipos += nused ; } /**- set default loop step */ istep = (ibot <= itop) ? 1 : -1 ; while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */ /**- check if we have a non-default loop step */ if( str[ipos] == '(' ){ /* decode an integer */ ipos++ ; istep = strtol( str+ipos , &cpt , 10 ) ; if( istep == 0 ){ REprintf("** ERROR: index loop step is 0!\n") ; free(subv) ; return NULL ; } nused = (cpt-(str+ipos)) ; ipos += nused ; if( str[ipos] == ')' ) ipos++ ; if( (ibot-itop)*istep > 0 ){ REprintf("** WARNING: index list '%d..%d(%d)' means nothing\n", ibot,itop,istep ) ; } } /**- add values to output */ for( ii=ibot ; (ii-itop)*istep <= 0 ; ii += istep ){ nout++ ; subv = (int *)realloc( (char *)subv , sizeof(int) * (nout+1) ) ; if( !subv ) { REprintf("** nifti_get_intlist: failed realloc of %d ints\n", nout+1); return NULL; } subv[0] = nout ; subv[nout] = ii ; } /**- check if we have a comma to skip over */ while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */ if( str[ipos] == ',' ) ipos++ ; /* skip commas */ } /* end of loop through selector string */ if( g_opts.debug > 1 ) { REprintf("+d int_list (vals = %d): ", subv[0]); for( ii = 1; ii <= subv[0]; ii++ ) REprintf("%d ", subv[ii]); REprintf("\n"); /*fputc('\n',stderr);*/ } if( subv[0] == 0 ){ free(subv); subv = NULL; } return subv ; } /*---------------------------------------------------------------------*/ /*! Given a NIFTI_TYPE string, such as "NIFTI_TYPE_INT16", return the * corresponding integral type code. The type code is the macro * value defined in nifti1.h. *//*-------------------------------------------------------------------*/ int nifti_datatype_from_string( const char * name ) { int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele); int c; if( !name ) return DT_UNKNOWN; for( c = tablen-1; c > 0; c-- ) if( !strcmp(name, nifti_type_list[c].name) ) break; return nifti_type_list[c].type; } /*---------------------------------------------------------------------*/ /*! Given a NIFTI_TYPE value, such as NIFTI_TYPE_INT16, return the * corresponding macro label as a string. The dtype code is the * macro value defined in nifti1.h. *//*-------------------------------------------------------------------*/ const char * nifti_datatype_to_string( int dtype ) { int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele); int c; for( c = tablen-1; c > 0; c-- ) if( nifti_type_list[c].type == dtype ) break; return nifti_type_list[c].name; } /*---------------------------------------------------------------------*/ /*! Determine whether dtype is a valid NIFTI_TYPE. * * DT_UNKNOWN is considered invalid * * The only difference 'for_nifti' makes is that DT_BINARY * should be invalid for a NIfTI dataset. *//*-------------------------------------------------------------------*/ int nifti_datatype_is_valid( int dtype, int for_nifti ) { int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele); int c; /* special case */ if( for_nifti && dtype == DT_BINARY ) return 0; for( c = tablen-1; c > 0; c-- ) if( nifti_type_list[c].type == dtype ) return 1; return 0; } /*---------------------------------------------------------------------*/ /*! Only as a test, verify that the new nifti_type_list table matches * the the usage of nifti_datatype_sizes (which could be changed to * use the table, if there were interest). * * return the number of errors (so 0 is success, as usual) *//*-------------------------------------------------------------------*/ int nifti_test_datatype_sizes(int verb) { int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele); int nbyper, ssize; int c, errs = 0; for( c = 0; c < tablen; c++ ) { nbyper = ssize = -1; nifti_datatype_sizes(nifti_type_list[c].type, &nbyper, &ssize); if( nbyper < 0 || ssize < 0 || nbyper != nifti_type_list[c].nbyper || ssize != nifti_type_list[c].swapsize ) { if( verb || g_opts.debug > 2 ) REprintf( "** type mismatch: %s, %d, %d, %d : %d, %d\n", nifti_type_list[c].name, nifti_type_list[c].type, nifti_type_list[c].nbyper, nifti_type_list[c].swapsize, nbyper, ssize); errs++; } } if( errs ) REprintf("** nifti_test_datatype_sizes: found %d errors\n",errs); else if( verb || g_opts.debug > 1 ) REprintf("-- nifti_test_datatype_sizes: all OK\n"); return errs; } /*---------------------------------------------------------------------*/ /*! Display the nifti_type_list table. * * if which == 1 : display DT_* * if which == 2 : display NIFTI_TYPE* * else : display all *//*-------------------------------------------------------------------*/ int nifti_disp_type_list( int which ) { char * style; int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele); int lwhich, c; if ( which == 1 ){ lwhich = 1; style = "DT_"; } else if( which == 2 ){ lwhich = 2; style = "NIFTI_TYPE_"; } else { lwhich = 3; style = "ALL"; } Rprintf("nifti_type_list entries (%s) :\n" " name type nbyper swapsize\n" " --------------------- ---- ------ --------\n", style); for( c = 0; c < tablen; c++ ) if( (lwhich & 1 && nifti_type_list[c].name[0] == 'D') || (lwhich & 2 && nifti_type_list[c].name[0] == 'N') ) Rprintf(" %-22s %5d %3d %5d\n", nifti_type_list[c].name, nifti_type_list[c].type, nifti_type_list[c].nbyper, nifti_type_list[c].swapsize); return 0; } Rniftilib/man/0000755000176000001440000000000012073247733013007 5ustar ripleyusersRniftilib/man/nifti_interpolate3D.Rd0000644000176000001440000000211111432314460017165 0ustar ripleyusers\name{nifti.interpolate3d} \alias{nifti.interpolate3d} \title{Interpolation between voxels} \description{ This function interpolates in 3d between voxels (in volume data). } \usage{ nifti.interpolate3d(nim, x, y, z, t=1) } \arguments{ \item{nim}{the nifti object} \item{x}{x coordinate (subpixel/floating point)} \item{y}{y coordinate (subpixel/floating point)} \item{z}{z coordinate (subpixel/floating point)} \item{t}{t coordinate (subpixel/floating point)} } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \author{ Oliver Granert neurologie.uni-kiel.de> } \seealso{ \code{\link{nifti.image.read}}, \code{\link{nifti.image.write}}, \code{\link{nifti.image.new}} } \examples{ \dontrun{ nim <- nifti.image.read(file.choose()) plot(c(nifti.interpolate3d(nim,100,100,3), nifti.interpolate3d(nim,100.25,100,3), nifti.interpolate3d(nim,100.5,100,3), nifti.interpolate3d(nim,100.75,100,3), nifti.interpolate3d(nim,101,100,3)), xlab="position x", ylab="interpolation") } } \keyword{utilities} Rniftilib/man/nifti_set_filenames.Rd0000644000176000001440000000171411432314460017276 0ustar ripleyusers\name{nifti.set.filenames} \alias{nifti.set.filenames} \title{Set filenames for a NIFTI image} \description{ Set filenames (image and header filename) for a NIfTI image. } \usage{ nifti.set.filenames(nim, prefix, check=1, set_byte_order=1) } \arguments{ \item{nim}{the nifti object} \item{prefix}{(required) prefix for output filenames} \item{check}{check for previous existence of filename (existence is an error condition)} \item{set_byte_order}{flag to set nim->byteorder here (if set\_byte\_order=1 then byteorder is set based on the CPU type)} } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \author{ Oliver Granert neurologie.uni-kiel.de> } \seealso{ \code{\link{nifti.image.write}}, \code{\link{nifti.image.read}}, \code{\link{nifti.image.new}} } \examples{ nim <- nifti.image.new() nifti.set.filenames(nim, "testvolume") # show the result nim$fname nim$iname } \keyword{manip} Rniftilib/man/nifti_image_write.Rd0000644000176000001440000000110311432314460016744 0ustar ripleyusers\name{nifti.image.write} \alias{nifti.image.write} \title{Write data to NIfTI (Analyze) files} \description{ This function writes volume data to a NIfTI file. } \usage{ nifti.image.write(nim) } \arguments{ \item{nim}{the nifti object} } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \author{ Oliver Granert neurologie.uni-kiel.de> } \seealso{ \code{\link{nifti.image.read}}, \code{\link{nifti.image.new}} } \examples{ \dontrun{ nim <- nifti.image.read(file.choose()) nifti.image.write(nim) } } \keyword{IO} Rniftilib/man/nifti_image_unload.Rd0000644000176000001440000000112311243564076017110 0ustar ripleyusers\name{nifti.image.unload} \alias{nifti.image.unload} \title{Unload NIfTI image data} \description{ Unload the image data in nifti struct, but keep the metadata. } \usage{ nifti.image.unload(nim) } \arguments{ \item{nim}{the nifti object} } \details{ Unload image data, but keep header information and other metadata. } \value{ A \code{\link{nifti}} object } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \seealso{ \code{\link{nifti.image.write}}, \code{\link{nifti.image.read}} \code{\link{nifti.image.free}} } \keyword{manip} \keyword{data}Rniftilib/man/nifti_image_read.Rd0000644000176000001440000000264412046540352016543 0ustar ripleyusers\name{nifti.image.read} \alias{nifti.image.read} \title{Read data from NIfTI (Analyze) files} \description{ This function reads the meta and image data from a nifti file. } \usage{ nifti.image.read(file, read_data=1, rm.NaN=TRUE) } \arguments{ \item{file}{name of the nifti file} \item{read_data}{0=do not read image data, 1=read image data} \item{rm.NaN}{logical value indicating whether NA and NaN values should be stripped (default in niftilib C library)} } \details{ If \code{read_data=0} only the header info is loaded. } \value{ \code{\link{nifti}} object } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \author{ Oliver Granert neurologie.uni-kiel.de> } \seealso{ \code{\link{nifti.image.write}}, \code{\link{nifti.image.new}} } \examples{ \dontrun{ nim <- nifti.image.read(file.choose()) # access to attributes... nim$qto.xyz # voxel to mm transformation matrix (q-form) nim$qto.ijk # mm to voxel transformation matrix (q-form) nim$sto.xyz # voxel to mm transformation matrix (s-form) nim$sto.ijk # mm to voxel transformation matrix (s-form) nim$toffset # nim$descrip # description nim$fname # header filename (store image information) nim$iname # image filename (store image data) nim$slice.duration # access to voxel values... nim[10,11,12] # voxel value at x=10, y=11, z=12 } } \keyword{IO} Rniftilib/man/nifti_disp_lib_version.Rd0000644000176000001440000000077211216105237020015 0ustar ripleyusers\name{nifti.disp.lib.version} \alias{nifti.disp.lib.version} \title{NIfTI library version.} \description{ Return NIfTI library version and date as a character string. } \usage{ nifti.disp.lib.version() } \value{ String containing library version and compilation date. } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \seealso{ \code{\link{nifti.image.new}}, \code{\link{nifti.image.write}}, \code{\link{nifti.image.read}} } \keyword{manip} \keyword{data} Rniftilib/man/nifti_read_subregion_image.Rd0000644000176000001440000000234011723252462020614 0ustar ripleyusers\name{nifti.read.subregion.image} \alias{nifti.read.subregion.image} \title{Read a subregion from a NIfTI image} \description{ EXPERIMENTAL (unstable interface!): Read a single arbitary subregion of any rectangular size from a NIfTI dataset. } \usage{ nifti.read.subregion.image(nim, start_index, region_size) } \arguments{ \item{nim}{the nifti object} \item{start_index}{start_index the index location of the first voxel that will be returned} \item{region_size}{region_size the size of the subregion to be returned} } \details{ This function may be used to read a single arbitary subregion of any rectangular size from a nifti dataset, such as a small 5x5x5 subregion around the center of a 3D image. Example: given nim$dim = c(64, 64, 64) (3-D dataset) if start_index = c( 29, 29, 29) and region_size = c( 5, 5, 5) -> read 5x5x5 region starting with the first voxel location at (29,29,29) } \value{ The subregion data in a vector. } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \author{ Oliver Granert neurologie.uni-kiel.de> } \seealso{ \code{\link{nifti.image.write}}, \code{\link{nifti.image.read}} } \keyword{manip} \keyword{data} Rniftilib/man/nifti_image_copy_info.Rd0000644000176000001440000000135011432314460017603 0ustar ripleyusers\name{nifti.image.copy.info} \alias{nifti.image.copy.info} \title{Copy NIFTI image (info) without voxel data.} \description{ Copy the nifti.image structure, without data. Duplicate the structure, including fname, iname and extensions. Leave the data pointer as NULL. } \usage{ nifti.image.copy.info(nim) } \arguments{ \item{nim}{the nifti object} } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \author{ Oliver Granert neurologie.uni-kiel.de> } \seealso{ \code{\link{nifti.image.new}}, \code{\link{nifti.image.read}}, \code{\link{nifti.image.write}} } \examples{ \dontrun{ nim <- nifti.image.read(file.choose()) nim_copy <- nifti.image.copy.info(nim) } } \keyword{manip} Rniftilib/man/nifti_image_new.Rd0000644000176000001440000000123411235512516016413 0ustar ripleyusers\name{nifti.image.new} \alias{nifti.image.new} \title{Create new NIfTI image} \description{ Basic initialization of a nifti.image structure (to a 1x1x1 image) } \usage{ nifti.image.new() } \details{ Creates an image of size 1x1x1. } \value{ A \code{\link{nifti}} object } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \author{ Oliver Granert neurologie.uni-kiel.de> } \seealso{ \code{\link{nifti.image.write}}, \code{\link{nifti.image.read}} } \examples{ # create 1x1x1 nifti volume nim=nifti.image.new() # resize nifti volume to 15x15x15 nim$dim<-c(15,15,15) } \keyword{manip} \keyword{data} Rniftilib/man/nifti.Rd0000644000176000001440000001316211723252462014406 0ustar ripleyusers\name{nifti} \alias{nifti} \alias{[.nifti} \alias{dim.nifti} \alias{dim<-.nifti} \alias{$.nifti} \alias{print.nifti} \alias{plot.nifti} \alias{[<-.nifti} \alias{$<-.nifti} \alias{is.nifti} \alias{nifti.image.getdim.save} \title{NIfTI object} \description{ A NIfTI object contains the image description and data of an image volume. Voxels can be accessed by the bracket [dim1,dim2,dim3,...,dim7] operator. } \usage{ \method{[}{nifti}(x, dim1=1:nifti.image.getdim.save(x,1), dim2=1:nifti.image.getdim.save(x,2), dim3=1:nifti.image.getdim.save(x,3), dim4=1:nifti.image.getdim.save(x,4), dim5=1:nifti.image.getdim.save(x,5), dim6=1:nifti.image.getdim.save(x,6), dim7=1:nifti.image.getdim.save(x,7)) \method{$}{nifti}(x, sym) \method{dim}{nifti}(x) \method{print}{nifti}(x,...) \method{plot}{nifti}(x, dim1=1:nifti.image.getdim.save(x,1), dim2=1:nifti.image.getdim.save(x,2),dim3=1, dim4=1,...) is.nifti(x) } \arguments{ \item{x}{NIfTI image object (class nifti)} \item{sym}{ \tabular{rl}{ \code{qto.xyz}\tab voxel to mm transformation (R style indexing!)\cr \code{qto.ijk}\tab mm to voxel transformation (R style indexing!)\cr \code{sto.xyz}\tab voxel to mm transformation (R style indexing!)\cr \code{sto.ijk}\tab mm to voxel transformation (R style indexing!)\cr \code{qto_xyz}\tab voxel to mm transformation (C style indexing!)\cr \code{qto_ijk}\tab mm to voxel transformation (C style indexing!)\cr \code{sto_xyz}\tab voxel to mm transformation (C style indexing!)\cr \code{sto_ijk}\tab mm to voxel transformation (C style indexing!)\cr \code{toffset}\tab \cr \code{descrip}\tab description (up to 80 characters)\cr \code{fname}\tab header filename (store image information)\cr \code{iname}\tab image filename (store image data)\cr \code{slice.duration}\tab time for 1 slice\cr \code{qform.code}\tab \code{NIFTI.XFORM.UNKNOWN} (0) \cr \tab \code{NIFTI.XFORM.SCANNER.ANAT} (1) \cr \tab \code{NIFTI.XFORM.ALIGNED.ANAT} (2) \cr \tab \code{NIFTI.XFORM.TALAIRACH} (3) \cr \tab \code{NIFTI.XFORM.MNI.152} (4)\cr \tab \code{qform code: >No<} for unknown tags \cr \code{sform.code}\tab \code{NIFTI.XFORM.UNKNOWN} (0) \cr \tab \code{NIFTI.XFORM.SCANNER.ANAT} (1)\cr \tab \code{NIFTI.XFORM.ALIGNED.ANAT} (2)\cr \tab \code{NIFTI.XFORM.TALAIRACH} (3) \cr \tab \code{NIFTI.XFORM.MNI.152} (4) \cr \tab \code{sform code: >No<} for unknown tags \cr \code{quatern.b}\tab \cr \code{quatern.c}\tab \cr \code{quatern.d}\tab \cr \code{qoffset.x}\tab \cr \code{qoffset.y}\tab \cr \code{qoffset.z}\tab \cr \code{qfac}\tab \cr \code{dim}\tab image volume size in voxel \cr \code{pixdim}\tab grid spacings. \cr \code{datatype}\tab data type (set also field \code{nbyper})\cr \code{nbyper}\tab bytes per voxel, matches datatype (read only) \cr \code{nifti.type}\tab \code{NIFTI.FTYPE.ANALYZE} (0) : .hdr + .img files \cr \tab \code{NIFTI.FTYPE.NIFTI1.1}(1) : .nii file \cr \tab \code{NIFTI.FTYPE.NIFTI1.2} (2) : .hdr + .img files \cr \tab \code{NIFTI.FTYPE.ASCII} (3) : ? \cr \code{sizeof_hdr}\tab MUST be 348\cr \code{scl.slope} \tab nifti1: Data scaling: slope. analyze 7.5: float funused1 \cr \code{scl.inter} \tab nifti1: Data scaling: offset. analyze 7.5: float funused2 \cr \code{xyz_units} \tab \code{NIFTI_UNITS_UNKNOWN} "" (0) \cr \tab \code{NIFTI_UNITS_METER} "m" (1) \cr \tab \code{NIFTI_UNITS_MM} "mm" (2) \cr \tab \code{NIFTI_UNITS_MICRON} "um" (3) \cr \tab \code{NIFTI_UNITS_SEC} "s" (8) \cr \tab \code{NIFTI_UNITS_MSEC} "ms" (16) \cr \tab \code{NIFTI_UNITS_USEC} "us" (24) \cr \tab \code{NIFTI_UNITS_HZ} "Hz" (32) \cr \tab \code{NIFTI_UNITS_PPM} "ppm" (40) \cr \tab \code{NIFTI_UNITS_RADS} "rad/s" (48) \cr \tab see also \code{\link{nifti.units.string}}\cr \code{time_units}\tab \code{NIFTI_UNITS_UNKNOWN} "" (0) \cr \tab \code{NIFTI_UNITS_METER} "m" (1) \cr \tab \code{NIFTI_UNITS_MM} "mm" (2) \cr \tab \code{NIFTI_UNITS_MICRON} "um" (3) \cr \tab \code{NIFTI_UNITS_SEC} "s" (8) \cr \tab \code{NIFTI_UNITS_MSEC} "ms" (16) \cr \tab \code{NIFTI_UNITS_USEC} "us" (24) \cr \tab \code{NIFTI_UNITS_HZ} "Hz" (32) \cr \tab \code{NIFTI_UNITS_PPM} "ppm" (40) \cr \tab \code{NIFTI_UNITS_RADS} "rad/s" (48) \cr \tab see also \code{\link{nifti.units.string}} }} \item{dim1}{vector of voxel indices (x)} \item{dim2}{vector of voxel indices (y)} \item{dim3}{vector of voxel indices (z)} \item{dim4}{vector of voxel indices (t)} \item{dim5}{vector of voxel indices} \item{dim6}{vector of voxel indices} \item{dim7}{vector of voxel indices} \item{...}{additional arguments for plotting (e.g. \code{\link{image}}) and printing} } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \author{ Oliver Granert neurologie.uni-kiel.de> } \seealso{ \code{\link{nifti.image.read}}, \code{\link{nifti.image.write}}, \code{\link{nifti.image.new}} } \keyword{package} \keyword{data} \keyword{manip} Rniftilib/man/nifti_image_alloc_data.Rd0000644000176000001440000000132311432314460017701 0ustar ripleyusers\name{nifti.image.alloc.data} \alias{nifti.image.alloc.data} \title{Allocate data block for NIfTI image} \description{ Allocate data block for NIfTI image using the information from the header. } \usage{ nifti.image.alloc.data(nim) } \arguments{ \item{nim}{the nifti object} } \details{ The function return the number of bytes allocated. } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \author{ Oliver Granert neurologie.uni-kiel.de> } \seealso{ \code{\link{nifti.image.new}}, \code{\link{nifti.image.write}}, \code{\link{nifti.image.read}} } \examples{ nim=nifti.image.new() no.of.bytes=nifti.image.alloc.data(nim) } \keyword{manip} \keyword{data} Rniftilib/man/nifti_image_setdatatype.Rd0000644000176000001440000000647311407747650020175 0ustar ripleyusers\name{nifti.image.setdatatype} \alias{nifti.image.setdatatype} \title{Change data type of nifti object.} \description{ Set \code{datatype} and \code{nbyper} fields. } \usage{ nifti.image.setdatatype(nim, value) } \arguments{ \item{nim}{ nifti image object } \item{value}{data type as string, e.g. "NIFTI_TYPE_UINT8", or numeric type id, e.g. 2. See details section for a list of possible values.} } \details{ \tabular{rcl}{ \bold{original ANALYZE 7.5 type codes} \tab \bold{numeric type id} \tab \bold{description} \cr \code{DT_NONE} \tab 0 \tab unknown/none data format\cr \code{DT_UNKNOWN} \tab 0 \tab unknown/none data format \cr \code{DT_BINARY} \tab 1 \tab binary (1 bit/voxel) \cr \code{DT_UNSIGNED_CHAR}\tab 2 \tab unsigned char (8 bits/voxel) \cr \code{DT_SIGNED_SHORT} \tab 4 \tab signed short (16 bits/voxel) \cr \code{DT_SIGNED_INT} \tab 8 \tab signed int (32 bits/voxel) \cr \code{DT_FLOAT} \tab 16 \tab float (32 bits/voxel) \cr \code{DT_COMPLEX} \tab 32 \tab complex (64 bits/voxel) \cr \code{DT_DOUBLE} \tab 64 \tab double (64 bits/voxel) \cr \code{DT_RGB} \tab 128 \tab RGB triple (24 bits/voxel) \cr \code{DT_ALL} \tab 255 \tab not very useful (?) \cr \tab \tab \cr \code{DT_UINT8} \tab 2 \tab \cr \code{DT_INT16} \tab 4 \tab \cr \code{DT_INT32} \tab 8 \tab \cr \code{DT_FLOAT32} \tab 16 \tab \cr \code{DT_COMPLEX64} \tab 32 \tab \cr \code{DT_FLOAT64} \tab 64 \tab \cr \code{DT_RGB24} \tab 128 \tab \cr \tab \tab \cr \code{DT_INT8} \tab 256 \tab signed char (8 bits) \cr \code{DT_UINT16} \tab 512 \tab unsigned short (16 bits) \cr \code{DT_UINT32} \tab 768 \tab unsigned int (32 bits) \cr \code{DT_INT64} \tab 1024 \tab long long (64 bits) \cr \code{DT_UINT64} \tab 1280 \tab unsigned long long (64 bits) \cr \code{DT_FLOAT128} \tab 1536 \tab long double (128 bits) \cr \code{DT_COMPLEX128} \tab 1792 \tab double pair (128 bits) \cr \code{DT_COMPLEX256} \tab 2048 \tab long double pair (256 bits) \cr \code{DT_RGBA32} \tab 2304 \tab 4 byte RGBA (32 bits/voxel) \cr \bold{new codes for NIFTI} \tab \tab \cr \code{NIFTI_TYPE_UINT8} \tab 2 \tab unsigned char \cr \code{NIFTI_TYPE_INT16} \tab 4 \tab signed short \cr \code{NIFTI_TYPE_INT32} \tab 8 \tab signed int \cr \code{NIFTI_TYPE_FLOAT32} \tab 16 \tab 32 bit float \cr \code{NIFTI_TYPE_COMPLEX64} \tab 32 \tab 64 bit complex = 2x32 bit floats \cr \code{NIFTI_TYPE_FLOAT64} \tab 64 \tab 64 bit float = double \cr \code{NIFTI_TYPE_RGB24} \tab 128 \tab 3x8 bit bytes \cr \code{NIFTI_TYPE_INT8} \tab 256 \tab signed char \cr \code{NIFTI_TYPE_UINT16} \tab 512 \tab unsigned short \cr \code{NIFTI_TYPE_UINT32} \tab 768 \tab unsigned int \cr \code{NIFTI_TYPE_INT64} \tab 1024 \tab signed long long \cr \code{NIFTI_TYPE_UINT64} \tab 1280 \tab unsigned long long. \cr \code{NIFTI_TYPE_FLOAT128} \tab 1536 \tab 128 bit float = long double \cr \code{NIFTI_TYPE_COMPLEX128} \tab 1792 \tab 128 bit complex = 2 64 bit floats \cr \code{NIFTI_TYPE_COMPLEX256} \tab 2048 \tab 256 bit complex = 2 128 bit floats \cr \code{NIFTI_TYPE_RGBA32} \tab 2304 \tab 4x8 bit bytes (32bits/voxel) \cr }} \seealso{ \code{\link{nifti.image.unload}}, \code{\link{nifti.image.alloc.data}} } \keyword{IO} Rniftilib/man/nifti_units_string.Rd0000644000176000001440000000115611723254424017216 0ustar ripleyusers\name{nifti.units.string} \alias{nifti.units.string} \title{Return string for NIfTI-1 unit code value.} \description{ Return a string holding the name of a NIFTI units type. } \usage{ nifti.units.string(value) } \arguments{ \item{value}{NIfTI-1 unit code} } \details{ Return a string holding the name of a NIFTI units type. } \value{ String for the given unit type value. } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \seealso{ \code{\link{nifti.datatype.string}}, \code{\link{nifti.image.write}}, \code{\link{nifti.image.read}} } \keyword{manip} \keyword{data} Rniftilib/man/nifti_compiled_with_zlib.Rd0000644000176000001440000000125211216273112020322 0ustar ripleyusers\name{nifti.compiled.with.zlib} \alias{nifti.compiled.with.zlib} \title{Check support for compressed NIfTI files.} \description{ Return whether the given Rniftilib C-library was compiled with \code{HAVE_ZLIB} set. } \usage{ nifti.compiled.with.zlib() } \value{ \item{TRUE}{library supports compressed files (.gz)} \item{FALSE}{compressed files are not supported} } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \seealso{ \code{\link{nifti.image.new}}, \code{\link{nifti.image.write}}, \code{\link{nifti.image.read}} } \examples{ nifti.compiled.with.zlib() # return logical value (TRUE or FALSE) } \keyword{manip} \keyword{data}Rniftilib/man/nifti_image_free.Rd0000644000176000001440000000114411243564076016552 0ustar ripleyusers\name{nifti.image.free} \alias{nifti.image.free} \title{Free NIfTI image data structure} \description{ Free image data (everything!). } \usage{ nifti.image.free(nim) } \arguments{ \item{nim}{the nifti object} } \details{ Free 'everything' about a nifti struct (including the passed struct): (fname and iname, data, extensions, nim) } \value{ A \code{\link{nifti}} object } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \seealso{ \code{\link{nifti.image.write}}, \code{\link{nifti.image.read}} \code{\link{nifti.image.unload}} } \keyword{manip} \keyword{data}Rniftilib/man/nifti_datatype_string.Rd0000644000176000001440000000123311723256263017666 0ustar ripleyusers\name{nifti.datatype.string} \alias{nifti.datatype.string} \title{Return string for NIfTI-1 datatype code value.} \description{ Return a string for the datatype of a NIFTI data type. } \usage{ nifti.datatype.string(value) } \arguments{ \item{value}{NIfTI-1 datatype} } \details{ Return a string for the datatype of a NIFTI data type (e.g. "INT8" signed integer data type). } \value{ String for the given data type value. } \references{ \url{http://nifti.nimh.nih.gov} \url{http://niftilib.sourceforge.net} } \seealso{ \code{\link{nifti.units.string}}, \code{\link{nifti.image.write}}, \code{\link{nifti.image.read}} } \keyword{manip} \keyword{data} Rniftilib/aclocal.m40000644000176000001440000000117411431064233014064 0ustar ripleyusers# generated automatically by aclocal 1.11.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_include([ax_check_zlib.m4]) Rniftilib/DESCRIPTION0000644000176000001440000000124212073363334013735 0ustar ripleyusersPackage: Rniftilib Version: 0.0-32 Date: 2012-02-28 Title: Rniftilib - R Interface to NIFTICLIB (V2.0.0: 2010-07-20) Author: Oliver Granert neurologie.uni-kiel.de> Maintainer: Oliver Granert Depends: R (>= 1.8.0) Suggests: Description: R interface to nifticlib (nifticlib-2.0.0) (read/write ANALYZE(TM)7.5/NIfTI-1 volume images) License: GPL (>= 2) URL: http://rniftilib.r-forge.r-project.org/ Repository: CRAN Repository/R-Forge/Project: rniftilib Repository/R-Forge/Revision: 56 Repository/R-Forge/DateTimeStamp: 2013-01-09 08:02:10 Date/Publication: 2013-01-09 22:53:32 Packaged: 2013-01-09 11:17:13 UTC; rforge Rniftilib/config.h.in0000644000176000001440000000332511432314460014250 0ustar ripleyusers/* config.h.in. Generated from configure.in by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #undef HAVE_MALLOC /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to rpl_malloc if the replacement function should be used. */ #undef malloc Rniftilib/ax_check_zlib.m40000644000176000001440000001067211431064233015256 0ustar ripleyusers# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_check_zlib.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_ZLIB() # # DESCRIPTION # # This macro searches for an installed zlib library. If nothing was # specified when calling configure, it searches first in /usr/local and # then in /usr. If the --with-zlib=DIR is specified, it will try to find # it in DIR/include/zlib.h and DIR/lib/libz.a. If --without-zlib is # specified, the library is not searched at all. # # If either the header file (zlib.h) or the library (libz) is not found, # the configuration exits on error, asking for a valid zlib installation # directory or --without-zlib. # # The macro defines the symbol HAVE_LIBZ if the library is found. You # should use autoheader to include a definition for this symbol in a # config.h file. Sample usage in a C/C++ source is as follows: # # #ifdef HAVE_LIBZ # #include # #endif /* HAVE_LIBZ */ # # LICENSE # # Copyright (c) 2008 Loic Dachary # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 7 AU_ALIAS([CHECK_ZLIB], [AX_CHECK_ZLIB]) AC_DEFUN([AX_CHECK_ZLIB], # # Handle user hints # [AC_MSG_CHECKING(if zlib is wanted) AC_ARG_WITH(zlib, [ --with-zlib=DIR root directory path of zlib installation [defaults to /usr/local or /usr if not found in /usr/local] --without-zlib to disable zlib usage completely], [if test "$withval" != no ; then AC_MSG_RESULT(yes) if test -d "$withval" then ZLIB_HOME="$withval" else AC_MSG_WARN([Sorry, $withval does not exist, checking usual places]) fi else AC_MSG_RESULT(no) fi], [AC_MSG_RESULT(yes)]) ZLIB_HOME=/usr/local if test ! -f "${ZLIB_HOME}/include/zlib.h" then ZLIB_HOME=/usr fi # # Locate zlib, if wanted # if test -n "${ZLIB_HOME}" then ZLIB_OLD_LDFLAGS=$LDFLAGS ZLIB_OLD_CPPFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib" CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include" AC_LANG_SAVE AC_LANG_C AC_CHECK_LIB(z, inflateEnd, [zlib_cv_libz=yes], [zlib_cv_libz=no]) AC_CHECK_HEADER(zlib.h, [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no]) AC_LANG_RESTORE if test "$zlib_cv_libz" = "yes" -a "$zlib_cv_zlib_h" = "yes" then # # If both library and header were found, use them # AC_CHECK_LIB(z, inflateEnd) AC_MSG_CHECKING(zlib in ${ZLIB_HOME}) AC_MSG_RESULT(ok) else # # If either header or library was not found, revert and bomb # AC_MSG_CHECKING(zlib in ${ZLIB_HOME}) LDFLAGS="$ZLIB_OLD_LDFLAGS" CPPFLAGS="$ZLIB_OLD_CPPFLAGS" AC_MSG_RESULT(failed) AC_MSG_ERROR(either specify a valid zlib installation with --with-zlib=DIR or disable zlib usage with --without-zlib) fi fi ]) Rniftilib/NAMESPACE0000644000176000001440000000100511723256057013447 0ustar ripleyusersuseDynLib(Rniftilib) export(nifti.image.new, nifti.image.alloc.data, nifti.image.unload, nifti.image.free) export(nifti.image.copy.info, nifti.set.filenames) export(nifti.image.read, nifti.image.write) export(is.nifti, nifti.image.setdatatype) export(nifti.read.subregion.image, nifti.interpolate3d) export(plot.nifti, print.nifti) export(nifti.compiled.with.zlib, nifti.disp.lib.version) export(nifti.units.string, nifti.datatype.string) export("$.nifti","$<-.nifti","[.nifti","[<-.nifti","dim.nifti","dim<-.nifti") Rniftilib/R/0000755000176000001440000000000012073247733012435 5ustar ripleyusersRniftilib/R/nifti.R0000644000176000001440000001107411746053711013671 0ustar ripleyusersnifti.image.new <- function() { .Call("Rnifti_image_new", PACKAGE="Rniftilib") } nifti.image.alloc.data <- function(nim) { .Call("Rnifti_image_alloc_data", nim, PACKAGE="Rniftilib") } nifti.image.unload <- function(nim) { .Call("Rnifti_image_unload", nim, PACKAGE="Rniftilib") } nifti.image.free <- function(nim) { .Call("Rnifti_image_free", nim, PACKAGE="Rniftilib") } nifti.image.copy.info <- function(nim) { .Call("Rnifti_image_copy_info", nim, PACKAGE="Rniftilib") } nifti.set.filenames <- function(nim, prefix, check=1, set_byte_order=1) { .Call("Rnifti_set_filenames", nim, prefix, check, set_byte_order, PACKAGE="Rniftilib") } nifti.image.read <- function(file, read_data=1, rm.NaN=TRUE) { .Call("Rnifti_image_read", file, read_data, rm.NaN, PACKAGE="Rniftilib") } nifti.image.write <- function(nim) { .Call("Rnifti_image_write", nim, PACKAGE="Rniftilib") } nifti.image.getdim.save <- function(nim, index) { d <- dim(nim) retval <- 1 if (length(d) >= index) retval <- d[index] retval } is.nifti <- function(x) { is(x,"nifti") } "[.nifti" <- function(x, dim1=1:nifti.image.getdim.save(x,1), dim2=1:nifti.image.getdim.save(x,2), dim3=1:nifti.image.getdim.save(x,3), dim4=1:nifti.image.getdim.save(x,4), dim5=1:nifti.image.getdim.save(x,5), dim6=1:nifti.image.getdim.save(x,6), dim7=1:nifti.image.getdim.save(x,7)) { .Call("Rnifti_image_getpixel", x, dim1-1, dim2-1, dim3-1, dim4-1, dim5-1, dim6-1, dim7-1, PACKAGE="Rniftilib") } "[<-.nifti" <- function(x, dim1=1:nifti.image.getdim.save(x,1), dim2=1:nifti.image.getdim.save(x,2), dim3=1:nifti.image.getdim.save(x,3), dim4=1:nifti.image.getdim.save(x,4), dim5=1:nifti.image.getdim.save(x,5), dim6=1:nifti.image.getdim.save(x,6), dim7=1:nifti.image.getdim.save(x,7), value) { .Call("Rnifti_image_setpixel", x, dim1-1, dim2-1, dim3-1, dim4-1, dim5-1, dim6-1, dim7-1, value, PACKAGE="Rniftilib") } "$.nifti" <- function(x, sym) { .Call("Rnifti_image_getattribute", x, sym, PACKAGE="Rniftilib") } "$<-.nifti" <- function(x, sym, value) { .Call("Rnifti_image_setattribute", x, sym, value, PACKAGE="Rniftilib") } nifti.image.setdatatype <- function(nim, value) { .Call("Rnifti_image_setdatatype", nim, value, PACKAGE="Rniftilib") } # EXPERIMENTAL function nifti.read.subregion.image <- function(nim, start_index, region_size) { .Call("Rnifti_read_subregion_image", nim, start_index, region_size, PACKAGE="Rniftilib") } nifti.interpolate3d <- function(nim, x, y, z, t=1) { iX <- floor(x) iY <- floor(y) iZ <- floor(z) coex <- x-iX coey <- y-iY coez <- z-iZ if (iX <=0 || iY <= 0 || iZ <= 0 || iX+1 > nifti.image.getdim.save(nim,1) || iY+1 > nifti.image.getdim.save(nim,2) || iZ+1 > nifti.image.getdim.save(nim,3)) return(0) p1 <- (1-coex)*(1-coey)*(1-coez)*nim[iX,iY,iZ,t] p2 <- (1-coex)*(1-coey)*( coez)*nim[iX,iY,iZ+1,t] p3 <- (1-coex)*( coey)*(1-coez)*nim[iX,iY+1,iZ,t] p4 <- (1-coex)*( coey)*( coez)*nim[iX,iY+1,iZ+1,t] p5 <- ( coex)*(1-coey)*(1-coez)*nim[iX+1,iY,iZ,t] p6 <- ( coex)*(1-coey)*( coez)*nim[iX+1,iY,iZ+1,t] p7 <- ( coex)*( coey)*(1-coez)*nim[iX+1,iY+1,iZ,t] p8 <- ( coex)*( coey)*( coez)*nim[iX+1,iY+1,iZ+1,t] return(p1+p2+p3+p4+p5+p6+p7+p8) } # generic functions to integrate the nifti methods into R environment plot.nifti <- function(x, dim1=1:nifti.image.getdim.save(x,1), dim2=1:nifti.image.getdim.save(x,2), dim3=1, dim4=1,...) { image(dim1,dim2,x[dim1,dim2,dim3,dim4],col=gray(1:255/255),...) } print.nifti <- function(x, ...) { .Call("Rnifti_image_printinfo", x, PACKAGE="Rniftilib") } "dim.nifti" <- function(x) { .Call("Rnifti_image_getattribute", x, "dim", PACKAGE="Rniftilib") } "dim<-.nifti" <- function(x, value) { .Call("Rnifti_image_setattribute", x, "dim", value, PACKAGE="Rniftilib") } nifti.compiled.with.zlib <- function() { .Call("Rnifti_compiled_with_zlib", PACKAGE="Rniftilib") } nifti.disp.lib.version <- function() { .Call("Rnifti_disp_lib_version", PACKAGE="Rniftilib") } nifti.units.string <- function(value) { .Call("Rnifti_units_string", value, PACKAGE="Rniftilib") } nifti.datatype.string <- function(value) { .Call("Rnifti_datatype_string", value, PACKAGE="Rniftilib") } Rniftilib/R/FirstLib.R0000644000176000001440000000053311723252462014273 0ustar ripleyusers## FirstLib: initialization of Rniftilib ##.First.lib <- function(lib, pkg) ##{ ## library.dynam("Rniftilib", pkg, lib) ##} ## LastLib: cleanup of Rniftilib ##.Last.lib <- function(libpath) ##{ ## library.dynam.unload("Rniftilib", libpath) ##} .onLoad <- function(libname, pkgname) { .Call("Rnifti_init", libname, PACKAGE=pkgname) } Rniftilib/configure0000755000176000001440000046564611432314460014156 0ustar ripleyusers#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.63 for Rniftilib configuration script 0.0.30. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell bug-autoconf@gnu.org about your system, echo including any error possibly output before this message. echo This can help us improve future autoconf versions. echo Configuration will now proceed without shell functions. } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='Rniftilib configuration script' PACKAGE_TARNAME='rniftilib-configuration-script' PACKAGE_VERSION='0.0.30' PACKAGE_STRING='Rniftilib configuration script 0.0.30' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS INCLUDE LIBOBJS EGREP GREP CPP ac_ct_CC CFLAGS CC OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_zlib ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC CC CFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { $as_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { $as_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 { (exit 1); exit 1; }; } ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { $as_echo "$as_me: error: working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures Rniftilib configuration script 0.0.30 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/rniftilib-configuration-script] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of Rniftilib configuration script 0.0.30:";; esac cat <<\_ACEOF Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-zlib=DIR root directory path of zlib installation defaults to /usr/local or /usr if not found in /usr/local --without-zlib to disable zlib usage completely Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CC C compiler command CFLAGS C compiler flags CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF Rniftilib configuration script configure 0.0.30 generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by Rniftilib configuration script $as_me 0.0.30, which was generated by GNU Autoconf 2.63. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test -r "$ac_site_file"; then { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 $as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" : ${R_HOME=`R RHOME`} if test -z "${R_HOME}"; then echo "could not determine R_HOME" exit 1 fi CC=`"${R_HOME}/bin/R" CMD config CC` CFLAGS=`"${R_HOME}/bin/R" CMD config CFLAGS` CPPFLAGS=`"${R_HOME}/bin/R" CMD config CPPFLAGS` # Checks for programs. ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:$LINENO: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi { $as_echo "$as_me:$LINENO: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } if test -z "$ac_file"; then $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C++ compiler cannot create executables See \`config.log' for more details." >&5 $as_echo "$as_me: error: C++ compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi fi fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } { $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } { $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest$ac_cv_exeext { $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if test "${ac_cv_cxx_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Checks for header files. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:$LINENO: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:$LINENO: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # Checks for libraries. # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:$LINENO: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if test "${ac_cv_c_inline+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_inline=$ac_kw else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac # Checks for library functions. # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in stdlib.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 $as_echo_n "checking for GNU libc compatible malloc... " >&6; } if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then ac_cv_func_malloc_0_nonnull=no else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *malloc (); #endif int main () { return ! malloc (0); ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_malloc_0_nonnull=yes else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_malloc_0_nonnull=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 $as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } if test $ac_cv_func_malloc_0_nonnull = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_MALLOC 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define HAVE_MALLOC 0 _ACEOF case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; esac cat >>confdefs.h <<\_ACEOF #define malloc rpl_malloc _ACEOF fi # # Handle user hints # { $as_echo "$as_me:$LINENO: checking if zlib is wanted" >&5 $as_echo_n "checking if zlib is wanted... " >&6; } # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then withval=$with_zlib; if test "$withval" != no ; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } if test -d "$withval" then ZLIB_HOME="$withval" else { $as_echo "$as_me:$LINENO: WARNING: Sorry, $withval does not exist, checking usual places" >&5 $as_echo "$as_me: WARNING: Sorry, $withval does not exist, checking usual places" >&2;} fi else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi else { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } fi ZLIB_HOME=/usr/local if test ! -f "${ZLIB_HOME}/include/zlib.h" then ZLIB_HOME=/usr fi # # Locate zlib, if wanted # if test -n "${ZLIB_HOME}" then ZLIB_OLD_LDFLAGS=$LDFLAGS ZLIB_OLD_CPPFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib" CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:$LINENO: checking for inflateEnd in -lz" >&5 $as_echo_n "checking for inflateEnd in -lz... " >&6; } if test "${ac_cv_lib_z_inflateEnd+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inflateEnd (); int main () { return inflateEnd (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_z_inflateEnd=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_z_inflateEnd=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_z_inflateEnd" >&5 $as_echo "$ac_cv_lib_z_inflateEnd" >&6; } if test "x$ac_cv_lib_z_inflateEnd" = x""yes; then zlib_cv_libz=yes else zlib_cv_libz=no fi if test "${ac_cv_header_zlib_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for zlib.h" >&5 $as_echo_n "checking for zlib.h... " >&6; } if test "${ac_cv_header_zlib_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 $as_echo "$ac_cv_header_zlib_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking zlib.h usability" >&5 $as_echo_n "checking zlib.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking zlib.h presence" >&5 $as_echo_n "checking zlib.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { $as_echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: zlib.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: zlib.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: zlib.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: zlib.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: zlib.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: zlib.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: zlib.h: in the future, the compiler will take precedence" >&2;} ;; esac { $as_echo "$as_me:$LINENO: checking for zlib.h" >&5 $as_echo_n "checking for zlib.h... " >&6; } if test "${ac_cv_header_zlib_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_zlib_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 $as_echo "$ac_cv_header_zlib_h" >&6; } fi if test "x$ac_cv_header_zlib_h" = x""yes; then zlib_cv_zlib_h=yes else zlib_cv_zlib_h=no fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "$zlib_cv_libz" = "yes" -a "$zlib_cv_zlib_h" = "yes" then # # If both library and header were found, use them # { $as_echo "$as_me:$LINENO: checking for inflateEnd in -lz" >&5 $as_echo_n "checking for inflateEnd in -lz... " >&6; } if test "${ac_cv_lib_z_inflateEnd+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inflateEnd (); int main () { return inflateEnd (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_z_inflateEnd=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_z_inflateEnd=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_z_inflateEnd" >&5 $as_echo "$ac_cv_lib_z_inflateEnd" >&6; } if test "x$ac_cv_lib_z_inflateEnd" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBZ 1 _ACEOF LIBS="-lz $LIBS" fi { $as_echo "$as_me:$LINENO: checking zlib in ${ZLIB_HOME}" >&5 $as_echo_n "checking zlib in ${ZLIB_HOME}... " >&6; } { $as_echo "$as_me:$LINENO: result: ok" >&5 $as_echo "ok" >&6; } else # # If either header or library was not found, revert and bomb # { $as_echo "$as_me:$LINENO: checking zlib in ${ZLIB_HOME}" >&5 $as_echo_n "checking zlib in ${ZLIB_HOME}... " >&6; } LDFLAGS="$ZLIB_OLD_LDFLAGS" CPPFLAGS="$ZLIB_OLD_CPPFLAGS" { $as_echo "$as_me:$LINENO: result: failed" >&5 $as_echo "failed" >&6; } { { $as_echo "$as_me:$LINENO: error: either specify a valid zlib installation with --with-zlib=DIR or disable zlib usage with --without-zlib" >&5 $as_echo "$as_me: error: either specify a valid zlib installation with --with-zlib=DIR or disable zlib usage with --without-zlib" >&2;} { (exit 1); exit 1; }; } fi fi ac_config_files="$ac_config_files src/Makevars" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Rniftilib configuration script $as_me 0.0.30, which was generated by GNU Autoconf 2.63. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTION]... [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ Rniftilib configuration script config.status 0.0.30 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { $as_echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { $as_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "src/Makevars") CONFIG_FILES="$CONFIG_FILES src/Makevars" ;; *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { $as_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=' ' ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\).*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\).*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 $as_echo "$as_me: error: could not setup config files machinery" >&2;} { (exit 1); exit 1; }; } _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 $as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 $as_echo "$as_me: error: could not setup config headers machinery" >&2;} { (exit 1); exit 1; }; } fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 $as_echo "$as_me: error: invalid tag $ac_tag" >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 $as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ac_file_inputs="$ac_file_inputs '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 $as_echo "$as_me: error: could not create -" >&2;} { (exit 1); exit 1; }; } fi ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 $as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi