1 #define _NIFTI2_IO_C_
2 #define __STDC_FORMAT_MACROS
3
4 #include <cinttypes>
5 #include "nifti2_io.h" /* typedefs, prototypes, macros, etc. */
6
7 /*****===================================================================*****/
8 /***** Sample functions to deal with NIFTI-1,2 and ANALYZE files *****/
9 /*****...................................................................*****/
10 /***** This code is released to the public domain. *****/
11 /*****...................................................................*****/
12 /***** Author: Robert W Cox, SSCC/DIRP/NIMH/NIH/DHHS/USA/EARTH *****/
13 /***** Date: August 2003 *****/
14 /*****...................................................................*****/
15 /***** Neither the National Institutes of Health (NIH), nor any of its *****/
16 /***** employees imply any warranty of usefulness of this software for *****/
17 /***** any purpose, and do not assume any liability for damages, *****/
18 /***** incidental or otherwise, caused by any use of this document. *****/
19 /*****===================================================================*****/
20
21 /** \file nifti1_io.c
22 \brief main collection of nifti1 i/o routines
23 - written by Bob Cox, SSCC NIMH
24 - revised by Mark Jenkinson, FMRIB
25 - revised by Rick Reynolds, SSCC, NIMH
26 - revised by Kate Fissell, University of Pittsburgh
27
28 The library history can be viewed via "nifti_tool -nifti_hist".
29 <br>The library version can be viewed via "nifti_tool -nifti_ver".
30 */
31
32 namespace mirtk {
33
34
35 /*! global history and version strings, for printing */
36 static char const * const gni1_history[] =
37 {
38 "----------------------------------------------------------------------\n"
39 "history (of nifti library changes):\n"
40 "\n",
41 "0.0 August, 2003 [rwcox]\n"
42 " (Robert W Cox of the National Institutes of Health, SSCC/DIRP/NIMH)\n"
43 " - initial version\n"
44 "\n",
45 "0.1 July/August, 2004 [Mark Jenkinson]\n"
46 " (FMRIB Centre, University of Oxford, UK)\n"
47 " - Mainly adding low-level IO and changing things to allow gzipped\n"
48 " files to be read and written\n"
49 " - Full backwards compatability should have been maintained\n"
50 "\n",
51 "0.2 16 Nov 2004 [rickr]\n"
52 " (Rick Reynolds of the National Institutes of Health, SSCC/DIRP/NIMH)\n"
53 " - included Mark's changes in the AFNI distribution (including znzlib/)\n"
54 " (HAVE_ZLIB is commented out for the standard distribution)\n"
55 " - modified nifti_validfilename() and nifti_makebasename()\n"
56 " - added nifti_find_file_extension()\n"
57 "\n",
58 "0.3 3 Dec 2004 [rickr]\n"
59 " - note: header extensions are not yet checked for\n"
60 " - added formatted history as global string, for printing\n"
61 " - added nifti_disp_lib_hist(), to display the nifti library history\n"
62 " - added nifti_disp_lib_version(), to display the nifti library history\n",
63 " - re-wrote nifti_findhdrname()\n"
64 " o used nifti_find_file_extension()\n"
65 " o changed order of file tests (default is .nii, depends on input)\n"
66 " o free hdrname on failure\n"
67 " - made similar changes to nifti_findimgname()\n"
68 " - check for NULL return from nifti_findhdrname() calls\n",
69 " - removed most of ERREX() macros\n"
70 " - modified nifti_image_read()\n"
71 " o added debug info and error checking (on gni_debug > 0, only)\n"
72 " o fail if workingname is NULL\n"
73 " o check for failure to open header file\n"
74 " o free workingname on failure\n"
75 " o check for failure of nifti_image_load()\n"
76 " o check for failure of nifti_convert_nhdr2nim()\n",
77 " - changed nifti_image_load() to int, and check nifti_read_buffer return\n"
78 " - changed nifti_read_buffer() to fail on short read, and to count float\n"
79 " fixes (to print on debug)\n"
80 " - changed nifti_image_infodump to print to stderr\n"
81 " - updated function header comments, or moved comments above header\n"
82 " - removed const keyword\n"
83 " - added LNI_FERR() macro for error reporting on input files\n"
84 "\n",
85 "0.4 10 Dec 2004 [rickr] - added header extensions\n"
86 " - in nifti1_io.h:\n"
87 " o added num_ext and ext_list to the definition of nifti_image\n"
88 " o made many functions static (more to follow)\n"
89 " o added LNI_MAX_NIA_EXT_LEN, for max nifti_type 3 extension length\n",
90 " - added __DATE__ to version output in nifti_disp_lib_version()\n"
91 " - added nifti_disp_matrix_orient() to print orientation information\n"
92 " - added '.nia' as a valid file extension in nifti_find_file_extension()\n"
93 " - added much more debug output\n"
94 " - in nifti_image_read(), in the case of an ASCII header, check for\n"
95 " extensions after the end of the header\n",
96 " - added nifti_read_extensions() function\n"
97 " - added nifti_read_next_extension() function\n"
98 " - added nifti_add_exten_to_list() function\n"
99 " - added nifti_check_extension() function\n"
100 " - added nifti_write_extensions() function\n"
101 " - added nifti_extension_size() function\n"
102 " - in nifti_set_iname_offest():\n"
103 " o adjust offset by the extension size and the extender size\n",
104 " o fixed the 'ceiling modulo 16' computation\n"
105 " - in nifti_image_write_hdr_img2(): \n"
106 " o added extension writing\n"
107 " o check for NULL return from nifti_findimgname()\n"
108 " - include number of extensions in nifti_image_to_ascii() output\n"
109 " - in nifti_image_from_ascii():\n"
110 " o return bytes_read as a parameter, computed from the final spos\n"
111 " o extract num_ext from ASCII header\n"
112 "\n",
113 "0.5 14 Dec 2004 [rickr] - added sub-brick reading functions\n"
114 " - added nifti_brick_list type to nifti1_io.h, along with new prototypes\n"
115 " - added main nifti_image_read_bricks() function, with description\n"
116 " - added nifti_image_load_bricks() - library function (requires nim)\n"
117 " - added valid_nifti_brick_list() - library function\n"
118 " - added free_NBL() - library function\n",
119 " - added update_nifti_image_for_brick_list() for dimension update\n"
120 " - added nifti_load_NBL_bricks(), nifti_alloc_NBL_mem(),\n"
121 " nifti_copynsort() and force_positive() (static functions)\n"
122 " - in nifti_image_read(), check for failed load only if read_data is set\n"
123 " - broke most of nifti_image_load() into nifti_image_load_prep()\n"
124 "\n",
125 "0.6 15 Dec 2004 [rickr] - added sub-brick writing functionality\n"
126 " - in nifti1_io.h, removed znzlib directory from include - all nifti\n"
127 " library files are now under the nifti directory\n"
128 " - nifti_read_extensions(): print no offset warning for nifti_type 3\n"
129 " - nifti_write_all_data():\n"
130 " o pass nifti_brick_list * NBL, for optional writing\n"
131 " o if NBL, write each sub-brick, sequentially\n",
132 " - nifti_set_iname_offset(): case 1 must have sizeof() cast to int\n"
133 " - pass NBL to nifti_image_write_hdr_img2(), and allow NBL or data\n"
134 " - added nifti_image_write_bricks() wrapper for ...write_hdr_img2()\n"
135 " - included compression abilities\n"
136 "\n",
137 "0.7 16 Dec 2004 [rickr] - minor changes to extension reading\n"
138 "\n",
139 "0.8 21 Dec 2004 [rickr] - restrict extension reading, and minor changes\n"
140 " - in nifti_image_read(), compute bytes for extensions (see remaining)\n"
141 " - in nifti_read_extensions(), pass 'remain' as space for extensions,\n"
142 " pass it to nifti_read_next_ext(), and update for each one read \n"
143 " - in nifti_check_extension(), require (size <= remain)\n",
144 " - in update_nifti_image_brick_list(), update nvox\n"
145 " - in nifti_image_load_bricks(), make explicit check for nbricks <= 0\n"
146 " - in int_force_positive(), check for (!list)\n"
147 " - in swap_nifti_header(), swap sizeof_hdr, and reorder to struct order\n"
148 " - change get_filesize functions to signed ( < 0 is no file or error )\n",
149 " - in nifti_validfilename(), lose redundant (len < 0) check\n"
150 " - make print_hex_vals() static\n"
151 " - in disp_nifti_1_header, restrict string field widths\n"
152 "\n",
153 "0.9 23 Dec 2004 [rickr] - minor changes\n"
154 " - broke ASCII header reading out of nifti_image_read(), into new\n"
155 " functions has_ascii_header() and read_ascii_image()\n",
156 " - check image_read failure and znzseek failure\n"
157 " - altered some debug output\n"
158 " - nifti_write_all_data() now returns an int\n"
159 "\n",
160 "0.10 29 Dec 2004 [rickr]\n"
161 " - renamed nifti_valid_extension() to nifti_check_extension()\n"
162 " - added functions nifti_makehdrname() and nifti_makeimgname()\n"
163 " - added function valid_nifti_extensions()\n"
164 " - in nifti_write_extensions(), check for validity before writing\n",
165 " - rewrote nifti_image_write_hdr_img2():\n"
166 " o set write_data and leave_open flags from write_opts\n"
167 " o add debug print statements\n"
168 " o use nifti_write_ascii_image() for the ascii case\n"
169 " o rewrote the logic of all cases to be easier to follow\n",
170 " - broke out code as nifti_write_ascii_image() function\n"
171 " - added debug to top-level write functions, and free the znzFile\n"
172 " - removed unused internal function nifti_image_open()\n"
173 "\n",
174 "0.11 30 Dec 2004 [rickr] - small mods\n"
175 " - moved static function prototypes from header to C file\n"
176 " - free extensions in nifti_image_free()\n"
177 "\n",
178 "1.0 07 Jan 2005 [rickr] - INITIAL RELEASE VERSION\n"
179 " - added function nifti_set_filenames()\n"
180 " - added function nifti_read_header()\n"
181 " - added static function nhdr_looks_good()\n"
182 " - added static function need_nhdr_swap()\n"
183 " - exported nifti_add_exten_to_list symbol\n",
184 " - fixed #bytes written in nifti_write_extensions()\n"
185 " - only modify offset if it is too small (nifti_set_iname_offset)\n"
186 " - added nifti_type 3 to nifti_makehdrname and nifti_makeimgname\n"
187 " - added function nifti_set_filenames()\n"
188 "\n",
189 "1.1 07 Jan 2005 [rickr]\n"
190 " - in nifti_read_header(), swap if needed\n"
191 "\n",
192 "1.2 07 Feb 2005 [kate fissell c/o rickr] \n"
193 " - nifti1.h: added doxygen comments for main struct and #define groups\n"
194 " - nifti1_io.h: added doxygen comments for file and nifti_image struct\n"
195 " - nifti1_io.h: added doxygen comments for file and some functions\n"
196 " - nifti1_io.c: changed nifti_copy_nim_info to use memcpy\n"
197 "\n",
198 "1.3 09 Feb 2005 [rickr]\n"
199 " - nifti1.h: added doxygen comments for extension structs\n"
200 " - nifti1_io.h: put most #defines in #ifdef _NIFTI1_IO_C_ block\n"
201 " - added a doxygen-style description to every exported function\n"
202 " - added doxygen-style comments within some functions\n"
203 " - re-exported many znzFile functions that I had made static\n"
204 " - re-added nifti_image_open (sorry, Mark)\n"
205 " - every exported function now has 'nifti' in the name (19 functions)\n",
206 " - made sure every alloc() has a failure test\n"
207 " - added nifti_copy_extensions function, for use in nifti_copy_nim_info\n"
208 " - nifti_is_gzfile: added initial strlen test\n"
209 " - nifti_set_filenames: added set_byte_order parameter option\n"
210 " (it seems appropriate to set the BO when new files are associated)\n"
211 " - disp_nifti_1_header: prints to stdout (a.o.t. stderr), with fflush\n"
212 "\n",
213 "1.4 23 Feb 2005 [rickr] - sourceforge merge\n"
214 " - merged into the nifti_io CVS directory structure at sourceforge.net\n"
215 " - merged in 4 changes by Mark, and re-added his const keywords\n"
216 " - cast some pointers to (void *) for -pedantic compile option\n"
217 " - added nifti_free_extensions()\n"
218 "\n",
219 "1.5 02 Mar 2005 [rickr] - started nifti global options\n"
220 " - gni_debug is now g_opts.debug\n"
221 " - added validity check parameter to nifti_read_header\n"
222 " - need_nhdr_swap no longer does test swaps on the stack\n"
223 "\n",
224 "1.6 05 April 2005 [rickr] - validation and collapsed_image_read\n"
225 " - added nifti_read_collapsed_image(), an interface for reading partial\n"
226 " datasets, specifying a subset of array indices\n"
227 " - for read_collapsed_image, added static functions: rci_read_data(),\n"
228 " rci_alloc_mem(), and make_pivot_list()\n",
229 " - added nifti_nim_is_valid() to check for consistency (more to do)\n"
230 " - added nifti_nim_has_valid_dims() to do many dimensions tests\n"
231 "\n",
232 "1.7 08 April 2005 [rickr]\n"
233 " - added nifti_update_dims_from_array() - to update dimensions\n"
234 " - modified nifti_makehdrname() and nifti_makeimgname():\n"
235 " if prefix has a valid extension, use it (else make one up)\n"
236 " - added nifti_get_intlist - for making an array of ints\n"
237 " - fixed init of NBL->bsize in nifti_alloc_NBL_mem() {thanks, Bob}\n"
238 "\n",
239 "1.8 14 April 2005 [rickr]\n"
240 " - added nifti_set_type_from_names(), for nifti_set_filenames()\n"
241 " (only updates type if number of files does not match it)\n"
242 " - added is_valid_nifti_type(), just to be sure\n"
243 " - updated description of nifti_read_collapsed_image() for *data change\n"
244 " (if *data is already set, assume memory exists for results)\n"
245 " - modified rci_alloc_mem() to allocate only if *data is NULL\n"
246 "\n",
247 "1.9 19 April 2005 [rickr]\n"
248 " - added extension codes NIFTI_ECODE_COMMENT and NIFTI_ECODE_XCEDE\n"
249 " - added nifti_type codes NIFTI_MAX_ECODE and NIFTI_MAX_FTYPE\n"
250 " - added nifti_add_extension() {exported}\n"
251 " - added nifti_fill_extension() as a static function\n"
252 " - added nifti_is_valid_ecode() {exported}\n",
253 " - nifti_type values are now NIFTI_FTYPE_* file codes\n"
254 " - in nifti_read_extensions(), decrement 'remain' by extender size, 4\n"
255 " - in nifti_set_iname_offset(), case 1, update if offset differs\n"
256 " - only output '-d writing nifti file' if debug > 1\n"
257 "\n",
258 "1.10 10 May 2005 [rickr]\n"
259 " - files are read using ZLIB only if they end in '.gz'\n"
260 "\n",
261 "1.11 12 August 2005 [kate fissell]\n"
262 " - Kate's 0.2 release packaging, for sourceforge\n"
263 "\n",
264 "1.12 17 August 2005 [rickr] - comment (doxygen) updates\n"
265 " - updated comments for most functions (2 updates from Cinly Ooi)\n"
266 " - added nifti_type_and_names_match()\n"
267 "\n",
268 "1.12a 24 August 2005 [rickr] - remove all tabs from Clibs/*/*.[ch]\n",
269 "1.12b 25 August 2005 [rickr] - changes by Hans Johnson\n",
270 "1.13 25 August 2005 [rickr]\n",
271 " - finished changes by Hans for Insight\n"
272 " - added const in all appropraite parameter locations (30-40)\n"
273 " (any pointer referencing data that will not change)\n"
274 " - shortened all string constants below 509 character limit\n"
275 "1.14 28 October 2005 [HJohnson]\n",
276 " - use nifti_set_filenames() in nifti_convert_nhdr2nim()\n"
277 "1.15 02 November 2005 [rickr]\n",
278 " - added skip_blank_ext to nifti_global_options\n"
279 " - added nifti_set_skip_blank_ext(), to set option\n"
280 " - if skip_blank_ext and no extensions, do not read/write extender\n"
281 "1.16 18 November 2005 [rickr]\n",
282 " - removed any test or access of dim[i], i>dim[0]\n"
283 " - do not set pixdim for collapsed dims to 1.0, leave them as they are\n"
284 " - added magic and dim[i] tests in nifti_hdr_looks_good()\n"
285 " - added 2 size_t casts\n"
286 "1.17 22 November 2005 [rickr]\n",
287 " - in hdr->nim, for i > dim[0], pass 0 or 1, else set to 1\n"
288 "1.18 02 March 2006 [rickr]\n",
289 " - in nifti_alloc_NBL_mem(), fixed nt=0 case from 1.17 change\n"
290 "1.19 23 May 2006 [HJohnson,rickr]\n",
291 " - nifti_write_ascii_image(): free(hstr)\n"
292 " - nifti_copy_extensions(): clear num_ext and ext_list\n"
293 "1.20 27 Jun 2006 [rickr]\n",
294 " - nifti_findhdrname(): fixed assign of efirst to match stated logic\n"
295 " (problem found by Atle Bjørnerud)\n"
296 "1.21 05 Sep 2006 [rickr] update for nifticlib-0.4 release\n",
297 " - was reminded to actually add nifti_set_skip_blank_ext()\n"
298 " - init g_opts.skip_blank_ext to 0\n"
299 "1.22 01 Jun 2007 nifticlib-0.5 release\n",
300 "1.23 05 Jun 2007 nifti_add_exten_to_list: revert on failure, free old list\n"
301 "1.24 07 Jun 2007 nifti_copy_extensions: use esize-8 for data size\n"
302 "1.25 12 Jun 2007 [rickr] EMPTY_IMAGE creation\n",
303 " - added nifti_make_new_header() - to create from dims/dtype\n"
304 " - added nifti_make_new_nim() - to create from dims/dtype/fill\n"
305 " - added nifti_is_valid_datatype(), and more debug info\n",
306 "1.26 27 Jul 2007 [rickr] handle single volumes > 2^31 bytes (but < 2^32)\n",
307 "1.27 28 Jul 2007 [rickr] nim->nvox, NBL-bsize are now type size_t\n"
308 "1.28 30 Jul 2007 [rickr] size_t updates\n",
309 "1.29 08 Aug 2007 [rickr] for list, valid_nifti_brick_list requires 3 dims\n"
310 "1.30 08 Nov 2007 [Yaroslav/rickr]\n"
311 " - fix ARM struct alignment problem in byte-swapping routines\n",
312 "1.31 29 Nov 2007 [rickr] for nifticlib-1.0.0\n"
313 " - added nifti_datatype_to/from_string routines\n"
314 " - added DT_RGBA32/NIFTI_TYPE_RGBA32 datatype macros (2304)\n"
315 " - added NIFTI_ECODE_FREESURFER (14)\n",
316 "1.32 08 Dec 2007 [rickr]\n"
317 " - nifti_hdr_looks_good() allows ANALYZE headers (req. by V. Luccio)\n"
318 " - added nifti_datatype_is_valid()\n",
319 "1.33 05 Feb 2008 [hansj,rickr] - block nia.gz use\n"
320 "1.34 13 Jun 2008 [rickr] - added nifti_compiled_with_zlib()\n"
321 "1.35 03 Aug 2008 [rickr]\n",
322 " - deal with swapping, so that CPU type does not affect output\n"
323 " (motivated by C Burns)\n"
324 " - added nifti_analyze75 structure and nifti_swap_as_analyze()\n"
325 " - previous swap_nifti_header is saved as old_swap_nifti_header\n"
326 " - also swap UNUSED fields in nifti_1_header struct\n",
327 "1.36 07 Oct 2008 [rickr]\n",
328 " - added nifti_NBL_matches_nim() check for write_bricks()\n"
329 "1.37 10 Mar 2009 [rickr]\n",
330 " - H Johnson cast updates (06 Feb)\n"
331 " - added NIFTI_ECODE_PYPICKLE for PyNIfTI (06 Feb)\n"
332 " - added NIFTI_ECODEs 18-28 for the LONI MiND group\n"
333 "1.38 28 Apr 2009 [rickr]\n",
334 " - uppercase extensions are now valid (requested by M. Coursolle)\n"
335 " - nifti_set_allow_upper_fext controls this option (req by C. Ooi)\n"
336 "1.39 23 Jun 2009 [rickr]: added 4 checks of alloc() returns\n",
337 "1.40 16 Mar 2010 [rickr]: added NIFTI_ECODE_VOXBO for D. Kimberg\n",
338 "1.41 28 Apr 2010 [rickr]: added NIFTI_ECODE_CARET for J. Harwell\n",
339 "1.42 06 Jul 2010 [rickr]: trouble with large (gz) files\n",
340 " - noted/investigated by M Hanke and Y Halchenko\n"
341 " - fixed znzread/write, noting example by M Adler\n"
342 " - changed nifti_swap_* routines/calls to take size_t (6)\n"
343 "1.43 07 Jul 2010 [rickr]: fixed znzR/W to again return nmembers\n",
344 "1.44 19 Jul 2013 [rickr]: ITK compatibility updates from H Johnson\n",
345 "----------------------------------------------------------------------\n"
346 };
347
348 /* rcr - todo
349
350 - nifti_tool -copy_sform SFORM_DSET.nii -infile ORIG.nii -prefix PP
351 -copy_orient SFORM_DSET.nii -infile ORIG.nii -prefix PP
352
353 - check converting nim 2 n2hdr
354 - update for n2 (and/or split from n1)
355 - is_nifti_file (maybe use nifti_header_version), nifti_hdr_looks_good
356 - extensions
357 - nifti_make_new_n1_header: check that dims are small enough (<2^15)
358 - nifti_convert_nim2nhdr: rename to nim2n1hdr and write nim2n2hdr
359 (maybe have nifti_convert_nim2nhdr wrap current version)
360 - nifti_set_iname_offset: n2 update via nifti_type
361 - track use of nifti_type
362 - nifti_image_write_hdr_img2: write nifti_2_header
363 */
364
365 static char const * const gni2_history[] =
366 {
367 "----------------------------------------------------------------------\n"
368 "history (of nifti-2 library changes):\n"
369 "\n",
370 "2.00 02 Jan, 2014 [rickr]\n"
371 " Richard Reynolds of the National Institutes of Health, SSCC/DIRP/NIMH\n"
372 " - initial version - change types to 64-bit based on new nifti_image\n",
373 "2.01 04 Apr, 2014 [rickr]\n"
374 " - added functionality for both nifti-1 and -2 headers\n"
375 " (read/display/swap/convert2nim/make_new_n?_hdr)\n"
376 " - still needs much nifti-2 functionality\n",
377 "2.02 11 May, 2015 [rickr]\n"
378 " - added to repository 28 Apr, 2015\n"
379 " - nifti_read_header() now returns found header struct\n"
380 "2.03 23 Jul, 2015 [rickr]\n"
381 " - possibly alter dimensions on CIFTI read\n"
382 " - return N-1 headers in unknown version cases\n",
383 "2.04 05 Aug, 2015 [rickr]\n"
384 " - have writing try NIFTI-2 if NIFTI-1 seesm insufficient\n"
385 };
386
387 static const char gni_version[]
388 = "nifti-2 library version 2.04 (5 August, 2015)";
389
390 /*! global nifti options structure - init with defaults */
391 /* see 'option accessor functions' */
392 static nifti_global_options g_opts = {
393 1, /* debug level */
394 0, /* skip_blank_ext - skip extender if no extensions */
395 1, /* allow_upper_fext - allow uppercase file extensions */
396 0, /* alter_cifti - alter CIFTI dims to use nx,t,u,v*/
397 };
398
399 char nifti1_magic[4] = { 'n', '+', '1', '\0' };
400 char nifti2_magic[8] = { 'n', '+', '2', '\0', '\r', '\n', '\032', '\n' };
401
402 /*! global nifti types structure list (per type, ordered oldest to newest) */
403 static const nifti_type_ele nifti_type_list[] = {
404 /* type nbyper swapsize name */
405 { 0, 0, 0, "DT_UNKNOWN" },
406 { 0, 0, 0, "DT_NONE" },
407 { 1, 0, 0, "DT_BINARY" }, /* not usable */
408 { 2, 1, 0, "DT_UNSIGNED_CHAR" },
409 { 2, 1, 0, "DT_UINT8" },
410 { 2, 1, 0, "NIFTI_TYPE_UINT8" },
411 { 4, 2, 2, "DT_SIGNED_SHORT" },
412 { 4, 2, 2, "DT_INT16" },
413 { 4, 2, 2, "NIFTI_TYPE_INT16" },
414 { 8, 4, 4, "DT_SIGNED_INT" },
415 { 8, 4, 4, "DT_INT32" },
416 { 8, 4, 4, "NIFTI_TYPE_INT32" },
417 { 16, 4, 4, "DT_FLOAT" },
418 { 16, 4, 4, "DT_FLOAT32" },
419 { 16, 4, 4, "NIFTI_TYPE_FLOAT32" },
420 { 32, 8, 4, "DT_COMPLEX" },
421 { 32, 8, 4, "DT_COMPLEX64" },
422 { 32, 8, 4, "NIFTI_TYPE_COMPLEX64" },
423 { 64, 8, 8, "DT_DOUBLE" },
424 { 64, 8, 8, "DT_FLOAT64" },
425 { 64, 8, 8, "NIFTI_TYPE_FLOAT64" },
426 { 128, 3, 0, "DT_RGB" },
427 { 128, 3, 0, "DT_RGB24" },
428 { 128, 3, 0, "NIFTI_TYPE_RGB24" },
429 { 255, 0, 0, "DT_ALL" },
430 { 256, 1, 0, "DT_INT8" },
431 { 256, 1, 0, "NIFTI_TYPE_INT8" },
432 { 512, 2, 2, "DT_UINT16" },
433 { 512, 2, 2, "NIFTI_TYPE_UINT16" },
434 { 768, 4, 4, "DT_UINT32" },
435 { 768, 4, 4, "NIFTI_TYPE_UINT32" },
436 { 1024, 8, 8, "DT_INT64" },
437 { 1024, 8, 8, "NIFTI_TYPE_INT64" },
438 { 1280, 8, 8, "DT_UINT64" },
439 { 1280, 8, 8, "NIFTI_TYPE_UINT64" },
440 { 1536, 16, 16, "DT_FLOAT128" },
441 { 1536, 16, 16, "NIFTI_TYPE_FLOAT128" },
442 { 1792, 16, 8, "DT_COMPLEX128" },
443 { 1792, 16, 8, "NIFTI_TYPE_COMPLEX128" },
444 { 2048, 32, 16, "DT_COMPLEX256" },
445 { 2048, 32, 16, "NIFTI_TYPE_COMPLEX256" },
446 { 2304, 4, 0, "DT_RGBA32" },
447 { 2304, 4, 0, "NIFTI_TYPE_RGBA32" },
448 };
449
450 /*---------------------------------------------------------------------------*/
451 /* prototypes for internal functions - not part of exported library */
452
453 /* extension routines */
454 static int nifti_read_extensions(nifti_image *nim, znzFile fp, int64_t remain);
455 static int nifti_read_next_extension( nifti1_extension * nex, nifti_image *nim, int remain, znzFile fp );
456 static int nifti_check_extension(nifti_image *nim, int size,int code, int rem);
457 static void update_nifti_image_for_brick_list(nifti_image * nim,
458 int64_t nbricks);
459 static int nifti_add_exten_to_list(nifti1_extension * new_ext,
460 nifti1_extension ** list, int new_length);
461 static int nifti_fill_extension(nifti1_extension * ext, const char * data,
462 int len, int ecode);
463 static void compute_strides(int64_t *strides,const int64_t *size,int nbyper);
464
465 /* NBL routines */
466 static int nifti_load_NBL_bricks(nifti_image * nim , int64_t * slist,
467 int64_t * sindex, nifti_brick_list * NBL, znzFile fp );
468 static int nifti_alloc_NBL_mem( nifti_image * nim, int64_t nbricks,
469 nifti_brick_list * nbl);
470 static int nifti_copynsort(int64_t nbricks, const int64_t *blist,
471 int64_t **slist, int64_t **sindex);
472 static int nifti_NBL_matches_nim(const nifti_image *nim,
473 const nifti_brick_list *NBL);
474
475 /* for nifti_read_collapsed_image: */
476 static int rci_read_data(nifti_image *nim, int *pivots, int64_t *prods,
477 int nprods, const int64_t dims[], char *data,
478 znzFile fp, int64_t base_offset);
479 static int rci_alloc_mem(void **data, int64_t prods[8], int nprods, int nbyper);
480 static int make_pivot_list(nifti_image * nim, const int64_t dims[],
481 int pivots[], int64_t prods[], int * nprods );
482
483 /* misc */
484 static int compare_strlist (const char * str, char ** strlist, int len);
485 static int fileext_compare (const char * test_ext, const char * known_ext);
486 static int fileext_n_compare (const char * test_ext,
487 const char * known_ext, size_t maxlen);
488 static int is_mixedcase (const char * str);
489 static int is_uppercase (const char * str);
490 static int make_lowercase (char * str);
491 static int make_uppercase (char * str);
492 static int need_nhdr_swap (short dim0, int hdrsize);
493 static int print_hex_vals (const char * data, int nbytes, FILE * fp);
494 static int unescape_string (char *str); /* string utility functions */
495 static char *escapize_string (const char *str);
496
497 /* consider for export */
498 static int nifti_ext_type_index(nifti_image * nim, int ecode);
499
500 /* internal I/O routines */
501 static znzFile nifti_image_load_prep( nifti_image *nim );
502 static int has_ascii_header(znzFile fp);
503 /*---------------------------------------------------------------------------*/
504
505
506 /* for calling from some main program */
507
508 /*----------------------------------------------------------------------*/
509 /*! display the nifti library module history (via stdout)
510 *//*--------------------------------------------------------------------*/
nifti_disp_lib_hist(int ver)511 void nifti_disp_lib_hist( int ver )
512 {
513 int c, len;
514
515 switch ( ver ) {
516 default: {
517 fprintf(stderr,"** disp_lib_list: bad ver %d\n", ver);
518 break;
519 }
520
521 case 0:
522 case 2: {
523 len = sizeof(gni2_history)/sizeof(char *);
524 for( c = 0; c < len; c++ )
525 fputs(gni2_history[c], stdout);
526 break;
527 }
528 case 1: {
529 len = sizeof(gni1_history)/sizeof(char *);
530 for( c = 0; c < len; c++ )
531 fputs(gni1_history[c], stdout);
532 break;
533 }
534 }
535 }
536
537 /*----------------------------------------------------------------------*/
538 /*! display the nifti library version (via stdout)
539 *//*--------------------------------------------------------------------*/
nifti_disp_lib_version(void)540 void nifti_disp_lib_version( void )
541 {
542 printf("%s, compiled %s\n", gni_version, __DATE__);
543 }
544
545
546 /*----------------------------------------------------------------------*/
547 /*! nifti_image_read_bricks - read nifti data as array of bricks
548 *
549 * 13 Dec 2004 [rickr]
550 *
551 * \param hname - filename of dataset to read (must be valid)
552 * \param nbricks - number of sub-bricks to read
553 * (if blist is valid, nbricks must be > 0)
554 * \param blist - list of sub-bricks to read
555 * (can be NULL; if NULL, read complete dataset)
556 * \param NBL - pointer to empty nifti_brick_list struct
557 * (must be a valid pointer)
558 *
559 * \return
560 * <br> nim - same as nifti_image_read, but
561 * nim->nt = NBL->nbricks (or nt*nu*nv*nw)
562 * nim->nu,nv,nw = 1
563 * nim->data = NULL
564 * <br> NBL - filled with data volumes
565 *
566 * By default, this function will read the nifti dataset and break the data
567 * into a list of nt*nu*nv*nw sub-bricks, each having size nx*ny*nz elements.
568 * That is to say, instead of reading the entire dataset as a single array,
569 * break it up into sub-bricks (volumes), each of size nx*ny*nz elements.
570 *
571 * Note: in the returned nifti_image, nu, nv and nw will always be 1. The
572 * intention of this function is to collapse the dataset into a single
573 * array of volumes (of length nbricks or nt*nu*nv*nw).
574 *
575 * If 'blist' is valid, it is taken to be a list of sub-bricks, of length
576 * 'nbricks'. The data will still be separated into sub-bricks of size
577 * nx*ny*nz elements, but now 'nbricks' sub-bricks will be returned, of the
578 * caller's choosing via 'blist'.
579 *
580 * E.g. consider a dataset with 12 sub-bricks (numbered 0..11), and the
581 * following code:
582 *
583 * <pre>
584 * { nifti_brick_list NB_orig, NB_select;
585 * nifti_image * nim_orig, * nim_select;
586 * int blist[5] = { 7, 0, 5, 5, 9 };
587 *
588 * nim_orig = nifti_image_read_bricks("myfile.nii", 0, NULL, &NB_orig);
589 * nim_select = nifti_image_read_bricks("myfile.nii", 5, blist, &NB_select);
590 * }
591 * </pre>
592 *
593 * Here, nim_orig gets the entire dataset, where NB_orig.nbricks = 12. But
594 * nim_select has NB_select.nbricks = 5.
595 *
596 * Note that the first case is not quite the same as just calling the
597 * nifti_image_read function, as here the data is separated into sub-bricks.
598 *
599 * Note that valid blist elements are in [0..nt*nu*nv*nw-1],
600 * or written [ 0 .. (dim[4]*dim[5]*dim[6]*dim[7] - 1) ].
601 *
602 * Note that, as is the case with all of the reading functions, the
603 * data will be allocated, read in, and properly byte-swapped, if
604 * necessary.
605 *
606 * \sa nifti_image_load_bricks, nifti_free_NBL, valid_nifti_brick_list,
607 nifti_image_read
608 *//*----------------------------------------------------------------------*/
nifti_image_read_bricks(const char * hname,int64_t nbricks,const int64_t * blist,nifti_brick_list * NBL)609 nifti_image *nifti_image_read_bricks(const char * hname, int64_t nbricks,
610 const int64_t * blist, nifti_brick_list * NBL)
611 {
612 nifti_image * nim;
613
614 if( !hname || !NBL ){
615 fprintf(stderr,"** nifti_image_read_bricks: bad params (%p,%p)\n",
616 hname, (void *)NBL);
617 return NULL;
618 }
619
620 if( blist && nbricks <= 0 ){
621 fprintf(stderr,"** nifti_image_read_bricks: bad nbricks, %" PRId64 "\n", nbricks);
622 return NULL;
623 }
624
625 nim = nifti_image_read(hname, 0); /* read header, but not data */
626
627 if( !nim ) return NULL; /* errors were already printed */
628
629 /* if we fail, free image and return */
630 if( nifti_image_load_bricks(nim, nbricks, blist, NBL) <= 0 ){
631 nifti_image_free(nim);
632 return NULL;
633 }
634
635 if( blist ) update_nifti_image_for_brick_list(nim, nbricks);
636
637 return nim;
638 }
639
640
641 /*----------------------------------------------------------------------
642 * update_nifti_image_for_brick_list - update nifti_image
643 *
644 * When loading a specific brick list, the distinction between
645 * nt, nu, nv and nw is lost. So put everything in t, and set
646 * dim[0] = 4.
647 *----------------------------------------------------------------------*/
update_nifti_image_for_brick_list(nifti_image * nim,int64_t nbricks)648 static void update_nifti_image_for_brick_list( nifti_image * nim ,
649 int64_t nbricks )
650 {
651 int64_t ndim;
652
653 if( g_opts.debug > 2 ){
654 fprintf(stderr,"+d updating image dimensions for %" PRId64 " bricks in list\n",
655 nbricks);
656 fprintf(stderr," ndim = %" PRId64 "\n",nim->ndim);
657 fprintf(stderr," nx,ny,nz,nt,nu,nv,nw: (%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ")\n",
658 nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw);
659 }
660
661 nim->nt = nbricks;
662 nim->nu = nim->nv = nim->nw = 1;
663 nim->dim[4] = nbricks;
664 nim->dim[5] = nim->dim[6] = nim->dim[7] = 1;
665
666 /* compute nvox */
667 /* do not rely on dimensions above dim[0] 16 Nov 2005 [rickr] */
668 for( nim->nvox = 1, ndim = 1; ndim <= nim->dim[0]; ndim++ )
669 nim->nvox *= nim->dim[ndim];
670
671 /* update the dimensions to 4 or lower */
672 for( ndim = 4; (ndim > 1) && (nim->dim[ndim] <= 1); ndim-- )
673 ;
674
675 if( g_opts.debug > 2 ){
676 fprintf(stderr,"+d ndim = %" PRId64 " -> %" PRId64 "\n",nim->ndim, ndim);
677 fprintf(stderr," --> (%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ")\n",
678 nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw);
679 }
680
681 nim->dim[0] = nim->ndim = ndim;
682 }
683
684
685 /*----------------------------------------------------------------------*/
686 /*! nifti_update_dims_from_array - update nx, ny, ... from nim->dim[]
687
688 Fix all the dimension information, based on a new nim->dim[].
689
690 Note: we assume that dim[0] will not increase.
691
692 Check for updates to pixdim[], dx,..., nx,..., nvox, ndim, dim[0].
693 *//*--------------------------------------------------------------------*/
nifti_update_dims_from_array(nifti_image * nim)694 int nifti_update_dims_from_array( nifti_image * nim )
695 {
696 int c;
697 int64_t ndim;
698
699 if( !nim ){
700 fprintf(stderr,"** update_dims: missing nim\n");
701 return 1;
702 }
703
704 if( g_opts.debug > 2 ){
705 fprintf(stderr,"+d updating image dimensions given nim->dim:");
706 for( c = 0; c < 8; c++ ) fprintf(stderr," %" PRId64 "", nim->dim[c]);
707 fputc('\n',stderr);
708 }
709
710 /* verify dim[0] first */
711 if(nim->dim[0] < 1 || nim->dim[0] > 7){
712 fprintf(stderr,"** invalid dim[0], dim[] = ");
713 for( c = 0; c < 8; c++ ) fprintf(stderr," %" PRId64 "", nim->dim[c]);
714 fputc('\n',stderr);
715 return 1;
716 }
717
718 /* set nx, ny ..., dx, dy, ..., one by one */
719
720 /* less than 1, set to 1, else copy */
721 if(nim->dim[1] < 1) nim->nx = nim->dim[1] = 1;
722 else nim->nx = nim->dim[1];
723 nim->dx = nim->pixdim[1];
724
725 /* if undefined, or less than 1, set to 1 */
726 if(nim->dim[0] < 2 || (nim->dim[0] >= 2 && nim->dim[2] < 1))
727 nim->ny = nim->dim[2] = 1;
728 else
729 nim->ny = nim->dim[2];
730 /* copy delta values, in any case */
731 nim->dy = nim->pixdim[2];
732
733 if(nim->dim[0] < 3 || (nim->dim[0] >= 3 && nim->dim[3] < 1))
734 nim->nz = nim->dim[3] = 1;
735 else /* just copy vals from arrays */
736 nim->nz = nim->dim[3];
737 nim->dz = nim->pixdim[3];
738
739 if(nim->dim[0] < 4 || (nim->dim[0] >= 4 && nim->dim[4] < 1))
740 nim->nt = nim->dim[4] = 1;
741 else /* just copy vals from arrays */
742 nim->nt = nim->dim[4];
743 nim->dt = nim->pixdim[4];
744
745 if(nim->dim[0] < 5 || (nim->dim[0] >= 5 && nim->dim[5] < 1))
746 nim->nu = nim->dim[5] = 1;
747 else /* just copy vals from arrays */
748 nim->nu = nim->dim[5];
749 nim->du = nim->pixdim[5];
750
751 if(nim->dim[0] < 6 || (nim->dim[0] >= 6 && nim->dim[6] < 1))
752 nim->nv = nim->dim[6] = 1;
753 else /* just copy vals from arrays */
754 nim->nv = nim->dim[6];
755 nim->dv = nim->pixdim[6];
756
757 if(nim->dim[0] < 7 || (nim->dim[0] >= 7 && nim->dim[7] < 1))
758 nim->nw = nim->dim[7] = 1;
759 else /* just copy vals from arrays */
760 nim->nw = nim->dim[7];
761 nim->dw = nim->pixdim[7];
762
763 for( c = 1, nim->nvox = 1; c <= nim->dim[0]; c++ )
764 nim->nvox *= nim->dim[c];
765
766 /* compute ndim, assuming it can be no larger than the old one */
767 for( ndim = nim->dim[0]; (ndim > 1) && (nim->dim[ndim] <= 1); ndim-- )
768 ;
769
770 if( g_opts.debug > 2 ){
771 fprintf(stderr,"+d ndim = %" PRId64 " -> %" PRId64 "\n",nim->ndim, ndim);
772 fprintf(stderr," --> (%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ")\n",
773 nim->nx, nim->ny, nim->nz, nim->nt, nim->nu, nim->nv, nim->nw);
774 }
775
776 nim->dim[0] = nim->ndim = ndim;
777
778 return 0;
779 }
780
781
782 /*----------------------------------------------------------------------*/
783 /*! Load the image data from disk into an already-prepared image struct.
784 *
785 * \param nim - initialized nifti_image, without data
786 * \param nbricks - the length of blist (must be 0 if blist is NULL)
787 * \param blist - an array of xyz volume indices to read (can be NULL)
788 * \param NBL - pointer to struct where resulting data will be stored
789 *
790 * If blist is NULL, read all sub-bricks.
791 *
792 * \return the number of loaded bricks (NBL->nbricks),
793 * 0 on failure, < 0 on error
794 *
795 * NOTE: it is likely that another function will copy the data pointers
796 * out of NBL, in which case the only pointer the calling function
797 * will want to free is NBL->bricks (not each NBL->bricks[i]).
798 *//*--------------------------------------------------------------------*/
nifti_image_load_bricks(nifti_image * nim,int64_t nbricks,const int64_t * blist,nifti_brick_list * NBL)799 int nifti_image_load_bricks( nifti_image * nim , int64_t nbricks,
800 const int64_t * blist, nifti_brick_list * NBL )
801 {
802 int64_t * slist = NULL, * sindex = NULL;
803 int rv;
804 znzFile fp;
805
806 /* we can have blist == NULL */
807 if( !nim || !NBL ){
808 fprintf(stderr,"** nifti_image_load_bricks, bad params (%p,%p)\n",
809 (void *)nim, (void *)NBL);
810 return -1;
811 }
812
813 if( blist && nbricks <= 0 ){
814 if( g_opts.debug > 1 )
815 fprintf(stderr,"-d load_bricks: received blist with nbricks = %" PRId64 ","
816 "ignoring blist\n", nbricks);
817 blist = NULL; /* pretend nothing was passed */
818 }
819
820 if( blist && ! valid_nifti_brick_list(nim, nbricks, blist, g_opts.debug>0) )
821 return -1;
822
823 /* for efficiency, let's read the file in order */
824 if( blist && nifti_copynsort( nbricks, blist, &slist, &sindex ) != 0 )
825 return -1;
826
827 /* open the file and position the FILE pointer */
828 fp = nifti_image_load_prep( nim );
829 if( !fp ){
830 if( g_opts.debug > 0 )
831 fprintf(stderr,"** nifti_image_load_bricks, failed load_prep\n");
832 if( blist ){ free(slist); free(sindex); }
833 return -1;
834 }
835
836 /* this will flag to allocate defaults */
837 if( !blist ) nbricks = 0;
838 if( nifti_alloc_NBL_mem( nim, nbricks, NBL ) != 0 ){
839 if( blist ){ free(slist); free(sindex); }
840 znzclose(fp);
841 return -1;
842 }
843
844 rv = nifti_load_NBL_bricks(nim, slist, sindex, NBL, fp);
845
846 if( rv != 0 ){
847 nifti_free_NBL( NBL ); /* failure! */
848 NBL->nbricks = 0; /* repetative, but clear */
849 }
850
851 if( slist ){ free(slist); free(sindex); }
852
853 znzclose(fp);
854
855 return NBL->nbricks;
856 }
857
858
859 /*----------------------------------------------------------------------*/
860 /*! nifti_free_NBL - free all pointers and clear structure
861 *
862 * note: this does not presume to free the structure pointer
863 *//*--------------------------------------------------------------------*/
nifti_free_NBL(nifti_brick_list * NBL)864 void nifti_free_NBL( nifti_brick_list * NBL )
865 {
866 int c;
867
868 if( NBL->bricks ){
869 for( c = 0; c < NBL->nbricks; c++ )
870 if( NBL->bricks[c] ) free(NBL->bricks[c]);
871 free(NBL->bricks);
872 NBL->bricks = NULL;
873 }
874
875 NBL->bsize = NBL->nbricks = 0;
876 }
877
878
879 /*----------------------------------------------------------------------
880 * nifti_load_NBL_bricks - read the file data into the NBL struct
881 *
882 * return 0 on success, -1 on failure
883 *----------------------------------------------------------------------*/
nifti_load_NBL_bricks(nifti_image * nim,int64_t * slist,int64_t * sindex,nifti_brick_list * NBL,znzFile fp)884 static int nifti_load_NBL_bricks( nifti_image * nim , int64_t * slist,
885 int64_t * sindex, nifti_brick_list * NBL, znzFile fp )
886 {
887 int64_t oposn, fposn; /* orig and current file positions */
888 int64_t rv, test;
889 int64_t c;
890 int64_t prev, isrc, idest; /* previous/current sub-brick, and new index */
891
892 test = znztell(fp); /* store current file position */
893 if( test < 0 ){
894 fprintf(stderr,"** load bricks: ztell failed??\n");
895 return -1;
896 }
897 fposn = oposn = test;
898
899 /* first, handle the default case, no passed blist */
900 if( !slist ){
901 for( c = 0; c < NBL->nbricks; c++ ) {
902 rv = nifti_read_buffer(fp, NBL->bricks[c], NBL->bsize, nim);
903 if( rv != NBL->bsize ){
904 fprintf(stderr,"** load bricks: cannot read brick %" PRId64 " from '%s'\n",
905 c, nim->iname ? nim->iname : nim->fname);
906 return -1;
907 }
908 }
909 if( g_opts.debug > 1 )
910 fprintf(stderr,"+d read %" PRId64 " default %" PRId64 "-byte bricks from file %s\n",
911 NBL->nbricks, NBL->bsize,
912 nim->iname ? nim->iname:nim->fname );
913 return 0;
914 }
915
916 if( !sindex ){
917 fprintf(stderr,"** load_NBL_bricks: missing index list\n");
918 return -1;
919 }
920
921 prev = -1; /* use prev for previous sub-brick */
922 for( c = 0; c < NBL->nbricks; c++ ){
923 isrc = slist[c]; /* this is original brick index (c is new one) */
924 idest = sindex[c]; /* this is the destination index for this data */
925
926 /* if this sub-brick is not the previous, we must read from disk */
927 if( isrc != prev ){
928
929 /* if we are not looking at the correct sub-brick, scan forward */
930 if( fposn != (oposn + isrc*NBL->bsize) ){
931 fposn = oposn + isrc*NBL->bsize;
932 /* rcr - znz functions need to handle 64-bit cases, */
933 /* see setting _FILE_OFFSET_BITS */
934 if( znzseek(fp, fposn, SEEK_SET) < 0 ){
935 fprintf(stderr,"** failed to locate brick %" PRId64 " in file '%s'\n",
936 isrc, nim->iname ? nim->iname : nim->fname);
937 return -1;
938 }
939 }
940
941 /* only 10,000 lines later and we're actually reading something! */
942 rv = nifti_read_buffer(fp, NBL->bricks[idest], NBL->bsize, nim);
943 if( rv != NBL->bsize ){
944 fprintf(stderr,"** failed to read brick %" PRId64 " from file '%s'\n",
945 isrc, nim->iname ? nim->iname : nim->fname);
946 if( g_opts.debug > 1 )
947 fprintf(stderr," (read %" PRId64 " of %" PRId64 " bytes)\n", rv, NBL->bsize);
948 return -1;
949 }
950 fposn += NBL->bsize;
951 } else {
952 /* we have already read this sub-brick, just copy the previous one */
953 /* note that this works because they are sorted */
954 memcpy(NBL->bricks[idest], NBL->bricks[sindex[c-1]], NBL->bsize);
955 }
956
957 prev = isrc; /* in any case, note the now previous sub-brick */
958 }
959
960 return 0;
961 }
962
963
964 /*----------------------------------------------------------------------
965 * nifti_alloc_NBL_mem - allocate memory for bricks
966 *
967 * return 0 on success, -1 on failure
968 *----------------------------------------------------------------------*/
nifti_alloc_NBL_mem(nifti_image * nim,int64_t nbricks,nifti_brick_list * nbl)969 static int nifti_alloc_NBL_mem(nifti_image * nim, int64_t nbricks,
970 nifti_brick_list * nbl)
971 {
972 int64_t c;
973
974 /* if nbricks is not specified, use the default */
975 if( nbricks > 0 ) nbl->nbricks = nbricks;
976 else { /* I missed this one with the 1.17 change 02 Mar 2006 [rickr] */
977 nbl->nbricks = 1;
978 for( c = 4; c <= nim->ndim; c++ )
979 nbl->nbricks *= nim->dim[c];
980 }
981
982 nbl->bsize = nim->nx * nim->ny * nim->nz * nim->nbyper; /* bytes */
983 nbl->bricks = (void **)malloc(nbl->nbricks * sizeof(void *));
984
985 if( ! nbl->bricks ){
986 fprintf(stderr,"** NANM: failed to alloc %" PRId64 " void ptrs\n",nbricks);
987 return -1;
988 }
989
990 for( c = 0; c < nbl->nbricks; c++ ){
991 nbl->bricks[c] = (void *)malloc(nbl->bsize);
992 if( ! nbl->bricks[c] ){
993 fprintf(stderr,"** NANM: failed to alloc %" PRId64 " bytes for brick %" PRId64 "\n",
994 nbl->bsize, c);
995 /* so free and clear everything before returning */
996 while( c > 0 ){
997 c--;
998 free(nbl->bricks[c]);
999 }
1000 free(nbl->bricks);
1001 nbl->bricks = NULL;
1002 nbl->bsize = nbl->nbricks = 0;
1003 return -1;
1004 }
1005 }
1006
1007 if( g_opts.debug > 2 )
1008 fprintf(stderr,"+d NANM: alloc'd %" PRId64 " bricks of %" PRId64 " bytes for NBL\n",
1009 nbl->nbricks, nbl->bsize);
1010
1011 return 0;
1012 }
1013
1014
1015 /*----------------------------------------------------------------------
1016 * nifti_copynsort - copy int list, and sort with indices
1017 *
1018 * 1. duplicate the incoming list
1019 * 2. create an sindex list, and init with 0..nbricks-1
1020 * 3. do a slow insertion sort on the small slist, along with sindex list
1021 * 4. check results, just to be positive
1022 *
1023 * So slist is sorted, and sindex hold original positions.
1024 *
1025 * return 0 on success, -1 on failure
1026 *----------------------------------------------------------------------*/
nifti_copynsort(int64_t nbricks,const int64_t * blist,int64_t ** slist,int64_t ** sindex)1027 static int nifti_copynsort(int64_t nbricks, const int64_t *blist,
1028 int64_t ** slist, int64_t ** sindex)
1029 {
1030 int64_t * stmp, * itmp; /* for ease of typing/reading */
1031 int64_t c1, c2, spos, tmp;
1032
1033 *slist = (int64_t *)malloc(nbricks * sizeof(int64_t));
1034 *sindex = (int64_t *)malloc(nbricks * sizeof(int64_t));
1035
1036 if( !*slist || !*sindex ){
1037 fprintf(stderr,"** NCS: failed to alloc %" PRId64 " ints for sorting\n",nbricks);
1038 if(*slist) free(*slist); /* maybe one succeeded */
1039 if(*sindex) free(*sindex);
1040 return -1;
1041 }
1042
1043 /* init the lists */
1044 for( c1 = 0; c1 < nbricks; c1++ ) {
1045 (*slist)[c1] = blist[c1];
1046 (*sindex)[c1] = c1;
1047 }
1048
1049 /* now actually sort slist */
1050 stmp = *slist;
1051 itmp = *sindex;
1052 for( c1 = 0; c1 < nbricks-1; c1++ ) {
1053 /* find smallest value, init to current */
1054 spos = c1;
1055 for( c2 = c1+1; c2 < nbricks; c2++ )
1056 if( stmp[c2] < stmp[spos] ) spos = c2;
1057 if( spos != c1 ) /* swap: fine, don't maintain sub-order, see if I care */
1058 {
1059 tmp = stmp[c1]; /* first swap the sorting values */
1060 stmp[c1] = stmp[spos];
1061 stmp[spos] = tmp;
1062
1063 tmp = itmp[c1]; /* then swap the index values */
1064 itmp[c1] = itmp[spos];
1065 itmp[spos] = tmp;
1066 }
1067 }
1068
1069 if( g_opts.debug > 2 ){
1070 fprintf(stderr, "+d sorted indexing list:\n");
1071 fprintf(stderr, " orig : ");
1072 for( c1 = 0; c1 < nbricks; c1++ ) fprintf(stderr," %" PRId64 "",blist[c1]);
1073 fprintf(stderr,"\n new : ");
1074 for( c1 = 0; c1 < nbricks; c1++ ) fprintf(stderr," %" PRId64 "",stmp[c1]);
1075 fprintf(stderr,"\n indices: ");
1076 for( c1 = 0; c1 < nbricks; c1++ ) fprintf(stderr," %" PRId64 "",itmp[c1]);
1077 fputc('\n', stderr);
1078 }
1079
1080 /* check the sort (why not? I've got time...) */
1081 for( c1 = 0; c1 < nbricks-1; c1++ ){
1082 if( (stmp[c1] > stmp[c1+1]) || (blist[itmp[c1]] != stmp[c1]) ){
1083 fprintf(stderr,"** sorting screw-up, way to go, rick!\n");
1084 free(stmp); free(itmp); *slist = NULL; *sindex = NULL;
1085 return -1;
1086 }
1087 }
1088
1089 if( g_opts.debug > 2 ) fprintf(stderr,"-d sorting is okay\n");
1090
1091 return 0;
1092 }
1093
1094
1095 /*----------------------------------------------------------------------*/
1096 /*! valid_nifti_brick_list - check sub-brick list for image
1097 *
1098 * This function verifies that nbricks and blist are appropriate
1099 * for use with this nim, based on the dimensions.
1100 *
1101 * \param nim nifti_image to check against
1102 * \param nbricks number of brick indices in blist
1103 * \param blist list of brick indices to check in nim
1104 * \param disp_error if this flag is set, report errors to user
1105 *
1106 * \return 1 if valid, 0 if not
1107 *//*--------------------------------------------------------------------*/
valid_nifti_brick_list(nifti_image * nim,int64_t nbricks,const int64_t * blist,int disp_error)1108 int valid_nifti_brick_list(nifti_image * nim , int64_t nbricks,
1109 const int64_t * blist, int disp_error)
1110 {
1111 int64_t c, nsubs;
1112
1113 if( !nim ){
1114 if( disp_error || g_opts.debug > 0 )
1115 fprintf(stderr,"** valid_nifti_brick_list: missing nifti image\n");
1116 return 0;
1117 }
1118
1119 if( nbricks <= 0 || !blist ){
1120 if( disp_error || g_opts.debug > 1 )
1121 fprintf(stderr,"** valid_nifti_brick_list: no brick list to check\n");
1122 return 0;
1123 }
1124
1125 if( nim->dim[0] < 3 ){
1126 if( disp_error || g_opts.debug > 1 )
1127 fprintf(stderr,"** cannot read explict brick list from %" PRId64 "-D dataset\n",
1128 nim->dim[0]);
1129 return 0;
1130 }
1131
1132 /* nsubs sub-brick is nt*nu*nv*nw */
1133 for( c = 4, nsubs = 1; c <= nim->dim[0]; c++ )
1134 nsubs *= nim->dim[c];
1135
1136 if( nsubs <= 0 ){
1137 fprintf(stderr,"** VNBL warning: bad dim list (%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ")\n",
1138 nim->dim[4], nim->dim[5], nim->dim[6], nim->dim[7]);
1139 return 0;
1140 }
1141
1142 for( c = 0; c < nbricks; c++ )
1143 if( (blist[c] < 0) || (blist[c] >= nsubs) ){
1144 if( disp_error || g_opts.debug > 1 )
1145 fprintf(stderr,
1146 "** volume index %" PRId64 " (#%" PRId64 ") is out of range [0,%" PRId64 "]\n",
1147 blist[c], c, nsubs-1);
1148 return 0;
1149 }
1150
1151 return 1; /* all is well */
1152 }
1153
1154 /*----------------------------------------------------------------------*/
1155 /* verify that NBL struct is a valid data source for the image
1156 *
1157 * return 1 if so, 0 otherwise
1158 *//*--------------------------------------------------------------------*/
nifti_NBL_matches_nim(const nifti_image * nim,const nifti_brick_list * NBL)1159 static int nifti_NBL_matches_nim(const nifti_image *nim,
1160 const nifti_brick_list *NBL)
1161 {
1162 int64_t volbytes = 0; /* bytes per volume */
1163 int64_t nvols = 0;
1164 int ind, errs = 0;
1165
1166
1167 if( !nim || !NBL ) {
1168 if( g_opts.debug > 0 )
1169 fprintf(stderr,"** nifti_NBL_matches_nim: NULL pointer(s)\n");
1170 return 0;
1171 }
1172
1173 /* for nim, compute volbytes and nvols */
1174 if( nim->ndim > 0 ) {
1175 /* first 3 indices are over a single volume */
1176 volbytes = (int64_t)nim->nbyper;
1177 for( ind = 1; ind <= nim->ndim && ind < 4; ind++ )
1178 volbytes *= nim->dim[ind];
1179
1180 for( ind = 4, nvols = 1; ind <= nim->ndim; ind++ )
1181 nvols *= nim->dim[ind];
1182 }
1183
1184 if( volbytes != NBL->bsize ) {
1185 if( g_opts.debug > 1 )
1186 fprintf(stderr,"** NBL/nim mismatch, volbytes = %" PRId64 ", %" PRId64 "\n",
1187 NBL->bsize, volbytes);
1188 errs++;
1189 }
1190
1191 if( nvols != NBL->nbricks ) {
1192 if( g_opts.debug > 1 )
1193 fprintf(stderr,"** NBL/nim mismatch, nvols = %" PRId64 ", %" PRId64 "\n",
1194 NBL->nbricks, nvols);
1195 errs++;
1196 }
1197
1198 if( errs ) return 0;
1199 else if ( g_opts.debug > 2 )
1200 fprintf(stderr,"-- nim/NBL agree: nvols = %" PRId64 ", nbytes = %" PRId64 "\n",
1201 nvols, volbytes);
1202
1203 return 1;
1204 }
1205
1206 /* end of new nifti_image_read_bricks() functionality */
1207
1208 /*----------------------------------------------------------------------*/
1209 /*! display the orientation from the quaternian fields
1210 *
1211 * \param mesg if non-NULL, display this message first
1212 * \param mat the matrix to convert to "nearest" orientation
1213 *
1214 * \return -1 if results cannot be determined, 0 if okay
1215 *//*--------------------------------------------------------------------*/
nifti_disp_matrix_orient(const char * mesg,nifti_dmat44 mat)1216 int nifti_disp_matrix_orient( const char * mesg, nifti_dmat44 mat )
1217 {
1218 int i, j, k;
1219
1220 if ( mesg ) fputs( mesg, stderr ); /* use stdout? */
1221
1222 nifti_dmat44_to_orientation( mat, &i,&j,&k );
1223 if ( i <= 0 || j <= 0 || k <= 0 ) return -1;
1224
1225 /* so we have good codes */
1226 fprintf(stderr, " i orientation = '%s'\n"
1227 " j orientation = '%s'\n"
1228 " k orientation = '%s'\n",
1229 nifti_orientation_string(i),
1230 nifti_orientation_string(j),
1231 nifti_orientation_string(k) );
1232 return 0;
1233 }
1234
1235
1236 /*----------------------------------------------------------------------*/
1237 /*! duplicate the given string (alloc length+1)
1238 *
1239 * \return allocated pointer (or NULL on failure)
1240 *//*--------------------------------------------------------------------*/
nifti_strdup(const char * str)1241 char *nifti_strdup(const char *str)
1242 {
1243 char *dup;
1244
1245 if( !str ) return NULL; /* allow calls passing NULL */
1246
1247 dup = (char *)malloc(strlen(str) + 1);
1248
1249 /* check for failure */
1250 if( dup ) strcpy(dup, str);
1251 else fprintf(stderr,"** nifti_strdup: failed to alloc %" PRId64 " bytes\n",
1252 (int64_t)(strlen(str)+1));
1253
1254 return dup;
1255 }
1256
1257
1258 /*---------------------------------------------------------------------------*/
1259 /*! Return a pointer to a string holding the name of a NIFTI datatype.
1260
1261 \param dt NIfTI-1 datatype
1262
1263 \return pointer to static string holding the datatype name
1264
1265 \warning Do not free() or modify this string!
1266 It points to static storage.
1267
1268 \sa NIFTI1_DATATYPES group in nifti1.h
1269 *//*-------------------------------------------------------------------------*/
nifti_datatype_string(int dt)1270 char const * nifti_datatype_string( int dt )
1271 {
1272 switch( dt ){
1273 case DT_UNKNOWN: return "UNKNOWN" ;
1274 case DT_BINARY: return "BINARY" ;
1275 case DT_INT8: return "INT8" ;
1276 case DT_UINT8: return "UINT8" ;
1277 case DT_INT16: return "INT16" ;
1278 case DT_UINT16: return "UINT16" ;
1279 case DT_INT32: return "INT32" ;
1280 case DT_UINT32: return "UINT32" ;
1281 case DT_INT64: return "INT64" ;
1282 case DT_UINT64: return "UINT64" ;
1283 case DT_FLOAT32: return "FLOAT32" ;
1284 case DT_FLOAT64: return "FLOAT64" ;
1285 case DT_FLOAT128: return "FLOAT128" ;
1286 case DT_COMPLEX64: return "COMPLEX64" ;
1287 case DT_COMPLEX128: return "COMPLEX128" ;
1288 case DT_COMPLEX256: return "COMPLEX256" ;
1289 case DT_RGB24: return "RGB24" ;
1290 case DT_RGBA32: return "RGBA32" ;
1291 }
1292 return "**ILLEGAL**" ;
1293 }
1294
1295 /*----------------------------------------------------------------------*/
1296 /*! Determine if the datatype code dt is an integer type (1=YES, 0=NO).
1297
1298 \return whether the given NIfTI-1 datatype code is valid
1299
1300 \sa NIFTI1_DATATYPES group in nifti1.h
1301 *//*--------------------------------------------------------------------*/
nifti_is_inttype(int dt)1302 int nifti_is_inttype( int dt )
1303 {
1304 switch( dt ){
1305 case DT_UNKNOWN: return 0 ;
1306 case DT_BINARY: return 0 ;
1307 case DT_INT8: return 1 ;
1308 case DT_UINT8: return 1 ;
1309 case DT_INT16: return 1 ;
1310 case DT_UINT16: return 1 ;
1311 case DT_INT32: return 1 ;
1312 case DT_UINT32: return 1 ;
1313 case DT_INT64: return 1 ;
1314 case DT_UINT64: return 1 ;
1315 case DT_FLOAT32: return 0 ;
1316 case DT_FLOAT64: return 0 ;
1317 case DT_FLOAT128: return 0 ;
1318 case DT_COMPLEX64: return 0 ;
1319 case DT_COMPLEX128: return 0 ;
1320 case DT_COMPLEX256: return 0 ;
1321 case DT_RGB24: return 1 ;
1322 case DT_RGBA32: return 1 ;
1323 }
1324 return 0 ;
1325 }
1326
1327 /*---------------------------------------------------------------------------*/
1328 /*! Return a pointer to a string holding the name of a NIFTI units type.
1329
1330 \param uu NIfTI-1 unit code
1331
1332 \return pointer to static string for the given unit type
1333
1334 \warning Do not free() or modify this string!
1335 It points to static storage.
1336
1337 \sa NIFTI1_UNITS group in nifti1.h
1338 *//*-------------------------------------------------------------------------*/
nifti_units_string(int uu)1339 char const *nifti_units_string( int uu )
1340 {
1341 switch( uu ){
1342 case NIFTI_UNITS_METER: return "m" ;
1343 case NIFTI_UNITS_MM: return "mm" ;
1344 case NIFTI_UNITS_MICRON: return "um" ;
1345 case NIFTI_UNITS_SEC: return "s" ;
1346 case NIFTI_UNITS_MSEC: return "ms" ;
1347 case NIFTI_UNITS_USEC: return "us" ;
1348 case NIFTI_UNITS_HZ: return "Hz" ;
1349 case NIFTI_UNITS_PPM: return "ppm" ;
1350 case NIFTI_UNITS_RADS: return "rad/s" ;
1351 }
1352 return "Unknown" ;
1353 }
1354
1355 /*---------------------------------------------------------------------------*/
1356 /*! Return a pointer to a string holding the name of a NIFTI transform type.
1357
1358 \param xx NIfTI-1 xform code
1359
1360 \return pointer to static string describing xform code
1361
1362 \warning Do not free() or modify this string!
1363 It points to static storage.
1364
1365 \sa NIFTI1_XFORM_CODES group in nifti1.h
1366 *//*-------------------------------------------------------------------------*/
nifti_xform_string(int xx)1367 char const *nifti_xform_string( int xx )
1368 {
1369 switch( xx ){
1370 case NIFTI_XFORM_SCANNER_ANAT: return "Scanner Anat" ;
1371 case NIFTI_XFORM_ALIGNED_ANAT: return "Aligned Anat" ;
1372 case NIFTI_XFORM_TALAIRACH: return "Talairach" ;
1373 case NIFTI_XFORM_MNI_152: return "MNI_152" ;
1374 }
1375 return "Unknown" ;
1376 }
1377
1378 /*---------------------------------------------------------------------------*/
1379 /*! Return a pointer to a string holding the name of a NIFTI intent type.
1380
1381 \param ii NIfTI-1 intent code
1382
1383 \return pointer to static string describing code
1384
1385 \warning Do not free() or modify this string!
1386 It points to static storage.
1387
1388 \sa NIFTI1_INTENT_CODES group in nifti1.h
1389 *//*-------------------------------------------------------------------------*/
nifti_intent_string(int ii)1390 char const *nifti_intent_string( int ii )
1391 {
1392 switch( ii ){
1393 case NIFTI_INTENT_CORREL: return "Correlation statistic" ;
1394 case NIFTI_INTENT_TTEST: return "T-statistic" ;
1395 case NIFTI_INTENT_FTEST: return "F-statistic" ;
1396 case NIFTI_INTENT_ZSCORE: return "Z-score" ;
1397 case NIFTI_INTENT_CHISQ: return "Chi-squared distribution" ;
1398 case NIFTI_INTENT_BETA: return "Beta distribution" ;
1399 case NIFTI_INTENT_BINOM: return "Binomial distribution" ;
1400 case NIFTI_INTENT_GAMMA: return "Gamma distribution" ;
1401 case NIFTI_INTENT_POISSON: return "Poisson distribution" ;
1402 case NIFTI_INTENT_NORMAL: return "Normal distribution" ;
1403 case NIFTI_INTENT_FTEST_NONC: return "F-statistic noncentral" ;
1404 case NIFTI_INTENT_CHISQ_NONC: return "Chi-squared noncentral" ;
1405 case NIFTI_INTENT_LOGISTIC: return "Logistic distribution" ;
1406 case NIFTI_INTENT_LAPLACE: return "Laplace distribution" ;
1407 case NIFTI_INTENT_UNIFORM: return "Uniform distribition" ;
1408 case NIFTI_INTENT_TTEST_NONC: return "T-statistic noncentral" ;
1409 case NIFTI_INTENT_WEIBULL: return "Weibull distribution" ;
1410 case NIFTI_INTENT_CHI: return "Chi distribution" ;
1411 case NIFTI_INTENT_INVGAUSS: return "Inverse Gaussian distribution" ;
1412 case NIFTI_INTENT_EXTVAL: return "Extreme Value distribution" ;
1413 case NIFTI_INTENT_PVAL: return "P-value" ;
1414
1415 case NIFTI_INTENT_LOGPVAL: return "Log P-value" ;
1416 case NIFTI_INTENT_LOG10PVAL: return "Log10 P-value" ;
1417
1418 case NIFTI_INTENT_ESTIMATE: return "Estimate" ;
1419 case NIFTI_INTENT_LABEL: return "Label index" ;
1420 case NIFTI_INTENT_NEURONAME: return "NeuroNames index" ;
1421 case NIFTI_INTENT_GENMATRIX: return "General matrix" ;
1422 case NIFTI_INTENT_SYMMATRIX: return "Symmetric matrix" ;
1423 case NIFTI_INTENT_DISPVECT: return "Displacement vector" ;
1424 case NIFTI_INTENT_VECTOR: return "Vector" ;
1425 case NIFTI_INTENT_POINTSET: return "Pointset" ;
1426 case NIFTI_INTENT_TRIANGLE: return "Triangle" ;
1427 case NIFTI_INTENT_QUATERNION: return "Quaternion" ;
1428
1429 case NIFTI_INTENT_DIMLESS: return "Dimensionless number" ;
1430 }
1431 return "Unknown" ;
1432 }
1433
1434 /*---------------------------------------------------------------------------*/
1435 /*! Return a pointer to a string holding the name of a NIFTI slice_code.
1436
1437 \param ss NIfTI-1 slice order code
1438
1439 \return pointer to static string describing code
1440
1441 \warning Do not free() or modify this string!
1442 It points to static storage.
1443
1444 \sa NIFTI1_SLICE_ORDER group in nifti1.h
1445 *//*-------------------------------------------------------------------------*/
nifti_slice_string(int ss)1446 char const *nifti_slice_string( int ss )
1447 {
1448 switch( ss ){
1449 case NIFTI_SLICE_SEQ_INC: return "sequential_increasing" ;
1450 case NIFTI_SLICE_SEQ_DEC: return "sequential_decreasing" ;
1451 case NIFTI_SLICE_ALT_INC: return "alternating_increasing" ;
1452 case NIFTI_SLICE_ALT_DEC: return "alternating_decreasing" ;
1453 case NIFTI_SLICE_ALT_INC2: return "alternating_increasing_2" ;
1454 case NIFTI_SLICE_ALT_DEC2: return "alternating_decreasing_2" ;
1455 }
1456 return "Unknown" ;
1457 }
1458
1459 /*---------------------------------------------------------------------------*/
1460 /*! Return a pointer to a string holding the name of a NIFTI orientation.
1461
1462 \param ii orientation code
1463
1464 \return pointer to static string holding the orientation information
1465
1466 \warning Do not free() or modify the return string!
1467 It points to static storage.
1468
1469 \sa NIFTI_L2R in nifti1_io.h
1470 *//*-------------------------------------------------------------------------*/
nifti_orientation_string(int ii)1471 char const *nifti_orientation_string( int ii )
1472 {
1473 switch( ii ){
1474 case NIFTI_L2R: return "Left-to-Right" ;
1475 case NIFTI_R2L: return "Right-to-Left" ;
1476 case NIFTI_P2A: return "Posterior-to-Anterior" ;
1477 case NIFTI_A2P: return "Anterior-to-Posterior" ;
1478 case NIFTI_I2S: return "Inferior-to-Superior" ;
1479 case NIFTI_S2I: return "Superior-to-Inferior" ;
1480 }
1481 return "Unknown" ;
1482 }
1483
1484 /*--------------------------------------------------------------------------*/
1485 /*! Given a datatype code, set number of bytes per voxel and the swapsize.
1486
1487 \param datatype nifti1 datatype code
1488 \param nbyper pointer to return value: number of bytes per voxel
1489 \param swapsize pointer to return value: size of swap blocks
1490
1491 \return appropriate values at nbyper and swapsize
1492
1493 The swapsize is set to 0 if this datatype doesn't ever need swapping.
1494
1495 \sa NIFTI1_DATATYPES in nifti1.h
1496 *//*------------------------------------------------------------------------*/
nifti_datatype_sizes(int datatype,int * nbyper,int * swapsize)1497 void nifti_datatype_sizes( int datatype , int *nbyper, int *swapsize )
1498 {
1499 int nb=0, ss=0 ;
1500 switch( datatype ){
1501 case DT_INT8:
1502 case DT_UINT8: nb = 1 ; ss = 0 ; break ;
1503
1504 case DT_INT16:
1505 case DT_UINT16: nb = 2 ; ss = 2 ; break ;
1506
1507 case DT_RGB24: nb = 3 ; ss = 0 ; break ;
1508 case DT_RGBA32: nb = 4 ; ss = 0 ; break ;
1509
1510 case DT_INT32:
1511 case DT_UINT32:
1512 case DT_FLOAT32: nb = 4 ; ss = 4 ; break ;
1513
1514 case DT_COMPLEX64: nb = 8 ; ss = 4 ; break ;
1515
1516 case DT_FLOAT64:
1517 case DT_INT64:
1518 case DT_UINT64: nb = 8 ; ss = 8 ; break ;
1519
1520 case DT_FLOAT128: nb = 16 ; ss = 16 ; break ;
1521
1522 case DT_COMPLEX128: nb = 16 ; ss = 8 ; break ;
1523
1524 case DT_COMPLEX256: nb = 32 ; ss = 16 ; break ;
1525 }
1526
1527 ASSIF(nbyper,nb) ; ASSIF(swapsize,ss) ; return ;
1528 }
1529
1530
1531 /*-----------------------------------------------------------------*/
1532 /*! copy between float and double mat44 types 10 Jul, 2015 [rickr] */
1533
nifti_mat44_to_dmat44(mat44 * fm,nifti_dmat44 * dm)1534 int nifti_mat44_to_dmat44(mat44 * fm, nifti_dmat44 * dm)
1535 {
1536 int i, j;
1537 if( !dm || !fm ) return 1;
1538 for( i=0; i<4; i++ )
1539 for( j=0; j<4; j++ )
1540 dm->m[i][j] = (double)fm->m[i][j];
1541 return 0;
1542 }
1543
nifti_dmat44_to_mat44(nifti_dmat44 * dm,mat44 * fm)1544 int nifti_dmat44_to_mat44(nifti_dmat44 * dm, mat44 * fm)
1545 {
1546 int i, j;
1547 if( !dm || !fm ) return 1;
1548 for( i=0; i<4; i++ )
1549 for( j=0; j<4; j++ )
1550 fm->m[i][j] = (float)dm->m[i][j];
1551 return 0;
1552 }
1553
1554
1555 /*---------------------------------------------------------------------------*/
1556 /*! Given the quaternion parameters (etc.), compute a transformation matrix
1557 of doubles.
1558
1559 See comments in nifti1.h for details.
1560 - qb,qc,qd = quaternion parameters
1561 - qx,qy,qz = offset parameters
1562 - dx,dy,dz = grid stepsizes (non-negative inputs are set to 1.0)
1563 - qfac = sign of dz step (< 0 is negative; >= 0 is positive)
1564
1565 <pre>
1566 If qx=qy=qz=0, dx=dy=dz=1, then the output is a rotation matrix.
1567 For qfac >= 0, the rotation is proper.
1568 For qfac < 0, the rotation is improper.
1569 </pre>
1570
1571 \see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h
1572 \see nifti_mat44_to_quatern, nifti_make_orthog_mat44,
1573 nifti_mat44_to_orientation
1574
1575 *//*-------------------------------------------------------------------------*/
nifti_quatern_to_dmat44(double qb,double qc,double qd,double qx,double qy,double qz,double dx,double dy,double dz,double qfac)1576 nifti_dmat44 nifti_quatern_to_dmat44( double qb, double qc, double qd,
1577 double qx, double qy, double qz,
1578 double dx, double dy, double dz, double qfac )
1579 {
1580 nifti_dmat44 R ;
1581 double a,b=qb,c=qc,d=qd , xd,yd,zd ;
1582
1583 /* last row is always [ 0 0 0 1 ] */
1584
1585 R.m[3][0]=R.m[3][1]=R.m[3][2] = 0.0 ; R.m[3][3]= 1.0 ;
1586
1587 /* compute a parameter from b,c,d */
1588
1589 a = 1.0l - (b*b + c*c + d*d) ;
1590 if( a < 1.e-7l ){ /* special case */
1591 a = 1.0l / sqrt(b*b+c*c+d*d) ;
1592 b *= a ; c *= a ; d *= a ; /* normalize (b,c,d) vector */
1593 a = 0.0l ; /* a = 0 ==> 180 degree rotation */
1594 } else{
1595 a = sqrt(a) ; /* angle = 2*arccos(a) */
1596 }
1597
1598 /* load rotation matrix, including scaling factors for voxel sizes */
1599
1600 xd = (dx > 0.0) ? dx : 1.0l ; /* make sure are positive */
1601 yd = (dy > 0.0) ? dy : 1.0l ;
1602 zd = (dz > 0.0) ? dz : 1.0l ;
1603
1604 if( qfac < 0.0 ) zd = -zd ; /* left handedness? */
1605
1606 R.m[0][0] = (a*a+b*b-c*c-d*d) * xd;
1607 R.m[0][1] = 2.0l * (b*c-a*d ) * yd ;
1608 R.m[0][2] = 2.0l * (b*d+a*c ) * zd ;
1609 R.m[1][0] = 2.0l * (b*c+a*d ) * xd ;
1610 R.m[1][1] = (a*a+c*c-b*b-d*d) * yd;
1611 R.m[1][2] = 2.0l * (c*d-a*b ) * zd ;
1612 R.m[2][0] = 2.0l * (b*d-a*c ) * xd ;
1613 R.m[2][1] = 2.0l * (c*d+a*b ) * yd ;
1614 R.m[2][2] = (a*a+d*d-c*c-b*b) * zd;
1615
1616 /* load offsets */
1617
1618 R.m[0][3] = qx ; R.m[1][3] = qy ; R.m[2][3] = qz ;
1619
1620 return R ;
1621 }
1622
1623 /*---------------------------------------------------------------------------*/
1624 /*! Given the quaternion parameters (etc.), compute a transformation matrix.
1625
1626 See comments in nifti1.h for details.
1627 - qb,qc,qd = quaternion parameters
1628 - qx,qy,qz = offset parameters
1629 - dx,dy,dz = grid stepsizes (non-negative inputs are set to 1.0)
1630 - qfac = sign of dz step (< 0 is negative; >= 0 is positive)
1631
1632 <pre>
1633 If qx=qy=qz=0, dx=dy=dz=1, then the output is a rotation matrix.
1634 For qfac >= 0, the rotation is proper.
1635 For qfac < 0, the rotation is improper.
1636 </pre>
1637
1638 \see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h
1639 \see nifti_mat44_to_quatern, nifti_make_orthog_mat44,
1640 nifti_mat44_to_orientation
1641
1642 *//*-------------------------------------------------------------------------*/
nifti_quatern_to_mat44(float qb,float qc,float qd,float qx,float qy,float qz,float dx,float dy,float dz,float qfac)1643 mat44 nifti_quatern_to_mat44( float qb, float qc, float qd,
1644 float qx, float qy, float qz,
1645 float dx, float dy, float dz, float qfac )
1646 {
1647 mat44 R ;
1648 double a,b=qb,c=qc,d=qd , xd,yd,zd ;
1649
1650 /* last row is always [ 0 0 0 1 ] */
1651
1652 R.m[3][0]=R.m[3][1]=R.m[3][2] = 0.0f ; R.m[3][3]= 1.0f ;
1653
1654 /* compute a parameter from b,c,d */
1655
1656 a = 1.0l - (b*b + c*c + d*d) ;
1657 if( a < 1.e-7l ){ /* special case */
1658 a = 1.0l / sqrt(b*b+c*c+d*d) ;
1659 b *= a ; c *= a ; d *= a ; /* normalize (b,c,d) vector */
1660 a = 0.0l ; /* a = 0 ==> 180 degree rotation */
1661 } else{
1662 a = sqrt(a) ; /* angle = 2*arccos(a) */
1663 }
1664
1665 /* load rotation matrix, including scaling factors for voxel sizes */
1666
1667 xd = (dx > 0.0) ? dx : 1.0l ; /* make sure are positive */
1668 yd = (dy > 0.0) ? dy : 1.0l ;
1669 zd = (dz > 0.0) ? dz : 1.0l ;
1670
1671 if( qfac < 0.0 ) zd = -zd ; /* left handedness? */
1672
1673 R.m[0][0] = (float)( (a*a+b*b-c*c-d*d) * xd) ;
1674 R.m[0][1] = 2.0l * (b*c-a*d ) * yd ;
1675 R.m[0][2] = 2.0l * (b*d+a*c ) * zd ;
1676 R.m[1][0] = 2.0l * (b*c+a*d ) * xd ;
1677 R.m[1][1] = (float)( (a*a+c*c-b*b-d*d) * yd) ;
1678 R.m[1][2] = 2.0l * (c*d-a*b ) * zd ;
1679 R.m[2][0] = 2.0l * (b*d-a*c ) * xd ;
1680 R.m[2][1] = 2.0l * (c*d+a*b ) * yd ;
1681 R.m[2][2] = (float)( (a*a+d*d-c*c-b*b) * zd) ;
1682
1683 /* load offsets */
1684
1685 R.m[0][3] = qx ; R.m[1][3] = qy ; R.m[2][3] = qz ;
1686
1687 return R ;
1688 }
1689
1690 /*---------------------------------------------------------------------------*/
1691 /*! Given the 3x4 upper corner of the matrix R, compute the quaternion
1692 parameters that fit it.
1693
1694 - Any NULL pointer on input won't get assigned (e.g., if you don't want
1695 dx,dy,dz, just pass NULL in for those pointers).
1696 - If the 3 input matrix columns are NOT orthogonal, they will be
1697 orthogonalized prior to calculating the parameters, using
1698 the polar decomposition to find the orthogonal matrix closest
1699 to the column-normalized input matrix.
1700 - However, if the 3 input matrix columns are NOT orthogonal, then
1701 the matrix produced by nifti_quatern_to_dmat44 WILL have orthogonal
1702 columns, so it won't be the same as the matrix input here.
1703 This "feature" is because the NIFTI 'qform' transform is
1704 deliberately not fully general -- it is intended to model a volume
1705 with perpendicular axes.
1706 - If the 3 input matrix columns are not even linearly independent,
1707 you'll just have to take your luck, won't you?
1708
1709 \see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h
1710
1711 \see nifti_quatern_to_dmat44, nifti_make_orthog_dmat44,
1712 nifti_dmat44_to_orientation
1713 *//*-------------------------------------------------------------------------*/
nifti_dmat44_to_quatern(nifti_dmat44 R,double * qb,double * qc,double * qd,double * qx,double * qy,double * qz,double * dx,double * dy,double * dz,double * qfac)1714 void nifti_dmat44_to_quatern(nifti_dmat44 R ,
1715 double *qb, double *qc, double *qd,
1716 double *qx, double *qy, double *qz,
1717 double *dx, double *dy, double *dz, double *qfac )
1718 {
1719 double r11,r12,r13 , r21,r22,r23 , r31,r32,r33 ;
1720 double xd,yd,zd , a,b,c,d ;
1721 nifti_dmat33 P,Q ;
1722
1723 /* offset outputs are read write out of input matrix */
1724
1725 ASSIF(qx,R.m[0][3]) ; ASSIF(qy,R.m[1][3]) ; ASSIF(qz,R.m[2][3]) ;
1726
1727 /* load 3x3 matrix into local variables */
1728
1729 r11 = R.m[0][0] ; r12 = R.m[0][1] ; r13 = R.m[0][2] ;
1730 r21 = R.m[1][0] ; r22 = R.m[1][1] ; r23 = R.m[1][2] ;
1731 r31 = R.m[2][0] ; r32 = R.m[2][1] ; r33 = R.m[2][2] ;
1732
1733 /* compute lengths of each column; these determine grid spacings */
1734
1735 xd = sqrt( r11*r11 + r21*r21 + r31*r31 ) ;
1736 yd = sqrt( r12*r12 + r22*r22 + r32*r32 ) ;
1737 zd = sqrt( r13*r13 + r23*r23 + r33*r33 ) ;
1738
1739 /* if a column length is zero, patch the trouble */
1740
1741 if( xd == 0.0l ){ r11 = 1.0l ; r21 = r31 = 0.0l ; xd = 1.0l ; }
1742 if( yd == 0.0l ){ r22 = 1.0l ; r12 = r32 = 0.0l ; yd = 1.0l ; }
1743 if( zd == 0.0l ){ r33 = 1.0l ; r13 = r23 = 0.0l ; zd = 1.0l ; }
1744
1745 /* assign the output lengths */
1746
1747 ASSIF(dx,xd) ; ASSIF(dy,yd) ; ASSIF(dz,zd) ;
1748
1749 /* normalize the columns */
1750
1751 r11 /= xd ; r21 /= xd ; r31 /= xd ;
1752 r12 /= yd ; r22 /= yd ; r32 /= yd ;
1753 r13 /= zd ; r23 /= zd ; r33 /= zd ;
1754
1755 /* At this point, the matrix has normal columns, but we have to allow
1756 for the fact that the hideous user may not have given us a matrix
1757 with orthogonal columns.
1758
1759 So, now find the orthogonal matrix closest to the current matrix.
1760
1761 One reason for using the polar decomposition to get this
1762 orthogonal matrix, rather than just directly orthogonalizing
1763 the columns, is so that inputting the inverse matrix to R
1764 will result in the inverse orthogonal matrix at this point.
1765 If we just orthogonalized the columns, this wouldn't necessarily hold. */
1766
1767 Q.m[0][0] = r11 ; Q.m[0][1] = r12 ; Q.m[0][2] = r13 ; /* load Q */
1768 Q.m[1][0] = r21 ; Q.m[1][1] = r22 ; Q.m[1][2] = r23 ;
1769 Q.m[2][0] = r31 ; Q.m[2][1] = r32 ; Q.m[2][2] = r33 ;
1770
1771 P = nifti_dmat33_polar(Q) ; /* P is orthog matrix closest to Q */
1772
1773 r11 = P.m[0][0] ; r12 = P.m[0][1] ; r13 = P.m[0][2] ; /* unload */
1774 r21 = P.m[1][0] ; r22 = P.m[1][1] ; r23 = P.m[1][2] ;
1775 r31 = P.m[2][0] ; r32 = P.m[2][1] ; r33 = P.m[2][2] ;
1776
1777 /* [ r11 r12 r13 ] */
1778 /* at this point, the matrix [ r21 r22 r23 ] is orthogonal */
1779 /* [ r31 r32 r33 ] */
1780
1781 /* compute the determinant to determine if it is proper */
1782
1783 zd = r11*r22*r33-r11*r32*r23-r21*r12*r33
1784 +r21*r32*r13+r31*r12*r23-r31*r22*r13 ; /* should be -1 or 1 */
1785
1786 if( zd > 0 ){ /* proper */
1787 ASSIF(qfac,1.0) ;
1788 } else { /* improper ==> flip 3rd column */
1789 ASSIF(qfac,-1.0) ;
1790 r13 = -r13 ; r23 = -r23 ; r33 = -r33 ;
1791 }
1792
1793 /* now, compute quaternion parameters */
1794
1795 a = r11 + r22 + r33 + 1.0l ;
1796
1797 if( a > 0.5l ){ /* simplest case */
1798 a = 0.5l * sqrt(a) ;
1799 b = 0.25l * (r32-r23) / a ;
1800 c = 0.25l * (r13-r31) / a ;
1801 d = 0.25l * (r21-r12) / a ;
1802 } else { /* trickier case */
1803 xd = 1.0 + r11 - (r22+r33) ; /* 4*b*b */
1804 yd = 1.0 + r22 - (r11+r33) ; /* 4*c*c */
1805 zd = 1.0 + r33 - (r11+r22) ; /* 4*d*d */
1806 if( xd > 1.0 ){
1807 b = 0.5l * sqrt(xd) ;
1808 c = 0.25l* (r12+r21) / b ;
1809 d = 0.25l* (r13+r31) / b ;
1810 a = 0.25l* (r32-r23) / b ;
1811 } else if( yd > 1.0 ){
1812 c = 0.5l * sqrt(yd) ;
1813 b = 0.25l* (r12+r21) / c ;
1814 d = 0.25l* (r23+r32) / c ;
1815 a = 0.25l* (r13-r31) / c ;
1816 } else {
1817 d = 0.5l * sqrt(zd) ;
1818 b = 0.25l* (r13+r31) / d ;
1819 c = 0.25l* (r23+r32) / d ;
1820 a = 0.25l* (r21-r12) / d ;
1821 }
1822 if( a < 0.0l ){ b=-b ; c=-c ; d=-d; a=-a; }
1823 }
1824
1825 ASSIF(qb,b) ; ASSIF(qc,c) ; ASSIF(qd,d) ;
1826 return ;
1827 }
1828
1829 /*---------------------------------------------------------------------------*/
1830 /*! Given the 3x4 upper corner of the matrix R, compute the quaternion
1831 parameters that fit it.
1832
1833 - Any NULL pointer on input won't get assigned (e.g., if you don't want
1834 dx,dy,dz, just pass NULL in for those pointers).
1835 - If the 3 input matrix columns are NOT orthogonal, they will be
1836 orthogonalized prior to calculating the parameters, using
1837 the polar decomposition to find the orthogonal matrix closest
1838 to the column-normalized input matrix.
1839 - However, if the 3 input matrix columns are NOT orthogonal, then
1840 the matrix produced by nifti_quatern_to_mat44 WILL have orthogonal
1841 columns, so it won't be the same as the matrix input here.
1842 This "feature" is because the NIFTI 'qform' transform is
1843 deliberately not fully general -- it is intended to model a volume
1844 with perpendicular axes.
1845 - If the 3 input matrix columns are not even linearly independent,
1846 you'll just have to take your luck, won't you?
1847
1848 \see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h
1849
1850 \see nifti_quatern_to_mat44, nifti_make_orthog_mat44,
1851 nifti_mat44_to_orientation
1852 *//*-------------------------------------------------------------------------*/
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)1853 void nifti_mat44_to_quatern( mat44 R ,
1854 float *qb, float *qc, float *qd,
1855 float *qx, float *qy, float *qz,
1856 float *dx, float *dy, float *dz, float *qfac )
1857 {
1858 double r11,r12,r13 , r21,r22,r23 , r31,r32,r33 ;
1859 double xd,yd,zd , a,b,c,d ;
1860 mat33 P,Q ;
1861
1862 /* offset outputs are read write out of input matrix */
1863
1864 ASSIF(qx,R.m[0][3]) ; ASSIF(qy,R.m[1][3]) ; ASSIF(qz,R.m[2][3]) ;
1865
1866 /* load 3x3 matrix into local variables */
1867
1868 r11 = R.m[0][0] ; r12 = R.m[0][1] ; r13 = R.m[0][2] ;
1869 r21 = R.m[1][0] ; r22 = R.m[1][1] ; r23 = R.m[1][2] ;
1870 r31 = R.m[2][0] ; r32 = R.m[2][1] ; r33 = R.m[2][2] ;
1871
1872 /* compute lengths of each column; these determine grid spacings */
1873
1874 xd = sqrt( r11*r11 + r21*r21 + r31*r31 ) ;
1875 yd = sqrt( r12*r12 + r22*r22 + r32*r32 ) ;
1876 zd = sqrt( r13*r13 + r23*r23 + r33*r33 ) ;
1877
1878 /* if a column length is zero, patch the trouble */
1879
1880 if( xd == 0.0l ){ r11 = 1.0l ; r21 = r31 = 0.0l ; xd = 1.0l ; }
1881 if( yd == 0.0l ){ r22 = 1.0l ; r12 = r32 = 0.0l ; yd = 1.0l ; }
1882 if( zd == 0.0l ){ r33 = 1.0l ; r13 = r23 = 0.0l ; zd = 1.0l ; }
1883
1884 /* assign the output lengths */
1885
1886 ASSIF(dx,(float)xd) ; ASSIF(dy,(float)yd) ; ASSIF(dz,(float)zd) ;
1887
1888 /* normalize the columns */
1889
1890 r11 /= xd ; r21 /= xd ; r31 /= xd ;
1891 r12 /= yd ; r22 /= yd ; r32 /= yd ;
1892 r13 /= zd ; r23 /= zd ; r33 /= zd ;
1893
1894 /* At this point, the matrix has normal columns, but we have to allow
1895 for the fact that the hideous user may not have given us a matrix
1896 with orthogonal columns.
1897
1898 So, now find the orthogonal matrix closest to the current matrix.
1899
1900 One reason for using the polar decomposition to get this
1901 orthogonal matrix, rather than just directly orthogonalizing
1902 the columns, is so that inputting the inverse matrix to R
1903 will result in the inverse orthogonal matrix at this point.
1904 If we just orthogonalized the columns, this wouldn't necessarily hold. */
1905
1906 Q.m[0][0] = (float)r11 ; Q.m[0][1] = (float)r12 ; Q.m[0][2] = (float)r13 ; /* load Q */
1907 Q.m[1][0] = (float)r21 ; Q.m[1][1] = (float)r22 ; Q.m[1][2] = (float)r23 ;
1908 Q.m[2][0] = (float)r31 ; Q.m[2][1] = (float)r32 ; Q.m[2][2] = (float)r33 ;
1909
1910 P = nifti_mat33_polar(Q) ; /* P is orthog matrix closest to Q */
1911
1912 r11 = P.m[0][0] ; r12 = P.m[0][1] ; r13 = P.m[0][2] ; /* unload */
1913 r21 = P.m[1][0] ; r22 = P.m[1][1] ; r23 = P.m[1][2] ;
1914 r31 = P.m[2][0] ; r32 = P.m[2][1] ; r33 = P.m[2][2] ;
1915
1916 /* [ r11 r12 r13 ] */
1917 /* at this point, the matrix [ r21 r22 r23 ] is orthogonal */
1918 /* [ r31 r32 r33 ] */
1919
1920 /* compute the determinant to determine if it is proper */
1921
1922 zd = r11*r22*r33-r11*r32*r23-r21*r12*r33
1923 +r21*r32*r13+r31*r12*r23-r31*r22*r13 ; /* should be -1 or 1 */
1924
1925 if( zd > 0 ){ /* proper */
1926 ASSIF(qfac,1.0f) ;
1927 } else { /* improper ==> flip 3rd column */
1928 ASSIF(qfac,-1.0f) ;
1929 r13 = -r13 ; r23 = -r23 ; r33 = -r33 ;
1930 }
1931
1932 /* now, compute quaternion parameters */
1933
1934 a = r11 + r22 + r33 + 1.0l ;
1935
1936 if( a > 0.5l ){ /* simplest case */
1937 a = 0.5l * sqrt(a) ;
1938 b = 0.25l * (r32-r23) / a ;
1939 c = 0.25l * (r13-r31) / a ;
1940 d = 0.25l * (r21-r12) / a ;
1941 } else { /* trickier case */
1942 xd = 1.0 + r11 - (r22+r33) ; /* 4*b*b */
1943 yd = 1.0 + r22 - (r11+r33) ; /* 4*c*c */
1944 zd = 1.0 + r33 - (r11+r22) ; /* 4*d*d */
1945 if( xd > 1.0 ){
1946 b = 0.5l * sqrt(xd) ;
1947 c = 0.25l* (r12+r21) / b ;
1948 d = 0.25l* (r13+r31) / b ;
1949 a = 0.25l* (r32-r23) / b ;
1950 } else if( yd > 1.0 ){
1951 c = 0.5l * sqrt(yd) ;
1952 b = 0.25l* (r12+r21) / c ;
1953 d = 0.25l* (r23+r32) / c ;
1954 a = 0.25l* (r13-r31) / c ;
1955 } else {
1956 d = 0.5l * sqrt(zd) ;
1957 b = 0.25l* (r13+r31) / d ;
1958 c = 0.25l* (r23+r32) / d ;
1959 a = 0.25l* (r21-r12) / d ;
1960 }
1961 if( a < 0.0l ){ b=-b ; c=-c ; d=-d; a=-a; }
1962 }
1963
1964 ASSIF(qb,(float)b) ; ASSIF(qc,(float)c) ; ASSIF(qd,(float)d) ;
1965 return ;
1966 }
1967
1968 /*---------------------------------------------------------------------------*/
1969 /*! Compute the inverse of a bordered 4x4 matrix.
1970
1971 <pre>
1972 - Some numerical code fragments were generated by Maple 8.
1973 - If a singular matrix is input, the output matrix will be all zero.
1974 - You can check for this by examining the [3][3] element, which will
1975 be 1.0 for the normal case and 0.0 for the bad case.
1976
1977 The input matrix should have the form:
1978 [ r11 r12 r13 v1 ]
1979 [ r21 r22 r23 v2 ]
1980 [ r31 r32 r33 v3 ]
1981 [ 0 0 0 1 ]
1982 </pre>
1983 *//*-------------------------------------------------------------------------*/
nifti_dmat44_inverse(nifti_dmat44 R)1984 nifti_dmat44 nifti_dmat44_inverse( nifti_dmat44 R )
1985 {
1986 double r11,r12,r13,r21,r22,r23,r31,r32,r33,v1,v2,v3 , deti ;
1987 nifti_dmat44 Q ;
1988 /* INPUT MATRIX IS: */
1989 r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 v1 ] */
1990 r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 v2 ] */
1991 r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 v3 ] */
1992 v1 = R.m[0][3]; v2 = R.m[1][3]; v3 = R.m[2][3]; /* [ 0 0 0 1 ] */
1993
1994 deti = r11*r22*r33-r11*r32*r23-r21*r12*r33
1995 +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;
1996
1997 if( deti != 0.0l ) deti = 1.0l / deti ;
1998
1999 Q.m[0][0] = deti*( r22*r33-r32*r23);
2000 Q.m[0][1] = deti*(-r12*r33+r32*r13);
2001 Q.m[0][2] = deti*( r12*r23-r22*r13);
2002 Q.m[0][3] = deti*(-r12*r23*v3+r12*v2*r33+r22*r13*v3
2003 -r22*v1*r33-r32*r13*v2+r32*v1*r23);
2004
2005 Q.m[1][0] = deti*(-r21*r33+r31*r23);
2006 Q.m[1][1] = deti*( r11*r33-r31*r13);
2007 Q.m[1][2] = deti*(-r11*r23+r21*r13);
2008 Q.m[1][3] = deti*( r11*r23*v3-r11*v2*r33-r21*r13*v3
2009 +r21*v1*r33+r31*r13*v2-r31*v1*r23);
2010
2011 Q.m[2][0] = deti*( r21*r32-r31*r22);
2012 Q.m[2][1] = deti*(-r11*r32+r31*r12);
2013 Q.m[2][2] = deti*( r11*r22-r21*r12);
2014 Q.m[2][3] = deti*(-r11*r22*v3+r11*r32*v2+r21*r12*v3
2015 -r21*r32*v1-r31*r12*v2+r31*r22*v1);
2016
2017 Q.m[3][0] = Q.m[3][1] = Q.m[3][2] = 0.0l ;
2018 Q.m[3][3] = (deti == 0.0l) ? 0.0l : 1.0l ; /* failure flag if deti == 0 */
2019
2020 return Q ;
2021 }
2022
2023 /*---------------------------------------------------------------------------*/
2024 /*! Compute the inverse of a bordered 4x4 matrix.
2025
2026 <pre>
2027 - Some numerical code fragments were generated by Maple 8.
2028 - If a singular matrix is input, the output matrix will be all zero.
2029 - You can check for this by examining the [3][3] element, which will
2030 be 1.0 for the normal case and 0.0 for the bad case.
2031
2032 The input matrix should have the form:
2033 [ r11 r12 r13 v1 ]
2034 [ r21 r22 r23 v2 ]
2035 [ r31 r32 r33 v3 ]
2036 [ 0 0 0 1 ]
2037 </pre>
2038 *//*-------------------------------------------------------------------------*/
nifti_mat44_inverse(mat44 R)2039 mat44 nifti_mat44_inverse( mat44 R )
2040 {
2041 double r11,r12,r13,r21,r22,r23,r31,r32,r33,v1,v2,v3 , deti ;
2042 mat44 Q ;
2043 /* INPUT MATRIX IS: */
2044 r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 v1 ] */
2045 r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 v2 ] */
2046 r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 v3 ] */
2047 v1 = R.m[0][3]; v2 = R.m[1][3]; v3 = R.m[2][3]; /* [ 0 0 0 1 ] */
2048
2049 deti = r11*r22*r33-r11*r32*r23-r21*r12*r33
2050 +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;
2051
2052 if( deti != 0.0l ) deti = 1.0l / deti ;
2053
2054 Q.m[0][0] = (float)( deti*( r22*r33-r32*r23) ) ;
2055 Q.m[0][1] = (float)( deti*(-r12*r33+r32*r13) ) ;
2056 Q.m[0][2] = (float)( deti*( r12*r23-r22*r13) ) ;
2057 Q.m[0][3] = (float)( deti*(-r12*r23*v3+r12*v2*r33+r22*r13*v3
2058 -r22*v1*r33-r32*r13*v2+r32*v1*r23) ) ;
2059
2060 Q.m[1][0] = (float)( deti*(-r21*r33+r31*r23) ) ;
2061 Q.m[1][1] = (float)( deti*( r11*r33-r31*r13) ) ;
2062 Q.m[1][2] = (float)( deti*(-r11*r23+r21*r13) ) ;
2063 Q.m[1][3] = (float)( deti*( r11*r23*v3-r11*v2*r33-r21*r13*v3
2064 +r21*v1*r33+r31*r13*v2-r31*v1*r23) ) ;
2065
2066 Q.m[2][0] = (float)( deti*( r21*r32-r31*r22) ) ;
2067 Q.m[2][1] = (float)( deti*(-r11*r32+r31*r12) ) ;
2068 Q.m[2][2] = (float)( deti*( r11*r22-r21*r12) ) ;
2069 Q.m[2][3] = (float)( deti*(-r11*r22*v3+r11*r32*v2+r21*r12*v3
2070 -r21*r32*v1-r31*r12*v2+r31*r22*v1) ) ;
2071
2072 Q.m[3][0] = Q.m[3][1] = Q.m[3][2] = 0.0l ;
2073 Q.m[3][3] = (deti == 0.0l) ? 0.0l : 1.0l ; /* failure flag if deti == 0 */
2074
2075 return Q ;
2076 }
2077
2078 /*---------------------------------------------------------------------------*/
2079 /*! Input 9 floats and make an orthgonal nifti_dmat44 out of them.
2080
2081 Each row is normalized, then nifti_mat33_polar() is used to orthogonalize
2082 them. If row #3 (r31,r32,r33) is input as zero, then it will be taken to
2083 be the cross product of rows #1 and #2.
2084
2085 This function can be used to create a rotation matrix for transforming
2086 an oblique volume to anatomical coordinates. For this application:
2087 - row #1 (r11,r12,r13) is the direction vector along the image i-axis
2088 - row #2 (r21,r22,r23) is the direction vector along the image j-axis
2089 - row #3 (r31,r32,r33) is the direction vector along the slice direction
2090 (if available; otherwise enter it as 0's)
2091
2092 The first 2 rows can be taken from the DICOM attribute (0020,0037)
2093 "Image Orientation (Patient)".
2094
2095 After forming the rotation matrix, the complete affine transformation from
2096 (i,j,k) grid indexes to (x,y,z) spatial coordinates can be computed by
2097 multiplying each column by the appropriate grid spacing:
2098 - column #1 (R.m[0][0],R.m[1][0],R.m[2][0]) by delta-x
2099 - column #2 (R.m[0][1],R.m[1][1],R.m[2][1]) by delta-y
2100 - column #3 (R.m[0][2],R.m[1][2],R.m[2][2]) by delta-z
2101
2102 and by then placing the center (x,y,z) coordinates of voxel (0,0,0) into
2103 the column #4 (R.m[0][3],R.m[1][3],R.m[2][3]).
2104
2105 \sa nifti_quatern_to_dmat44, nifti_dmat44_to_quatern,
2106 nifti_dmat44_to_orientation
2107 *//*-------------------------------------------------------------------------*/
nifti_make_orthog_dmat44(double r11,double r12,double r13,double r21,double r22,double r23,double r31,double r32,double r33)2108 nifti_dmat44 nifti_make_orthog_dmat44( double r11, double r12, double r13 ,
2109 double r21, double r22, double r23 ,
2110 double r31, double r32, double r33 )
2111 {
2112 nifti_dmat44 R ;
2113 nifti_dmat33 Q , P ;
2114 double val ;
2115
2116 R.m[3][0] = R.m[3][1] = R.m[3][2] = 0.0l ; R.m[3][3] = 1.0l ;
2117
2118 Q.m[0][0] = r11 ; Q.m[0][1] = r12 ; Q.m[0][2] = r13 ; /* load Q */
2119 Q.m[1][0] = r21 ; Q.m[1][1] = r22 ; Q.m[1][2] = r23 ;
2120 Q.m[2][0] = r31 ; Q.m[2][1] = r32 ; Q.m[2][2] = r33 ;
2121
2122 /* normalize row 1 */
2123
2124 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] ;
2125 if( val > 0.0l ){
2126 val = 1.0l / sqrt(val) ;
2127 Q.m[0][0] *= val ; Q.m[0][1] *= val ; Q.m[0][2] *= val ;
2128 } else {
2129 Q.m[0][0] = 1.0l ; Q.m[0][1] = 0.0l ; Q.m[0][2] = 0.0l ;
2130 }
2131
2132 /* normalize row 2 */
2133
2134 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] ;
2135 if( val > 0.0l ){
2136 val = 1.0l / sqrt(val) ;
2137 Q.m[1][0] *= val ; Q.m[1][1] *= val ; Q.m[1][2] *= val ;
2138 } else {
2139 Q.m[1][0] = 0.0l ; Q.m[1][1] = 1.0l ; Q.m[1][2] = 0.0l ;
2140 }
2141
2142 /* normalize row 3 */
2143
2144 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] ;
2145 if( val > 0.0l ){
2146 val = 1.0l / sqrt(val) ;
2147 Q.m[2][0] *= val ; Q.m[2][1] *= val ; Q.m[2][2] *= val ;
2148 } else {
2149 Q.m[2][0] = Q.m[0][1]*Q.m[1][2] - Q.m[0][2]*Q.m[1][1] ; /* cross */
2150 Q.m[2][1] = Q.m[0][2]*Q.m[1][0] - Q.m[0][0]*Q.m[1][2] ; /* product */
2151 Q.m[2][2] = Q.m[0][0]*Q.m[1][1] - Q.m[0][1]*Q.m[1][0] ;
2152 }
2153
2154 P = nifti_dmat33_polar(Q) ; /* P is orthog matrix closest to Q */
2155
2156 R.m[0][0] = P.m[0][0] ; R.m[0][1] = P.m[0][1] ; R.m[0][2] = P.m[0][2] ;
2157 R.m[1][0] = P.m[1][0] ; R.m[1][1] = P.m[1][1] ; R.m[1][2] = P.m[1][2] ;
2158 R.m[2][0] = P.m[2][0] ; R.m[2][1] = P.m[2][1] ; R.m[2][2] = P.m[2][2] ;
2159
2160 R.m[0][3] = R.m[1][3] = R.m[2][3] = 0.0f ; return R ;
2161 }
2162
2163 /*---------------------------------------------------------------------------*/
2164 /*! Input 9 floats and make an orthgonal mat44 out of them.
2165
2166 Each row is normalized, then nifti_mat33_polar() is used to orthogonalize
2167 them. If row #3 (r31,r32,r33) is input as zero, then it will be taken to
2168 be the cross product of rows #1 and #2.
2169
2170 This function can be used to create a rotation matrix for transforming
2171 an oblique volume to anatomical coordinates. For this application:
2172 - row #1 (r11,r12,r13) is the direction vector along the image i-axis
2173 - row #2 (r21,r22,r23) is the direction vector along the image j-axis
2174 - row #3 (r31,r32,r33) is the direction vector along the slice direction
2175 (if available; otherwise enter it as 0's)
2176
2177 The first 2 rows can be taken from the DICOM attribute (0020,0037)
2178 "Image Orientation (Patient)".
2179
2180 After forming the rotation matrix, the complete affine transformation from
2181 (i,j,k) grid indexes to (x,y,z) spatial coordinates can be computed by
2182 multiplying each column by the appropriate grid spacing:
2183 - column #1 (R.m[0][0],R.m[1][0],R.m[2][0]) by delta-x
2184 - column #2 (R.m[0][1],R.m[1][1],R.m[2][1]) by delta-y
2185 - column #3 (R.m[0][2],R.m[1][2],R.m[2][2]) by delta-z
2186
2187 and by then placing the center (x,y,z) coordinates of voxel (0,0,0) into
2188 the column #4 (R.m[0][3],R.m[1][3],R.m[2][3]).
2189
2190 \sa nifti_quatern_to_mat44, nifti_mat44_to_quatern,
2191 nifti_mat44_to_orientation
2192 *//*-------------------------------------------------------------------------*/
nifti_make_orthog_mat44(float r11,float r12,float r13,float r21,float r22,float r23,float r31,float r32,float r33)2193 mat44 nifti_make_orthog_mat44( float r11, float r12, float r13 ,
2194 float r21, float r22, float r23 ,
2195 float r31, float r32, float r33 )
2196 {
2197 mat44 R ;
2198 mat33 Q , P ;
2199 double val ;
2200
2201 R.m[3][0] = R.m[3][1] = R.m[3][2] = 0.0l ; R.m[3][3] = 1.0l ;
2202
2203 Q.m[0][0] = r11 ; Q.m[0][1] = r12 ; Q.m[0][2] = r13 ; /* load Q */
2204 Q.m[1][0] = r21 ; Q.m[1][1] = r22 ; Q.m[1][2] = r23 ;
2205 Q.m[2][0] = r31 ; Q.m[2][1] = r32 ; Q.m[2][2] = r33 ;
2206
2207 /* normalize row 1 */
2208
2209 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] ;
2210 if( val > 0.0l ){
2211 val = 1.0l / sqrt(val) ;
2212 Q.m[0][0] *= (float)val ; Q.m[0][1] *= (float)val ; Q.m[0][2] *= (float)val ;
2213 } else {
2214 Q.m[0][0] = 1.0l ; Q.m[0][1] = 0.0l ; Q.m[0][2] = 0.0l ;
2215 }
2216
2217 /* normalize row 2 */
2218
2219 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] ;
2220 if( val > 0.0l ){
2221 val = 1.0l / sqrt(val) ;
2222 Q.m[1][0] *= (float)val ; Q.m[1][1] *= (float)val ; Q.m[1][2] *= (float)val ;
2223 } else {
2224 Q.m[1][0] = 0.0l ; Q.m[1][1] = 1.0l ; Q.m[1][2] = 0.0l ;
2225 }
2226
2227 /* normalize row 3 */
2228
2229 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] ;
2230 if( val > 0.0l ){
2231 val = 1.0l / sqrt(val) ;
2232 Q.m[2][0] *= (float)val ; Q.m[2][1] *= (float)val ; Q.m[2][2] *= (float)val ;
2233 } else {
2234 Q.m[2][0] = Q.m[0][1]*Q.m[1][2] - Q.m[0][2]*Q.m[1][1] ; /* cross */
2235 Q.m[2][1] = Q.m[0][2]*Q.m[1][0] - Q.m[0][0]*Q.m[1][2] ; /* product */
2236 Q.m[2][2] = Q.m[0][0]*Q.m[1][1] - Q.m[0][1]*Q.m[1][0] ;
2237 }
2238
2239 P = nifti_mat33_polar(Q) ; /* P is orthog matrix closest to Q */
2240
2241 R.m[0][0] = P.m[0][0] ; R.m[0][1] = P.m[0][1] ; R.m[0][2] = P.m[0][2] ;
2242 R.m[1][0] = P.m[1][0] ; R.m[1][1] = P.m[1][1] ; R.m[1][2] = P.m[1][2] ;
2243 R.m[2][0] = P.m[2][0] ; R.m[2][1] = P.m[2][1] ; R.m[2][2] = P.m[2][2] ;
2244
2245 R.m[0][3] = R.m[1][3] = R.m[2][3] = 0.0f ; return R ;
2246 }
2247
2248 /*----------------------------------------------------------------------*/
2249 /*! compute the inverse of a 3x3 matrix
2250 *//*--------------------------------------------------------------------*/
nifti_dmat33_inverse(nifti_dmat33 R)2251 nifti_dmat33 nifti_dmat33_inverse( nifti_dmat33 R ) /* inverse of 3x3 matrix */
2252 {
2253 double r11,r12,r13,r21,r22,r23,r31,r32,r33 , deti ;
2254 nifti_dmat33 Q ;
2255 /* INPUT MATRIX: */
2256 r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 ] */
2257 r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 ] */
2258 r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 ] */
2259
2260 deti = r11*r22*r33-r11*r32*r23-r21*r12*r33
2261 +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;
2262
2263 if( deti != 0.0l ) deti = 1.0l / deti ;
2264
2265 Q.m[0][0] = deti*( r22*r33-r32*r23);
2266 Q.m[0][1] = deti*(-r12*r33+r32*r13);
2267 Q.m[0][2] = deti*( r12*r23-r22*r13);
2268
2269 Q.m[1][0] = deti*(-r21*r33+r31*r23);
2270 Q.m[1][1] = deti*( r11*r33-r31*r13);
2271 Q.m[1][2] = deti*(-r11*r23+r21*r13);
2272
2273 Q.m[2][0] = deti*( r21*r32-r31*r22);
2274 Q.m[2][1] = deti*(-r11*r32+r31*r12);
2275 Q.m[2][2] = deti*( r11*r22-r21*r12);
2276
2277 return Q ;
2278 }
2279
2280 /*----------------------------------------------------------------------*/
2281 /*! compute the inverse of a 3x3 matrix
2282 *//*--------------------------------------------------------------------*/
nifti_mat33_inverse(mat33 R)2283 mat33 nifti_mat33_inverse( mat33 R ) /* inverse of 3x3 matrix */
2284 {
2285 double r11,r12,r13,r21,r22,r23,r31,r32,r33 , deti ;
2286 mat33 Q ;
2287 /* INPUT MATRIX: */
2288 r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 ] */
2289 r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 ] */
2290 r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 ] */
2291
2292 deti = r11*r22*r33-r11*r32*r23-r21*r12*r33
2293 +r21*r32*r13+r31*r12*r23-r31*r22*r13 ;
2294
2295 if( deti != 0.0l ) deti = 1.0l / deti ;
2296
2297 Q.m[0][0] = (float)( deti*( r22*r33-r32*r23) ) ;
2298 Q.m[0][1] = (float)( deti*(-r12*r33+r32*r13) ) ;
2299 Q.m[0][2] = (float)( deti*( r12*r23-r22*r13) ) ;
2300
2301 Q.m[1][0] = (float)( deti*(-r21*r33+r31*r23) ) ;
2302 Q.m[1][1] = (float)( deti*( r11*r33-r31*r13) ) ;
2303 Q.m[1][2] = (float)( deti*(-r11*r23+r21*r13) ) ;
2304
2305 Q.m[2][0] = (float)( deti*( r21*r32-r31*r22) ) ;
2306 Q.m[2][1] = (float)( deti*(-r11*r32+r31*r12) ) ;
2307 Q.m[2][2] = (float)( deti*( r11*r22-r21*r12) ) ;
2308
2309 return Q ;
2310 }
2311
2312 /*----------------------------------------------------------------------*/
2313 /*! compute the determinant of a 3x3 matrix
2314 *//*--------------------------------------------------------------------*/
nifti_dmat33_determ(nifti_dmat33 R)2315 double nifti_dmat33_determ( nifti_dmat33 R ) /* determinant of 3x3 matrix */
2316 {
2317 double r11,r12,r13,r21,r22,r23,r31,r32,r33 ;
2318 /* INPUT MATRIX: */
2319 r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 ] */
2320 r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 ] */
2321 r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 ] */
2322
2323 return (r11*r22*r33-r11*r32*r23-r21*r12*r33
2324 +r21*r32*r13+r31*r12*r23-r31*r22*r13) ;
2325 }
2326
2327 /*----------------------------------------------------------------------*/
2328 /*! compute the determinant of a 3x3 matrix
2329 *//*--------------------------------------------------------------------*/
nifti_mat33_determ(mat33 R)2330 float nifti_mat33_determ( mat33 R ) /* determinant of 3x3 matrix */
2331 {
2332 double r11,r12,r13,r21,r22,r23,r31,r32,r33 ;
2333 /* INPUT MATRIX: */
2334 r11 = R.m[0][0]; r12 = R.m[0][1]; r13 = R.m[0][2]; /* [ r11 r12 r13 ] */
2335 r21 = R.m[1][0]; r22 = R.m[1][1]; r23 = R.m[1][2]; /* [ r21 r22 r23 ] */
2336 r31 = R.m[2][0]; r32 = R.m[2][1]; r33 = R.m[2][2]; /* [ r31 r32 r33 ] */
2337
2338 return (float)(r11*r22*r33-r11*r32*r23-r21*r12*r33
2339 +r21*r32*r13+r31*r12*r23-r31*r22*r13) ;
2340 }
2341
2342 /*----------------------------------------------------------------------*/
2343 /*! compute the max row norm of a 3x3 matrix
2344 *//*--------------------------------------------------------------------*/
nifti_dmat33_rownorm(nifti_dmat33 A)2345 double nifti_dmat33_rownorm( nifti_dmat33 A ) /* max row norm of 3x3 matrix */
2346 {
2347 double r1,r2,r3 ;
2348
2349 r1 = fabs(A.m[0][0])+fabs(A.m[0][1])+fabs(A.m[0][2]);
2350 r2 = fabs(A.m[1][0])+fabs(A.m[1][1])+fabs(A.m[1][2]);
2351 r3 = fabs(A.m[2][0])+fabs(A.m[2][1])+fabs(A.m[2][2]);
2352 if( r1 < r2 ) r1 = r2 ;
2353 if( r1 < r3 ) r1 = r3 ;
2354 return r1 ;
2355 }
2356
2357 /*----------------------------------------------------------------------*/
2358 /*! compute the max row norm of a 3x3 matrix
2359 *//*--------------------------------------------------------------------*/
nifti_mat33_rownorm(mat33 A)2360 float nifti_mat33_rownorm( mat33 A ) /* max row norm of 3x3 matrix */
2361 {
2362 float r1,r2,r3 ;
2363
2364 r1 = (float)( fabs(A.m[0][0])+fabs(A.m[0][1])+fabs(A.m[0][2]) ) ;
2365 r2 = (float)( fabs(A.m[1][0])+fabs(A.m[1][1])+fabs(A.m[1][2]) ) ;
2366 r3 = (float)( fabs(A.m[2][0])+fabs(A.m[2][1])+fabs(A.m[2][2]) ) ;
2367 if( r1 < r2 ) r1 = r2 ;
2368 if( r1 < r3 ) r1 = r3 ;
2369 return r1 ;
2370 }
2371
2372 /*----------------------------------------------------------------------*/
2373 /*! compute the max column norm of a 3x3 matrix
2374 *//*--------------------------------------------------------------------*/
nifti_dmat33_colnorm(nifti_dmat33 A)2375 double nifti_dmat33_colnorm( nifti_dmat33 A )/* max column norm of 3x3 matrix */
2376 {
2377 double r1,r2,r3 ;
2378
2379 r1 = fabs(A.m[0][0])+fabs(A.m[1][0])+fabs(A.m[2][0]);
2380 r2 = fabs(A.m[0][1])+fabs(A.m[1][1])+fabs(A.m[2][1]);
2381 r3 = fabs(A.m[0][2])+fabs(A.m[1][2])+fabs(A.m[2][2]);
2382 if( r1 < r2 ) r1 = r2 ;
2383 if( r1 < r3 ) r1 = r3 ;
2384 return r1 ;
2385 }
2386
2387 /*----------------------------------------------------------------------*/
2388 /*! compute the max column norm of a 3x3 matrix
2389 *//*--------------------------------------------------------------------*/
nifti_mat33_colnorm(mat33 A)2390 float nifti_mat33_colnorm( mat33 A ) /* max column norm of 3x3 matrix */
2391 {
2392 float r1,r2,r3 ;
2393
2394 r1 = (float)( fabs(A.m[0][0])+fabs(A.m[1][0])+fabs(A.m[2][0]) ) ;
2395 r2 = (float)( fabs(A.m[0][1])+fabs(A.m[1][1])+fabs(A.m[2][1]) ) ;
2396 r3 = (float)( fabs(A.m[0][2])+fabs(A.m[1][2])+fabs(A.m[2][2]) ) ;
2397 if( r1 < r2 ) r1 = r2 ;
2398 if( r1 < r3 ) r1 = r3 ;
2399 return r1 ;
2400 }
2401
2402 /*----------------------------------------------------------------------*/
2403 /*! multiply 2 3x3 matrices
2404 *//*--------------------------------------------------------------------*/
nifti_dmat33_mul(nifti_dmat33 A,nifti_dmat33 B)2405 nifti_dmat33 nifti_dmat33_mul( nifti_dmat33 A , nifti_dmat33 B )
2406 /* multiply 2 3x3 matrices */
2407 {
2408 nifti_dmat33 C ; int i,j ;
2409 for( i=0 ; i < 3 ; i++ )
2410 for( j=0 ; j < 3 ; j++ )
2411 C.m[i][j] = A.m[i][0] * B.m[0][j]
2412 + A.m[i][1] * B.m[1][j]
2413 + A.m[i][2] * B.m[2][j] ;
2414 return C ;
2415 }
2416
2417 /*----------------------------------------------------------------------*/
2418 /*! multiply 2 3x3 matrices
2419 *//*--------------------------------------------------------------------*/
nifti_mat33_mul(mat33 A,mat33 B)2420 mat33 nifti_mat33_mul( mat33 A , mat33 B ) /* multiply 2 3x3 matrices */
2421 {
2422 mat33 C ; int i,j ;
2423 for( i=0 ; i < 3 ; i++ )
2424 for( j=0 ; j < 3 ; j++ )
2425 C.m[i][j] = A.m[i][0] * B.m[0][j]
2426 + A.m[i][1] * B.m[1][j]
2427 + A.m[i][2] * B.m[2][j] ;
2428 return C ;
2429 }
2430
2431 /*---------------------------------------------------------------------------*/
2432 /*! polar decomposition of a 3x3 matrix
2433
2434 This finds the closest orthogonal matrix to input A
2435 (in both the Frobenius and L2 norms).
2436
2437 Algorithm is that from NJ Higham, SIAM J Sci Stat Comput, 7:1160-1174.
2438 *//*-------------------------------------------------------------------------*/
nifti_dmat33_polar(nifti_dmat33 A)2439 nifti_dmat33 nifti_dmat33_polar( nifti_dmat33 A )
2440 {
2441 nifti_dmat33 X , Y , Z ;
2442 double alp,bet,gam,gmi , dif=1.0 ;
2443 int k=0 ;
2444
2445 X = A ;
2446
2447 /* force matrix to be nonsingular */
2448
2449 gam = nifti_dmat33_determ(X) ;
2450 while( gam == 0.0 ){ /* perturb matrix */
2451 gam = 0.00001 * ( 0.001 + nifti_dmat33_rownorm(X) );
2452 X.m[0][0] += gam ; X.m[1][1] += gam ; X.m[2][2] += gam ;
2453 gam = nifti_dmat33_determ(X) ;
2454 }
2455
2456 while(1){
2457 Y = nifti_dmat33_inverse(X) ;
2458 if( dif > 0.3 ){ /* far from convergence */
2459 alp = sqrt( nifti_dmat33_rownorm(X) * nifti_dmat33_colnorm(X) );
2460 bet = sqrt( nifti_dmat33_rownorm(Y) * nifti_dmat33_colnorm(Y) );
2461 gam = sqrt( bet / alp );
2462 gmi = 1.0 / gam;
2463 } else {
2464 gam = gmi = 1.0f ; /* close to convergence */
2465 }
2466 Z.m[0][0] = 0.5 * ( gam*X.m[0][0] + gmi*Y.m[0][0] );
2467 Z.m[0][1] = 0.5 * ( gam*X.m[0][1] + gmi*Y.m[1][0] );
2468 Z.m[0][2] = 0.5 * ( gam*X.m[0][2] + gmi*Y.m[2][0] );
2469 Z.m[1][0] = 0.5 * ( gam*X.m[1][0] + gmi*Y.m[0][1] );
2470 Z.m[1][1] = 0.5 * ( gam*X.m[1][1] + gmi*Y.m[1][1] );
2471 Z.m[1][2] = 0.5 * ( gam*X.m[1][2] + gmi*Y.m[2][1] );
2472 Z.m[2][0] = 0.5 * ( gam*X.m[2][0] + gmi*Y.m[0][2] );
2473 Z.m[2][1] = 0.5 * ( gam*X.m[2][1] + gmi*Y.m[1][2] );
2474 Z.m[2][2] = 0.5 * ( gam*X.m[2][2] + gmi*Y.m[2][2] );
2475
2476 dif = fabs(Z.m[0][0]-X.m[0][0])+fabs(Z.m[0][1]-X.m[0][1])
2477 +fabs(Z.m[0][2]-X.m[0][2])+fabs(Z.m[1][0]-X.m[1][0])
2478 +fabs(Z.m[1][1]-X.m[1][1])+fabs(Z.m[1][2]-X.m[1][2])
2479 +fabs(Z.m[2][0]-X.m[2][0])+fabs(Z.m[2][1]-X.m[2][1])
2480 +fabs(Z.m[2][2]-X.m[2][2]);
2481
2482 k = k+1 ;
2483 if( k > 100 || dif < 3.e-6 ) break ; /* convergence or exhaustion */
2484 X = Z ;
2485 }
2486
2487 return Z ;
2488 }
2489
2490 /*---------------------------------------------------------------------------*/
2491 /*! polar decomposition of a 3x3 matrix
2492
2493 This finds the closest orthogonal matrix to input A
2494 (in both the Frobenius and L2 norms).
2495
2496 Algorithm is that from NJ Higham, SIAM J Sci Stat Comput, 7:1160-1174.
2497 *//*-------------------------------------------------------------------------*/
nifti_mat33_polar(mat33 A)2498 mat33 nifti_mat33_polar( mat33 A )
2499 {
2500 mat33 X , Y , Z ;
2501 float alp,bet,gam,gmi , dif=1.0f ;
2502 int k=0 ;
2503
2504 X = A ;
2505
2506 /* force matrix to be nonsingular */
2507
2508 gam = nifti_mat33_determ(X) ;
2509 while( gam == 0.0 ){ /* perturb matrix */
2510 gam = (float)( 0.00001 * ( 0.001 + nifti_mat33_rownorm(X) ) ) ;
2511 X.m[0][0] += gam ; X.m[1][1] += gam ; X.m[2][2] += gam ;
2512 gam = nifti_mat33_determ(X) ;
2513 }
2514
2515 while(1){
2516 Y = nifti_mat33_inverse(X) ;
2517 if( dif > 0.3 ){ /* far from convergence */
2518 alp = (float)( sqrt( nifti_mat33_rownorm(X) * nifti_mat33_colnorm(X) ) ) ;
2519 bet = (float)( sqrt( nifti_mat33_rownorm(Y) * nifti_mat33_colnorm(Y) ) ) ;
2520 gam = (float)( sqrt( bet / alp ) ) ;
2521 gmi = (float)( 1.0 / gam ) ;
2522 } else {
2523 gam = gmi = 1.0f ; /* close to convergence */
2524 }
2525 Z.m[0][0] = (float)( 0.5 * ( gam*X.m[0][0] + gmi*Y.m[0][0] ) ) ;
2526 Z.m[0][1] = (float)( 0.5 * ( gam*X.m[0][1] + gmi*Y.m[1][0] ) ) ;
2527 Z.m[0][2] = (float)( 0.5 * ( gam*X.m[0][2] + gmi*Y.m[2][0] ) ) ;
2528 Z.m[1][0] = (float)( 0.5 * ( gam*X.m[1][0] + gmi*Y.m[0][1] ) ) ;
2529 Z.m[1][1] = (float)( 0.5 * ( gam*X.m[1][1] + gmi*Y.m[1][1] ) ) ;
2530 Z.m[1][2] = (float)( 0.5 * ( gam*X.m[1][2] + gmi*Y.m[2][1] ) ) ;
2531 Z.m[2][0] = (float)( 0.5 * ( gam*X.m[2][0] + gmi*Y.m[0][2] ) ) ;
2532 Z.m[2][1] = (float)( 0.5 * ( gam*X.m[2][1] + gmi*Y.m[1][2] ) ) ;
2533 Z.m[2][2] = (float)( 0.5 * ( gam*X.m[2][2] + gmi*Y.m[2][2] ) ) ;
2534
2535 dif = (float)( fabs(Z.m[0][0]-X.m[0][0])+fabs(Z.m[0][1]-X.m[0][1])
2536 +fabs(Z.m[0][2]-X.m[0][2])+fabs(Z.m[1][0]-X.m[1][0])
2537 +fabs(Z.m[1][1]-X.m[1][1])+fabs(Z.m[1][2]-X.m[1][2])
2538 +fabs(Z.m[2][0]-X.m[2][0])+fabs(Z.m[2][1]-X.m[2][1])
2539 +fabs(Z.m[2][2]-X.m[2][2]) );
2540
2541 k = k+1 ;
2542 if( k > 100 || dif < 3.e-6 ) break ; /* convergence or exhaustion */
2543 X = Z ;
2544 }
2545
2546 return Z ;
2547 }
2548
2549 /*---------------------------------------------------------------------------*/
2550 /*! compute the (closest) orientation from a 4x4 ijk->xyz tranformation matrix
2551
2552 <pre>
2553 Input: 4x4 matrix that transforms (i,j,k) indexes to (x,y,z) coordinates,
2554 where +x=Right, +y=Anterior, +z=Superior.
2555 (Only the upper-left 3x3 corner of R is used herein.)
2556 Output: 3 orientation codes that correspond to the closest "standard"
2557 anatomical orientation of the (i,j,k) axes.
2558 Method: Find which permutation of (x,y,z) has the smallest angle to the
2559 (i,j,k) axes directions, which are the columns of the R matrix.
2560 Errors: The codes returned will be zero.
2561
2562 For example, an axial volume might get return values of
2563 *icod = NIFTI_R2L (i axis is mostly Right to Left)
2564 *jcod = NIFTI_P2A (j axis is mostly Posterior to Anterior)
2565 *kcod = NIFTI_I2S (k axis is mostly Inferior to Superior)
2566 </pre>
2567
2568 \see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h
2569
2570 \see nifti_quatern_to_mat44, nifti_mat44_to_quatern,
2571 nifti_make_orthog_mat44
2572 *//*-------------------------------------------------------------------------*/
nifti_dmat44_to_orientation(nifti_dmat44 R,int * icod,int * jcod,int * kcod)2573 void nifti_dmat44_to_orientation( nifti_dmat44 R ,
2574 int *icod, int *jcod, int *kcod )
2575 {
2576 double xi,xj,xk , yi,yj,yk , zi,zj,zk , val,detQ,detP ;
2577 nifti_dmat33 P , Q , M ;
2578 int i,j,k=0,p,q,r , ibest,jbest,kbest,pbest,qbest,rbest ;
2579 double vbest ;
2580
2581 if( icod == NULL || jcod == NULL || kcod == NULL ) return ; /* bad */
2582
2583 *icod = *jcod = *kcod = 0 ; /* error returns, if sh*t happens */
2584
2585 /* load column vectors for each (i,j,k) direction from matrix */
2586
2587 /*-- i axis --*/ /*-- j axis --*/ /*-- k axis --*/
2588
2589 xi = R.m[0][0] ; xj = R.m[0][1] ; xk = R.m[0][2] ;
2590 yi = R.m[1][0] ; yj = R.m[1][1] ; yk = R.m[1][2] ;
2591 zi = R.m[2][0] ; zj = R.m[2][1] ; zk = R.m[2][2] ;
2592
2593 /* normalize column vectors to get unit vectors along each ijk-axis */
2594
2595 /* normalize i axis */
2596
2597 val = sqrt( xi*xi + yi*yi + zi*zi ) ;
2598 if( val == 0.0 ) return ; /* stupid input */
2599 xi /= val ; yi /= val ; zi /= val ;
2600
2601 /* normalize j axis */
2602
2603 val = sqrt( xj*xj + yj*yj + zj*zj ) ;
2604 if( val == 0.0 ) return ; /* stupid input */
2605 xj /= val ; yj /= val ; zj /= val ;
2606
2607 /* orthogonalize j axis to i axis, if needed */
2608
2609 val = xi*xj + yi*yj + zi*zj ; /* dot product between i and j */
2610 if( fabs(val) > 1.e-4 ){
2611 xj -= val*xi ; yj -= val*yi ; zj -= val*zi ;
2612 val = sqrt( xj*xj + yj*yj + zj*zj ) ; /* must renormalize */
2613 if( val == 0.0 ) return ; /* j was parallel to i? */
2614 xj /= val ; yj /= val ; zj /= val ;
2615 }
2616
2617 /* normalize k axis; if it is zero, make it the cross product i x j */
2618
2619 val = sqrt( xk*xk + yk*yk + zk*zk ) ;
2620 if( val == 0.0 ){ xk = yi*zj-zi*yj; yk = zi*xj-zj*xi ; zk=xi*yj-yi*xj ; }
2621 else { xk /= val ; yk /= val ; zk /= val ; }
2622
2623 /* orthogonalize k to i */
2624
2625 val = xi*xk + yi*yk + zi*zk ; /* dot product between i and k */
2626 if( fabs(val) > 1.e-4 ){
2627 xk -= val*xi ; yk -= val*yi ; zk -= val*zi ;
2628 val = sqrt( xk*xk + yk*yk + zk*zk ) ;
2629 if( val == 0.0 ) return ; /* bad */
2630 xk /= val ; yk /= val ; zk /= val ;
2631 }
2632
2633 /* orthogonalize k to j */
2634
2635 val = xj*xk + yj*yk + zj*zk ; /* dot product between j and k */
2636 if( fabs(val) > 1.e-4 ){
2637 xk -= val*xj ; yk -= val*yj ; zk -= val*zj ;
2638 val = sqrt( xk*xk + yk*yk + zk*zk ) ;
2639 if( val == 0.0 ) return ; /* bad */
2640 xk /= val ; yk /= val ; zk /= val ;
2641 }
2642
2643 Q.m[0][0] = xi ; Q.m[0][1] = xj ; Q.m[0][2] = xk ;
2644 Q.m[1][0] = yi ; Q.m[1][1] = yj ; Q.m[1][2] = yk ;
2645 Q.m[2][0] = zi ; Q.m[2][1] = zj ; Q.m[2][2] = zk ;
2646
2647 /* at this point, Q is the rotation matrix from (i,j,k) to (x,y,z) axes */
2648
2649 detQ = nifti_dmat33_determ( Q ) ;
2650 if( detQ == 0.0 ) return ; /* shouldn't happen unless user is a DUFIS */
2651
2652 /* Build and test all possible +1/-1 coordinate permutation matrices P;
2653 then find the P such that the rotation matrix M=PQ is closest to the
2654 identity, in the sense of M having the smallest total rotation angle. */
2655
2656 /* Despite the formidable looking 6 nested loops, there are
2657 only 3*3*3*2*2*2 = 216 passes, which will run very quickly. */
2658
2659 vbest = -666.0 ; ibest=pbest=qbest=rbest=1 ; jbest=2 ; kbest=3 ;
2660 for( i=1 ; i <= 3 ; i++ ){ /* i = column number to use for row #1 */
2661 for( j=1 ; j <= 3 ; j++ ){ /* j = column number to use for row #2 */
2662 if( i == j ) continue ;
2663 for( k=1 ; k <= 3 ; k++ ){ /* k = column number to use for row #3 */
2664 if( i == k || j == k ) continue ;
2665 P.m[0][0] = P.m[0][1] = P.m[0][2] =
2666 P.m[1][0] = P.m[1][1] = P.m[1][2] =
2667 P.m[2][0] = P.m[2][1] = P.m[2][2] = 0.0 ;
2668 for( p=-1 ; p <= 1 ; p+=2 ){ /* p,q,r are -1 or +1 */
2669 for( q=-1 ; q <= 1 ; q+=2 ){ /* and go into rows #1,2,3 */
2670 for( r=-1 ; r <= 1 ; r+=2 ){
2671 P.m[0][i-1] = p ; P.m[1][j-1] = q ; P.m[2][k-1] = r ;
2672 detP = nifti_dmat33_determ(P) ; /* sign of permutation */
2673 if( detP * detQ <= 0.0 ) continue ; /* doesn't match sign of Q */
2674 M = nifti_dmat33_mul(P,Q) ;
2675
2676 /* angle of M rotation = 2.0*acos(0.5*sqrt(1.0+trace(M))) */
2677 /* we want largest trace(M) == smallest angle == M nearest to I */
2678
2679 val = M.m[0][0] + M.m[1][1] + M.m[2][2] ; /* trace */
2680 if( val > vbest ){
2681 vbest = val ;
2682 ibest = i ; jbest = j ; kbest = k ;
2683 pbest = p ; qbest = q ; rbest = r ;
2684 }
2685 }}}}}}
2686
2687 /* At this point ibest is 1 or 2 or 3; pbest is -1 or +1; etc.
2688
2689 The matrix P that corresponds is the best permutation approximation
2690 to Q-inverse; that is, P (approximately) takes (x,y,z) coordinates
2691 to the (i,j,k) axes.
2692
2693 For example, the first row of P (which contains pbest in column ibest)
2694 determines the way the i axis points relative to the anatomical
2695 (x,y,z) axes. If ibest is 2, then the i axis is along the y axis,
2696 which is direction P2A (if pbest > 0) or A2P (if pbest < 0).
2697
2698 So, using ibest and pbest, we can assign the output code for
2699 the i axis. Mutatis mutandis for the j and k axes, of course. */
2700
2701 switch( ibest*pbest ){
2702 case 1: i = NIFTI_L2R ; break ;
2703 case -1: i = NIFTI_R2L ; break ;
2704 case 2: i = NIFTI_P2A ; break ;
2705 case -2: i = NIFTI_A2P ; break ;
2706 case 3: i = NIFTI_I2S ; break ;
2707 case -3: i = NIFTI_S2I ; break ;
2708 }
2709
2710 switch( jbest*qbest ){
2711 case 1: j = NIFTI_L2R ; break ;
2712 case -1: j = NIFTI_R2L ; break ;
2713 case 2: j = NIFTI_P2A ; break ;
2714 case -2: j = NIFTI_A2P ; break ;
2715 case 3: j = NIFTI_I2S ; break ;
2716 case -3: j = NIFTI_S2I ; break ;
2717 }
2718
2719 switch( kbest*rbest ){
2720 case 1: k = NIFTI_L2R ; break ;
2721 case -1: k = NIFTI_R2L ; break ;
2722 case 2: k = NIFTI_P2A ; break ;
2723 case -2: k = NIFTI_A2P ; break ;
2724 case 3: k = NIFTI_I2S ; break ;
2725 case -3: k = NIFTI_S2I ; break ;
2726 }
2727
2728 *icod = i ; *jcod = j ; *kcod = k ; return ;
2729 }
2730
2731 /*---------------------------------------------------------------------------*/
2732 /*! compute the (closest) orientation from a 4x4 ijk->xyz tranformation matrix
2733
2734 <pre>
2735 Input: 4x4 matrix that transforms (i,j,k) indexes to (x,y,z) coordinates,
2736 where +x=Right, +y=Anterior, +z=Superior.
2737 (Only the upper-left 3x3 corner of R is used herein.)
2738 Output: 3 orientation codes that correspond to the closest "standard"
2739 anatomical orientation of the (i,j,k) axes.
2740 Method: Find which permutation of (x,y,z) has the smallest angle to the
2741 (i,j,k) axes directions, which are the columns of the R matrix.
2742 Errors: The codes returned will be zero.
2743
2744 For example, an axial volume might get return values of
2745 *icod = NIFTI_R2L (i axis is mostly Right to Left)
2746 *jcod = NIFTI_P2A (j axis is mostly Posterior to Anterior)
2747 *kcod = NIFTI_I2S (k axis is mostly Inferior to Superior)
2748 </pre>
2749
2750 \see "QUATERNION REPRESENTATION OF ROTATION MATRIX" in nifti1.h
2751
2752 \see nifti_quatern_to_mat44, nifti_mat44_to_quatern,
2753 nifti_make_orthog_mat44
2754 *//*-------------------------------------------------------------------------*/
nifti_mat44_to_orientation(mat44 R,int * icod,int * jcod,int * kcod)2755 void nifti_mat44_to_orientation( mat44 R , int *icod, int *jcod, int *kcod )
2756 {
2757 float xi,xj,xk , yi,yj,yk , zi,zj,zk , val,detQ,detP ;
2758 mat33 P , Q , M ;
2759 int i,j,k=0,p,q,r , ibest,jbest,kbest,pbest,qbest,rbest ;
2760 float vbest ;
2761
2762 if( icod == NULL || jcod == NULL || kcod == NULL ) return ; /* bad */
2763
2764 *icod = *jcod = *kcod = 0 ; /* error returns, if sh*t happens */
2765
2766 /* load column vectors for each (i,j,k) direction from matrix */
2767
2768 /*-- i axis --*/ /*-- j axis --*/ /*-- k axis --*/
2769
2770 xi = R.m[0][0] ; xj = R.m[0][1] ; xk = R.m[0][2] ;
2771 yi = R.m[1][0] ; yj = R.m[1][1] ; yk = R.m[1][2] ;
2772 zi = R.m[2][0] ; zj = R.m[2][1] ; zk = R.m[2][2] ;
2773
2774 /* normalize column vectors to get unit vectors along each ijk-axis */
2775
2776 /* normalize i axis */
2777
2778 val = (float)sqrt( xi*xi + yi*yi + zi*zi ) ;
2779 if( val == 0.0 ) return ; /* stupid input */
2780 xi /= val ; yi /= val ; zi /= val ;
2781
2782 /* normalize j axis */
2783
2784 val = (float)sqrt( xj*xj + yj*yj + zj*zj ) ;
2785 if( val == 0.0 ) return ; /* stupid input */
2786 xj /= val ; yj /= val ; zj /= val ;
2787
2788 /* orthogonalize j axis to i axis, if needed */
2789
2790 val = xi*xj + yi*yj + zi*zj ; /* dot product between i and j */
2791 if( fabs(val) > 1.e-4 ){
2792 xj -= val*xi ; yj -= val*yi ; zj -= val*zi ;
2793 val = (float)sqrt( xj*xj + yj*yj + zj*zj ) ; /* must renormalize */
2794 if( val == 0.0 ) return ; /* j was parallel to i? */
2795 xj /= val ; yj /= val ; zj /= val ;
2796 }
2797
2798 /* normalize k axis; if it is zero, make it the cross product i x j */
2799
2800 val = (float)sqrt( xk*xk + yk*yk + zk*zk ) ;
2801 if( val == 0.0 ){ xk = yi*zj-zi*yj; yk = zi*xj-zj*xi ; zk=xi*yj-yi*xj ; }
2802 else { xk /= val ; yk /= val ; zk /= val ; }
2803
2804 /* orthogonalize k to i */
2805
2806 val = xi*xk + yi*yk + zi*zk ; /* dot product between i and k */
2807 if( fabs(val) > 1.e-4 ){
2808 xk -= val*xi ; yk -= val*yi ; zk -= val*zi ;
2809 val = (float)sqrt( xk*xk + yk*yk + zk*zk ) ;
2810 if( val == 0.0 ) return ; /* bad */
2811 xk /= val ; yk /= val ; zk /= val ;
2812 }
2813
2814 /* orthogonalize k to j */
2815
2816 val = xj*xk + yj*yk + zj*zk ; /* dot product between j and k */
2817 if( fabs(val) > 1.e-4 ){
2818 xk -= val*xj ; yk -= val*yj ; zk -= val*zj ;
2819 val = (float)sqrt( xk*xk + yk*yk + zk*zk ) ;
2820 if( val == 0.0 ) return ; /* bad */
2821 xk /= val ; yk /= val ; zk /= val ;
2822 }
2823
2824 Q.m[0][0] = xi ; Q.m[0][1] = xj ; Q.m[0][2] = xk ;
2825 Q.m[1][0] = yi ; Q.m[1][1] = yj ; Q.m[1][2] = yk ;
2826 Q.m[2][0] = zi ; Q.m[2][1] = zj ; Q.m[2][2] = zk ;
2827
2828 /* at this point, Q is the rotation matrix from the (i,j,k) to (x,y,z) axes */
2829
2830 detQ = nifti_mat33_determ( Q ) ;
2831 if( detQ == 0.0 ) return ; /* shouldn't happen unless user is a DUFIS */
2832
2833 /* Build and test all possible +1/-1 coordinate permutation matrices P;
2834 then find the P such that the rotation matrix M=PQ is closest to the
2835 identity, in the sense of M having the smallest total rotation angle. */
2836
2837 /* Despite the formidable looking 6 nested loops, there are
2838 only 3*3*3*2*2*2 = 216 passes, which will run very quickly. */
2839
2840 vbest = -666.0f ; ibest=pbest=qbest=rbest=1 ; jbest=2 ; kbest=3 ;
2841 for( i=1 ; i <= 3 ; i++ ){ /* i = column number to use for row #1 */
2842 for( j=1 ; j <= 3 ; j++ ){ /* j = column number to use for row #2 */
2843 if( i == j ) continue ;
2844 for( k=1 ; k <= 3 ; k++ ){ /* k = column number to use for row #3 */
2845 if( i == k || j == k ) continue ;
2846 P.m[0][0] = P.m[0][1] = P.m[0][2] =
2847 P.m[1][0] = P.m[1][1] = P.m[1][2] =
2848 P.m[2][0] = P.m[2][1] = P.m[2][2] = 0.0f ;
2849 for( p=-1 ; p <= 1 ; p+=2 ){ /* p,q,r are -1 or +1 */
2850 for( q=-1 ; q <= 1 ; q+=2 ){ /* and go into rows #1,2,3 */
2851 for( r=-1 ; r <= 1 ; r+=2 ){
2852 P.m[0][i-1] = p ; P.m[1][j-1] = q ; P.m[2][k-1] = r ;
2853 detP = nifti_mat33_determ(P) ; /* sign of permutation */
2854 if( detP * detQ <= 0.0 ) continue ; /* doesn't match sign of Q */
2855 M = nifti_mat33_mul(P,Q) ;
2856
2857 /* angle of M rotation = 2.0*acos(0.5*sqrt(1.0+trace(M))) */
2858 /* we want largest trace(M) == smallest angle == M nearest to I */
2859
2860 val = M.m[0][0] + M.m[1][1] + M.m[2][2] ; /* trace */
2861 if( val > vbest ){
2862 vbest = val ;
2863 ibest = i ; jbest = j ; kbest = k ;
2864 pbest = p ; qbest = q ; rbest = r ;
2865 }
2866 }}}}}}
2867
2868 /* At this point ibest is 1 or 2 or 3; pbest is -1 or +1; etc.
2869
2870 The matrix P that corresponds is the best permutation approximation
2871 to Q-inverse; that is, P (approximately) takes (x,y,z) coordinates
2872 to the (i,j,k) axes.
2873
2874 For example, the first row of P (which contains pbest in column ibest)
2875 determines the way the i axis points relative to the anatomical
2876 (x,y,z) axes. If ibest is 2, then the i axis is along the y axis,
2877 which is direction P2A (if pbest > 0) or A2P (if pbest < 0).
2878
2879 So, using ibest and pbest, we can assign the output code for
2880 the i axis. Mutatis mutandis for the j and k axes, of course. */
2881
2882 switch( ibest*pbest ){
2883 case 1: i = NIFTI_L2R ; break ;
2884 case -1: i = NIFTI_R2L ; break ;
2885 case 2: i = NIFTI_P2A ; break ;
2886 case -2: i = NIFTI_A2P ; break ;
2887 case 3: i = NIFTI_I2S ; break ;
2888 case -3: i = NIFTI_S2I ; break ;
2889 }
2890
2891 switch( jbest*qbest ){
2892 case 1: j = NIFTI_L2R ; break ;
2893 case -1: j = NIFTI_R2L ; break ;
2894 case 2: j = NIFTI_P2A ; break ;
2895 case -2: j = NIFTI_A2P ; break ;
2896 case 3: j = NIFTI_I2S ; break ;
2897 case -3: j = NIFTI_S2I ; break ;
2898 }
2899
2900 switch( kbest*rbest ){
2901 case 1: k = NIFTI_L2R ; break ;
2902 case -1: k = NIFTI_R2L ; break ;
2903 case 2: k = NIFTI_P2A ; break ;
2904 case -2: k = NIFTI_A2P ; break ;
2905 case 3: k = NIFTI_I2S ; break ;
2906 case -3: k = NIFTI_S2I ; break ;
2907 }
2908
2909 *icod = i ; *jcod = j ; *kcod = k ; return ;
2910 }
2911
2912 /*---------------------------------------------------------------------------*/
2913 /* Routines to swap byte arrays in various ways:
2914 - 2 at a time: ab -> ba [short]
2915 - 4 at a time: abcd -> dcba [int, float]
2916 - 8 at a time: abcdDCBA -> ABCDdcba [long long, double]
2917 - 16 at a time: abcdefghHGFEDCBA -> ABCDEFGHhgfedcba [long double]
2918 -----------------------------------------------------------------------------*/
2919
2920 /*----------------------------------------------------------------------*/
2921 /*! swap each byte pair from the given list of n pairs
2922 *
2923 * Due to alignment of structures at some architectures (e.g. on ARM),
2924 * stick to char varaibles.
2925 * Fixes http://bugs.debian.org/446893 Yaroslav <debian@onerussian.com>
2926 *
2927 *//*--------------------------------------------------------------------*/
nifti_swap_2bytes(int64_t n,void * ar)2928 void nifti_swap_2bytes( int64_t n , void *ar ) /* 2 bytes at a time */
2929 {
2930 int64_t ii ;
2931 unsigned char * cp1 = (unsigned char *)ar, * cp2 ;
2932 unsigned char tval;
2933
2934 for( ii=0 ; ii < n ; ii++ ){
2935 cp2 = cp1 + 1;
2936 tval = *cp1; *cp1 = *cp2; *cp2 = tval;
2937 cp1 += 2;
2938 }
2939 return ;
2940 }
2941
2942 /*----------------------------------------------------------------------*/
2943 /*! swap 4 bytes at a time from the given list of n sets of 4 bytes
2944 *//*--------------------------------------------------------------------*/
nifti_swap_4bytes(int64_t n,void * ar)2945 void nifti_swap_4bytes( int64_t n , void *ar ) /* 4 bytes at a time */
2946 {
2947 int64_t ii ;
2948 unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ;
2949 unsigned char tval ;
2950
2951 for( ii=0 ; ii < n ; ii++ ){
2952 cp1 = cp0; cp2 = cp0+3;
2953 tval = *cp1; *cp1 = *cp2; *cp2 = tval;
2954 cp1++; cp2--;
2955 tval = *cp1; *cp1 = *cp2; *cp2 = tval;
2956 cp0 += 4;
2957 }
2958 return ;
2959 }
2960
2961 /*----------------------------------------------------------------------*/
2962 /*! swap 8 bytes at a time from the given list of n sets of 8 bytes
2963 *
2964 * perhaps use this style for the general Nbytes, as Yaroslav suggests
2965 *//*--------------------------------------------------------------------*/
nifti_swap_8bytes(int64_t n,void * ar)2966 void nifti_swap_8bytes( int64_t n , void *ar ) /* 8 bytes at a time */
2967 {
2968 int64_t ii ;
2969 unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ;
2970 unsigned char tval ;
2971
2972 for( ii=0 ; ii < n ; ii++ ){
2973 cp1 = cp0; cp2 = cp0+7;
2974 while ( cp2 > cp1 ) /* unroll? */
2975 {
2976 tval = *cp1 ; *cp1 = *cp2 ; *cp2 = tval ;
2977 cp1++; cp2--;
2978 }
2979 cp0 += 8;
2980 }
2981 return ;
2982 }
2983
2984 /*----------------------------------------------------------------------*/
2985 /*! swap 16 bytes at a time from the given list of n sets of 16 bytes
2986 *//*--------------------------------------------------------------------*/
nifti_swap_16bytes(int64_t n,void * ar)2987 void nifti_swap_16bytes( int64_t n , void *ar ) /* 16 bytes at a time */
2988 {
2989 int64_t ii ;
2990 unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ;
2991 unsigned char tval ;
2992
2993 for( ii=0 ; ii < n ; ii++ ){
2994 cp1 = cp0; cp2 = cp0+15;
2995 while ( cp2 > cp1 )
2996 {
2997 tval = *cp1 ; *cp1 = *cp2 ; *cp2 = tval ;
2998 cp1++; cp2--;
2999 }
3000 cp0 += 16;
3001 }
3002 return ;
3003 }
3004
3005 #if 0 /* not important: save for version update 6 Jul 2010 [rickr] */
3006
3007 /*----------------------------------------------------------------------*/
3008 /*! generic: swap siz bytes at a time from the given list of n sets
3009 *//*--------------------------------------------------------------------*/
3010 void nifti_swap_bytes( int64_t n , int siz , void *ar )
3011 {
3012 int64_t ii ;
3013 unsigned char * cp0 = (unsigned char *)ar, * cp1, * cp2 ;
3014 unsigned char tval ;
3015
3016 for( ii=0 ; ii < n ; ii++ ){
3017 cp1 = cp0; cp2 = cp0+(siz-1);
3018 while ( cp2 > cp1 )
3019 {
3020 tval = *cp1 ; *cp1 = *cp2 ; *cp2 = tval ;
3021 cp1++; cp2--;
3022 }
3023 cp0 += siz;
3024 }
3025 return ;
3026 }
3027 #endif
3028
3029 /*---------------------------------------------------------------------------*/
3030
3031 /*----------------------------------------------------------------------*/
3032 /*! based on siz, call the appropriate nifti_swap_Nbytes() function
3033 *//*--------------------------------------------------------------------*/
nifti_swap_Nbytes(int64_t n,int siz,void * ar)3034 void nifti_swap_Nbytes( int64_t n , int siz , void *ar ) /* subsuming case */
3035 {
3036 switch( siz ){
3037 case 2: nifti_swap_2bytes ( n , ar ) ; break ;
3038 case 4: nifti_swap_4bytes ( n , ar ) ; break ;
3039 case 8: nifti_swap_8bytes ( n , ar ) ; break ;
3040 case 16: nifti_swap_16bytes( n , ar ) ; break ;
3041 default: /* nifti_swap_bytes ( n , siz, ar ) ; */
3042 fprintf(stderr,"** NIfTI: cannot swap in %d byte blocks\n", siz);
3043 break ;
3044 }
3045 return ;
3046 }
3047
3048
3049 /*-------------------------------------------------------------------------*/
3050 /*! Byte swap NIFTI file header, depending on the version.
3051 *//*---------------------------------------------------------------------- */
swap_nifti_header(void * hdr,int ni_ver)3052 void swap_nifti_header( void * hdr , int ni_ver )
3053 {
3054 if ( ni_ver == 0 ) nifti_swap_as_analyze((nifti_analyze75 *)hdr);
3055 else if( ni_ver == 1 ) nifti_swap_as_nifti1((nifti_1_header *)hdr);
3056 else if( ni_ver == 2 ) nifti_swap_as_nifti2((nifti_2_header *)hdr);
3057 else if( ni_ver >= 0 && ni_ver <= 9 ) {
3058 fprintf(stderr,"** swap_nifti_header: not ready for version %d\n",ni_ver);
3059 } else {
3060 fprintf(stderr,"** swap_nifti_header: illegal version %d\n", ni_ver);
3061 }
3062 }
3063
3064
3065 /*-------------------------------------------------------------------------*/
3066 /*! Byte swap NIFTI-2 file header.
3067 *//*---------------------------------------------------------------------- */
nifti_swap_as_nifti2(nifti_2_header * h)3068 void nifti_swap_as_nifti2( nifti_2_header * h )
3069 {
3070 if ( ! h ) {
3071 fprintf(stderr,"** nifti_swap_as_nifti2: NULL pointer\n");
3072 return;
3073 }
3074
3075 nifti_swap_4bytes(1, &h->sizeof_hdr);
3076
3077 nifti_swap_2bytes(1, &h->datatype);
3078 nifti_swap_2bytes(1, &h->bitpix);
3079
3080 nifti_swap_8bytes(8, h->dim);
3081 nifti_swap_8bytes(1, &h->intent_p1);
3082 nifti_swap_8bytes(1, &h->intent_p2);
3083 nifti_swap_8bytes(1, &h->intent_p3);
3084 nifti_swap_8bytes(8, h->pixdim);
3085
3086 nifti_swap_8bytes(1, &h->vox_offset);
3087 nifti_swap_8bytes(1, &h->scl_slope);
3088 nifti_swap_8bytes(1, &h->scl_inter);
3089 nifti_swap_8bytes(1, &h->cal_max);
3090 nifti_swap_8bytes(1, &h->cal_min);
3091 nifti_swap_8bytes(1, &h->slice_duration);
3092 nifti_swap_8bytes(1, &h->toffset);
3093 nifti_swap_8bytes(1, &h->slice_start);
3094 nifti_swap_8bytes(1, &h->slice_end);
3095
3096 nifti_swap_4bytes(1, &h->qform_code);
3097 nifti_swap_4bytes(1, &h->sform_code);
3098
3099 nifti_swap_8bytes(1, &h->quatern_b);
3100 nifti_swap_8bytes(1, &h->quatern_c);
3101 nifti_swap_8bytes(1, &h->quatern_d);
3102 nifti_swap_8bytes(1, &h->qoffset_x);
3103 nifti_swap_8bytes(1, &h->qoffset_y);
3104 nifti_swap_8bytes(1, &h->qoffset_z);
3105
3106 nifti_swap_8bytes(4, h->srow_x);
3107 nifti_swap_8bytes(4, h->srow_y);
3108 nifti_swap_8bytes(4, h->srow_z);
3109
3110 nifti_swap_4bytes(1, &h->slice_code);
3111 nifti_swap_4bytes(1, &h->xyzt_units);
3112 nifti_swap_4bytes(1, &h->intent_code);
3113 }
3114
3115 /*-------------------------------------------------------------------------*/
3116 /*! Byte swap NIFTI-1 file header in various places and ways.
3117 * return 0 on success
3118 *//*---------------------------------------------------------------------- */
nifti_swap_as_nifti1(nifti_1_header * h)3119 void nifti_swap_as_nifti1( nifti_1_header * h )
3120 {
3121 if ( ! h ) {
3122 fprintf(stderr,"** nifti_swap_as_nifti1: NULL pointer\n");
3123 return;
3124 }
3125
3126 nifti_swap_4bytes(1, &h->sizeof_hdr);
3127 nifti_swap_4bytes(1, &h->extents);
3128 nifti_swap_2bytes(1, &h->session_error);
3129
3130 nifti_swap_2bytes(8, h->dim);
3131 nifti_swap_4bytes(1, &h->intent_p1);
3132 nifti_swap_4bytes(1, &h->intent_p2);
3133 nifti_swap_4bytes(1, &h->intent_p3);
3134
3135 nifti_swap_2bytes(1, &h->intent_code);
3136 nifti_swap_2bytes(1, &h->datatype);
3137 nifti_swap_2bytes(1, &h->bitpix);
3138 nifti_swap_2bytes(1, &h->slice_start);
3139
3140 nifti_swap_4bytes(8, h->pixdim);
3141
3142 nifti_swap_4bytes(1, &h->vox_offset);
3143 nifti_swap_4bytes(1, &h->scl_slope);
3144 nifti_swap_4bytes(1, &h->scl_inter);
3145 nifti_swap_2bytes(1, &h->slice_end);
3146
3147 nifti_swap_4bytes(1, &h->cal_max);
3148 nifti_swap_4bytes(1, &h->cal_min);
3149 nifti_swap_4bytes(1, &h->slice_duration);
3150 nifti_swap_4bytes(1, &h->toffset);
3151 nifti_swap_4bytes(1, &h->glmax);
3152 nifti_swap_4bytes(1, &h->glmin);
3153
3154 nifti_swap_2bytes(1, &h->qform_code);
3155 nifti_swap_2bytes(1, &h->sform_code);
3156
3157 nifti_swap_4bytes(1, &h->quatern_b);
3158 nifti_swap_4bytes(1, &h->quatern_c);
3159 nifti_swap_4bytes(1, &h->quatern_d);
3160 nifti_swap_4bytes(1, &h->qoffset_x);
3161 nifti_swap_4bytes(1, &h->qoffset_y);
3162 nifti_swap_4bytes(1, &h->qoffset_z);
3163
3164 nifti_swap_4bytes(4, h->srow_x);
3165 nifti_swap_4bytes(4, h->srow_y);
3166 nifti_swap_4bytes(4, h->srow_z);
3167 }
3168
3169 /*-------------------------------------------------------------------------*/
3170 /*! Byte swap as an ANALYZE 7.5 header
3171 *
3172 * return non-zero on failure
3173 *//*---------------------------------------------------------------------- */
nifti_swap_as_analyze(nifti_analyze75 * h)3174 void nifti_swap_as_analyze( nifti_analyze75 * h )
3175 {
3176 if ( ! h ) {
3177 fprintf(stderr,"** nifti_swap_as_analyze: NULL pointer\n");
3178 return;
3179 }
3180
3181 nifti_swap_4bytes(1, &h->sizeof_hdr);
3182 nifti_swap_4bytes(1, &h->extents);
3183 nifti_swap_2bytes(1, &h->session_error);
3184
3185 nifti_swap_2bytes(8, h->dim);
3186 nifti_swap_2bytes(1, &h->unused8);
3187 nifti_swap_2bytes(1, &h->unused9);
3188 nifti_swap_2bytes(1, &h->unused10);
3189 nifti_swap_2bytes(1, &h->unused11);
3190 nifti_swap_2bytes(1, &h->unused12);
3191 nifti_swap_2bytes(1, &h->unused13);
3192 nifti_swap_2bytes(1, &h->unused14);
3193
3194 nifti_swap_2bytes(1, &h->datatype);
3195 nifti_swap_2bytes(1, &h->bitpix);
3196 nifti_swap_2bytes(1, &h->dim_un0);
3197
3198 nifti_swap_4bytes(8, h->pixdim);
3199
3200 nifti_swap_4bytes(1, &h->vox_offset);
3201 nifti_swap_4bytes(1, &h->funused1);
3202 nifti_swap_4bytes(1, &h->funused2);
3203 nifti_swap_4bytes(1, &h->funused3);
3204
3205 nifti_swap_4bytes(1, &h->cal_max);
3206 nifti_swap_4bytes(1, &h->cal_min);
3207 nifti_swap_4bytes(1, &h->compressed);
3208 nifti_swap_4bytes(1, &h->verified);
3209 nifti_swap_4bytes(1, &h->glmax);
3210 nifti_swap_4bytes(1, &h->glmin);
3211
3212 nifti_swap_4bytes(1, &h->views);
3213 nifti_swap_4bytes(1, &h->vols_added);
3214 nifti_swap_4bytes(1, &h->start_field);
3215 nifti_swap_4bytes(1, &h->field_skip);
3216
3217 nifti_swap_4bytes(1, &h->omax);
3218 nifti_swap_4bytes(1, &h->omin);
3219 nifti_swap_4bytes(1, &h->smax);
3220 nifti_swap_4bytes(1, &h->smin);
3221 }
3222
3223 /*-------------------------------------------------------------------------*/
3224 /*! OLD VERSION of swap_nifti_header (left for undo/compare operations)
3225
3226 Byte swap NIFTI-1 file header in various places and ways.
3227
3228 If is_nifti is nonzero, will also swap the NIFTI-specific
3229 components of the header; otherwise, only the components
3230 common to NIFTI and ANALYZE will be swapped.
3231 *//*---------------------------------------------------------------------- */
old_swap_nifti_header(nifti_1_header * h,int is_nifti)3232 void old_swap_nifti_header( nifti_1_header *h , int is_nifti )
3233 {
3234 /* this stuff is always present, for ANALYZE and NIFTI */
3235
3236 swap_4(h->sizeof_hdr) ;
3237 nifti_swap_2bytes( 8 , h->dim ) ;
3238 nifti_swap_4bytes( 8 , h->pixdim ) ;
3239
3240 swap_2(h->datatype) ;
3241 swap_2(h->bitpix) ;
3242
3243 swap_4(h->vox_offset); swap_4(h->cal_max); swap_4(h->cal_min);
3244
3245 /* this stuff is NIFTI specific */
3246
3247 if( is_nifti ){
3248 swap_4(h->intent_p1); swap_4(h->intent_p2); swap_4(h->intent_p3);
3249 swap_2(h->intent_code);
3250
3251 swap_2(h->slice_start); swap_2(h->slice_end);
3252 swap_4(h->scl_slope); swap_4(h->scl_inter);
3253 swap_4(h->slice_duration); swap_4(h->toffset);
3254
3255 swap_2(h->qform_code); swap_2(h->sform_code);
3256 swap_4(h->quatern_b); swap_4(h->quatern_c); swap_4(h->quatern_d);
3257 swap_4(h->qoffset_x); swap_4(h->qoffset_y); swap_4(h->qoffset_z);
3258 nifti_swap_4bytes(4,h->srow_x);
3259 nifti_swap_4bytes(4,h->srow_y);
3260 nifti_swap_4bytes(4,h->srow_z);
3261 }
3262 return ;
3263 }
3264
3265
3266 #define USE_STAT
3267 #ifdef USE_STAT
3268 /*---------------------------------------------------------------------------*/
3269 /* Return the file length (0 if file not found or has no contents).
3270 This is a Unix-specific function, since it uses stat().
3271 -----------------------------------------------------------------------------*/
3272 #include <sys/types.h>
3273 #include <sys/stat.h>
3274
3275 /*---------------------------------------------------------------------------*/
3276 /*! return the size of a file, in bytes
3277
3278 \return size of file on success, -1 on error or no file
3279
3280 changed to return int, -1 means no file or error 20 Dec 2004 [rickr]
3281 *//*-------------------------------------------------------------------------*/
nifti_get_filesize(const char * pathname)3282 int64_t nifti_get_filesize( const char *pathname )
3283 {
3284 struct stat buf ; int ii ;
3285
3286 if( pathname == NULL || *pathname == '\0' ) return -1 ;
3287 ii = stat( pathname , &buf ); if( ii != 0 ) return -1 ;
3288 return buf.st_size ;
3289 }
3290
3291 #else /*---------- non-Unix version of the above, less efficient -----------*/
3292
nifti_get_filesize(const char * pathname)3293 int64_t nifti_get_filesize( const char *pathname )
3294 {
3295 znzFile fp ; int64_t len ;
3296
3297 if( pathname == NULL || *pathname == '\0' ) return -1 ;
3298 fp = znzopen(pathname,"rb",0); if( znz_isnull(fp) ) return -1 ;
3299 znzseek(fp,0L,SEEK_END) ; len = znztell(fp) ;
3300 znzclose(fp) ; return len ;
3301 }
3302
3303 #endif /* USE_STAT */
3304
3305
3306 /*----------------------------------------------------------------------*/
3307 /*! return the total volume size, in bytes
3308
3309 This is computed as nvox * nbyper.
3310 *//*--------------------------------------------------------------------*/
nifti_get_volsize(const nifti_image * nim)3311 int64_t nifti_get_volsize(const nifti_image *nim)
3312 {
3313 return (int64_t)nim->nbyper * nim->nvox ; /* total bytes */
3314 }
3315
3316
3317 /*--------------------------------------------------------------------------*/
3318 /* Support functions for filenames in read and write
3319 - allows for gzipped files
3320 */
3321
3322
3323 /*----------------------------------------------------------------------*/
3324 /*! simple check for file existence
3325
3326 \return 1 on existence, 0 otherwise
3327 *//*--------------------------------------------------------------------*/
nifti_fileexists(const char * fname)3328 int nifti_fileexists(const char* fname)
3329 {
3330 znzFile fp;
3331 fp = znzopen( fname , "rb" , 1 ) ;
3332 if( !znz_isnull(fp) ) { znzclose(fp); return 1; }
3333 return 0; /* fp is NULL */
3334 }
3335
3336 /*----------------------------------------------------------------------*/
3337 /*! return whether the filename is valid
3338
3339 Note: uppercase extensions are now valid. 27 Apr 2009 [rickr]
3340
3341 The name is considered valid if the file basename has length greater than
3342 zero, AND one of the valid nifti extensions is provided.
3343 fname input | return |
3344 ===============================
3345 "myimage" | 0 |
3346 "myimage.tif" | 0 |
3347 "myimage.tif.gz" | 0 |
3348 "myimage.nii" | 1 |
3349 ".nii" | 0 |
3350 ".myhiddenimage" | 0 |
3351 ".myhiddenimage.nii" | 1 |
3352 *//*--------------------------------------------------------------------*/
nifti_is_complete_filename(const char * fname)3353 int nifti_is_complete_filename(const char* fname)
3354 {
3355 const char * ext;
3356
3357 /* check input file(s) for sanity */
3358 if( fname == NULL || *fname == '\0' ){
3359 if ( g_opts.debug > 1 )
3360 fprintf(stderr,"-- empty filename in nifti_validfilename()\n");
3361 return 0;
3362 }
3363
3364 ext = nifti_find_file_extension(fname);
3365 if ( ext == NULL ) { /*Invalid extension given */
3366 if ( g_opts.debug > 0 )
3367 fprintf(stderr,"-- no nifti valid extension for filename '%s'\n", fname);
3368 return 0;
3369 }
3370
3371 if ( ext && ext == fname ) { /* then no filename prefix */
3372 if ( g_opts.debug > 0 )
3373 fprintf(stderr,"-- no prefix for filename '%s'\n", fname);
3374 return 0;
3375 }
3376 return 1;
3377 }
3378
3379 /*----------------------------------------------------------------------*/
3380 /*! return whether the filename is valid
3381
3382 Allow uppercase extensions as valid. 27 Apr 2009 [rickr]
3383 Any .gz extension case must match the base extension case.
3384
3385 The name is considered valid if its length is positive, excluding
3386 any nifti filename extension.
3387 fname input | return | result of nifti_makebasename
3388 ====================================================================
3389 "myimage" | 1 | "myimage"
3390 "myimage.tif" | 1 | "myimage.tif"
3391 "myimage.tif.gz" | 1 | "myimage.tif"
3392 "myimage.nii" | 1 | "myimage"
3393 ".nii" | 0 | <ERROR - basename has zero length>
3394 ".myhiddenimage" | 1 | ".myhiddenimage"
3395 ".myhiddenimage.nii | 1 | ".myhiddenimage"
3396 *//*--------------------------------------------------------------------*/
nifti_validfilename(const char * fname)3397 int nifti_validfilename(const char* fname)
3398 {
3399 const char * ext;
3400
3401 /* check input file(s) for sanity */
3402 if( fname == NULL || *fname == '\0' ){
3403 if ( g_opts.debug > 1 )
3404 fprintf(stderr,"-- empty filename in nifti_validfilename()\n");
3405 return 0;
3406 }
3407
3408 ext = nifti_find_file_extension(fname);
3409
3410 if ( ext && ext == fname ) { /* then no filename prefix */
3411 if ( g_opts.debug > 0 )
3412 fprintf(stderr,"-- no prefix for filename '%s'\n", fname);
3413 return 0;
3414 }
3415
3416 return 1;
3417 }
3418
3419 /*----------------------------------------------------------------------*/
3420 /*! check the end of the filename for a valid nifti extension
3421
3422 Valid extensions are currently .nii, .hdr, .img, .nia,
3423 or any of them followed by .gz. Note that '.' is part of
3424 the extension.
3425
3426 Uppercase extensions are also valid, but not mixed case.
3427
3428 \return a pointer to the extension substring within the original
3429 function input parameter name, or NULL if not found.
3430 \caution Note that if the input parameter is is immutabale
3431 (i.e. a const char *) then this function performs an
3432 implicit casting away of the mutability constraint and
3433 the return parameter will appear as a mutable
3434 even though it is part of the immuttable string.
3435 *//*--------------------------------------------------------------------*/
nifti_find_file_extension(const char * name)3436 char * nifti_find_file_extension( const char * name )
3437 {
3438 const char * ext;
3439 char extcopy[8];
3440 int len;
3441 char extnii[8] = ".nii"; /* modifiable, for possible uppercase */
3442 char exthdr[8] = ".hdr"; /* (leave space for .gz) */
3443 char extimg[8] = ".img";
3444 char extnia[8] = ".nia";
3445 char extgz[4] = ".gz";
3446 char * elist[4] = { NULL, NULL, NULL, NULL};
3447
3448 /* stupid compiler... */
3449 elist[0] = extnii; elist[1] = exthdr; elist[2] = extimg; elist[3] = extnia;
3450
3451 if ( ! name ) return NULL;
3452
3453 len = (int)strlen(name);
3454 if ( len < 4 ) return NULL;
3455
3456 ext = name + len - 4;
3457
3458 /* make manipulation copy, and possibly convert to lowercase */
3459 strcpy(extcopy, ext);
3460 if( g_opts.allow_upper_fext ) make_lowercase(extcopy);
3461
3462 /* if it look like a basic extension, fail or return it */
3463 if( compare_strlist(extcopy, elist, 4) >= 0 ) {
3464 if( is_mixedcase(ext) ) {
3465 fprintf(stderr,"** mixed case extension '%s' is not valid\n", ext);
3466 return NULL;
3467 }
3468 else return (char *)ext; /* Cast away the constness of the input parameter */
3469 }
3470
3471 #ifdef HAVE_ZLIB
3472 if ( len < 7 ) return NULL;
3473
3474 ext = name + len - 7;
3475
3476 /* make manipulation copy, and possibly convert to lowercase */
3477 strcpy(extcopy, ext);
3478 if( g_opts.allow_upper_fext ) make_lowercase(extcopy);
3479
3480 /* go after .gz extensions using the modifiable strings */
3481 strcat(elist[0], extgz); strcat(elist[1], extgz); strcat(elist[2], extgz);
3482
3483 if( compare_strlist(extcopy, elist, 3) >= 0 ) {
3484 if( is_mixedcase(ext) ) {
3485 fprintf(stderr,"** mixed case extension '%s' is not valid\n", ext);
3486 return NULL;
3487 }
3488 else return (char *)ext; /* Cast away the constness of the input parameter */
3489 }
3490
3491 #endif
3492
3493 if( g_opts.debug > 1 )
3494 fprintf(stderr,"** find_file_ext: failed for name '%s'\n", name);
3495
3496 return NULL;
3497 }
3498
3499 /*----------------------------------------------------------------------*/
3500 /*! return whether the filename ends in ".gz"
3501 *//*--------------------------------------------------------------------*/
nifti_is_gzfile(const char * fname)3502 int nifti_is_gzfile(const char* fname)
3503 {
3504 /* return true if the filename ends with .gz */
3505 if (fname == NULL) { return 0; }
3506 #ifdef HAVE_ZLIB
3507 { /* just so len doesn't generate compile warning */
3508 int len;
3509 len = (int)strlen(fname);
3510 if (len < 3) return 0; /* so we don't search before the name */
3511 if (fileext_compare(fname + strlen(fname) - 3,".gz")==0) { return 1; }
3512 }
3513 #endif
3514 return 0;
3515 }
3516
3517 /*----------------------------------------------------------------------*/
3518 /*! return whether the given library was compiled with HAVE_ZLIB set
3519 *//*--------------------------------------------------------------------*/
nifti_compiled_with_zlib(void)3520 int nifti_compiled_with_zlib(void)
3521 {
3522 #ifdef HAVE_ZLIB
3523 return 1;
3524 #else
3525 return 0;
3526 #endif
3527 }
3528
3529 /*----------------------------------------------------------------------*/
3530 /*! duplicate the filename, while clearing any extension
3531
3532 This allocates memory for basename which should eventually be freed.
3533 *//*--------------------------------------------------------------------*/
nifti_makebasename(const char * fname)3534 char * nifti_makebasename(const char* fname)
3535 {
3536 char *basename;
3537 const char *ext;
3538
3539 basename=nifti_strdup(fname);
3540
3541 ext = nifti_find_file_extension(basename);
3542 if ( ext )
3543 {
3544 basename[strlen(basename)-strlen(ext)] = '\0'; /* clear out extension */
3545 }
3546
3547 return basename; /* in either case */
3548 }
3549
3550 /*----------------------------------------------------------------------*/
3551 /* option accessor functions */
3552 /*----------------------------------------------------------------------*/
3553
3554 /*----------------------------------------------------------------------*/
3555 /*! set nifti's global debug level, for status reporting
3556
3557 - 0 : quiet, nothing is printed to the terminal, but errors
3558 - 1 : normal execution (the default)
3559 - 2, 3 : more details
3560 *//*--------------------------------------------------------------------*/
nifti_set_debug_level(int level)3561 void nifti_set_debug_level( int level )
3562 {
3563 g_opts.debug = level;
3564 }
3565
3566 /*----------------------------------------------------------------------*/
3567 /*! set nifti's global skip_blank_ext flag 5 Sep 2006 [rickr]
3568
3569 explicitly set to 0 or 1
3570 *//*--------------------------------------------------------------------*/
nifti_set_skip_blank_ext(int skip)3571 void nifti_set_skip_blank_ext( int skip )
3572 {
3573 g_opts.skip_blank_ext = skip ? 1 : 0;
3574 }
3575
3576 /*----------------------------------------------------------------------*/
3577 /*! set nifti's global allow_upper_fext flag 28 Apr 2009 [rickr]
3578
3579 explicitly set to 0 or 1
3580 *//*--------------------------------------------------------------------*/
nifti_set_allow_upper_fext(int allow)3581 void nifti_set_allow_upper_fext( int allow )
3582 {
3583 g_opts.allow_upper_fext = allow ? 1 : 0;
3584 }
3585
3586 /*----------------------------------------------------------------------*/
3587 /*! get nifti's global alter_cifti flag 22 Jul 2015 [rickr]
3588 *//*--------------------------------------------------------------------*/
nifti_get_alter_cifti(void)3589 int nifti_get_alter_cifti( void )
3590 {
3591 return g_opts.alter_cifti;
3592 }
3593
3594 /*----------------------------------------------------------------------*/
3595 /*! set nifti's global alter_cifti flag 22 Jul 2015 [rickr]
3596
3597 explicitly set to 0 or 1
3598 *//*--------------------------------------------------------------------*/
nifti_set_alter_cifti(int alter_cifti)3599 void nifti_set_alter_cifti( int alter_cifti )
3600 {
3601 g_opts.alter_cifti = alter_cifti ? 1 : 0;
3602 }
3603
3604 /*----------------------------------------------------------------------*/
3605 /*! check current directory for existing header file
3606
3607 \return filename of header on success and NULL if no appropriate file
3608 could be found
3609
3610 If fname has an uppercase extension, check for uppercase files.
3611
3612 NB: it allocates memory for hdrname which should be freed
3613 when no longer required
3614 *//*-------------------------------------------------------------------*/
nifti_findhdrname(const char * fname)3615 char * nifti_findhdrname(const char* fname)
3616 {
3617 char *basename, *hdrname;
3618 const char *ext;
3619 char elist[2][5] = { ".hdr", ".nii" };
3620 char extzip[4] = ".gz";
3621 int efirst = 1; /* init to .nii extension */
3622 int eisupper = 0; /* init to lowercase extensions */
3623
3624 /**- check input file(s) for sanity */
3625 if( !nifti_validfilename(fname) ) return NULL;
3626
3627 basename = nifti_makebasename(fname);
3628 if( !basename ) return NULL; /* only on string alloc failure */
3629
3630 /**- return filename if it has a valid extension and exists
3631 (except if it is an .img file (and maybe .gz)) */
3632 ext = nifti_find_file_extension(fname);
3633
3634 if( ext ) eisupper = is_uppercase(ext); /* do we look for uppercase? */
3635
3636 /* if the file exists and is a valid header name (not .img), return it */
3637 if ( ext && nifti_fileexists(fname) ) {
3638 /* allow for uppercase extension */
3639 if ( fileext_n_compare(ext,".img",4) != 0 ){
3640 hdrname = nifti_strdup(fname);
3641 free(basename);
3642 return hdrname;
3643 } else
3644 efirst = 0; /* note for below */
3645 }
3646
3647 /* So the requested name is a basename, contains .img, or does not exist. */
3648 /* In any case, use basename. */
3649
3650 /**- if .img, look for .hdr, .hdr.gz, .nii, .nii.gz, in that order */
3651 /**- else, look for .nii, .nii.gz, .hdr, .hdr.gz, in that order */
3652
3653 /* if we get more extension choices, this could be a loop */
3654
3655 /* note: efirst is 0 in the case of ".img" */
3656
3657 /* if the user passed an uppercase entension (.IMG), search for uppercase */
3658 if( eisupper ) {
3659 make_uppercase(elist[0]);
3660 make_uppercase(elist[1]);
3661 make_uppercase(extzip);
3662 }
3663
3664 hdrname = (char *)calloc(sizeof(char),strlen(basename)+8);
3665 if( !hdrname ){
3666 fprintf(stderr,"** nifti_findhdrname: failed to alloc hdrname\n");
3667 free(basename);
3668 return NULL;
3669 }
3670
3671 strcpy(hdrname,basename);
3672 strcat(hdrname,elist[efirst]);
3673 if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
3674 #ifdef HAVE_ZLIB
3675 strcat(hdrname,extzip);
3676 if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
3677 #endif
3678
3679 /* okay, try the other possibility */
3680
3681 efirst = 1 - efirst;
3682
3683 strcpy(hdrname,basename);
3684 strcat(hdrname,elist[efirst]);
3685 if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
3686 #ifdef HAVE_ZLIB
3687 strcat(hdrname,extzip);
3688 if (nifti_fileexists(hdrname)) { free(basename); return hdrname; }
3689 #endif
3690
3691 /**- if nothing has been found, return NULL */
3692 free(basename);
3693 free(hdrname);
3694 return NULL;
3695 }
3696
3697
3698 /*------------------------------------------------------------------------*/
3699 /*! check current directory for existing image file
3700
3701 \param fname filename to check for
3702 \nifti_type nifti_type for dataset - this determines whether to
3703 first check for ".nii" or ".img" (since both may exist)
3704
3705 \return filename of data/img file on success and NULL if no appropriate
3706 file could be found
3707
3708 If fname has a valid, uppercase extension, apply all extensions as
3709 uppercase.
3710
3711 NB: it allocates memory for the image filename, which should be freed
3712 when no longer required
3713 *//*---------------------------------------------------------------------*/
nifti_findimgname(const char * fname,int nifti_type)3714 char * nifti_findimgname(const char* fname , int nifti_type)
3715 {
3716 /* store all extensions as strings, in case we need to go uppercase */
3717 char *basename, *imgname, elist[2][5] = { ".nii", ".img" };
3718 char extzip[4] = ".gz";
3719 char extnia[5] = ".nia";
3720 const char *ext;
3721 int first; /* first extension to use */
3722
3723 /* check input file(s) for sanity */
3724 if( !nifti_validfilename(fname) ) return NULL;
3725
3726 basename = nifti_makebasename(fname);
3727 imgname = (char *)calloc(sizeof(char),strlen(basename)+8);
3728 if( !imgname ){
3729 fprintf(stderr,"** nifti_findimgname: failed to alloc imgname\n");
3730 free(basename);
3731 return NULL;
3732 }
3733
3734 /* if we are looking for uppercase, apply the fact now */
3735 ext = nifti_find_file_extension(fname);
3736 if( ext && is_uppercase(ext) ) {
3737 make_uppercase(elist[0]);
3738 make_uppercase(elist[1]);
3739 make_uppercase(extzip);
3740 make_uppercase(extnia);
3741 }
3742
3743 /* only valid extension for ASCII type is .nia, handle first */
3744 if( nifti_type == NIFTI_FTYPE_ASCII ){
3745 strcpy(imgname,basename);
3746 strcat(imgname,extnia);
3747 if (nifti_fileexists(imgname)) { free(basename); return imgname; }
3748
3749 } else {
3750
3751 /**- test for .nii and .img (don't assume input type from image type) */
3752 /**- if nifti_type = 1, check for .nii first, else .img first */
3753
3754 /* if we get 3 or more extensions, can make a loop here... */
3755
3756 if (nifti_type == NIFTI_FTYPE_NIFTI1_1) first = 0; /* should match .nii */
3757 else first = 1; /* should match .img */
3758
3759 strcpy(imgname,basename);
3760 strcat(imgname,elist[first]);
3761 if (nifti_fileexists(imgname)) { free(basename); return imgname; }
3762 #ifdef HAVE_ZLIB /* then also check for .gz */
3763 strcat(imgname,extzip);
3764 if (nifti_fileexists(imgname)) { free(basename); return imgname; }
3765 #endif
3766
3767 /* failed to find image file with expected extension, try the other */
3768
3769 strcpy(imgname,basename);
3770 strcat(imgname,elist[1-first]); /* can do this with only 2 choices */
3771 if (nifti_fileexists(imgname)) { free(basename); return imgname; }
3772 #ifdef HAVE_ZLIB /* then also check for .gz */
3773 strcat(imgname,extzip);
3774 if (nifti_fileexists(imgname)) { free(basename); return imgname; }
3775 #endif
3776 }
3777
3778 /**- if nothing has been found, return NULL */
3779 free(basename);
3780 free(imgname);
3781 return NULL;
3782 }
3783
3784
3785 /*----------------------------------------------------------------------*/
3786 /*! creates a filename for storing the header, based on nifti_type
3787
3788 \param prefix - this will be copied before the suffix is added
3789 \param nifti_type - determines the extension, unless one is in prefix
3790 \param check - check for existence (fail condition)
3791 \param comp - add .gz for compressed name
3792
3793 Note that if prefix provides a file suffix, nifti_type is not used.
3794
3795 NB: this allocates memory which should be freed
3796
3797 \sa nifti_set_filenames
3798 *//*-------------------------------------------------------------------*/
nifti_makehdrname(const char * prefix,int nifti_type,int check,int comp)3799 char * nifti_makehdrname(const char * prefix, int nifti_type, int check,
3800 int comp)
3801 {
3802 char * iname;
3803 const char * ext;
3804 char extnii[5] = ".nii"; /* modifiable, for possible uppercase */
3805 char exthdr[5] = ".hdr";
3806 char extimg[5] = ".img";
3807 char extnia[5] = ".nia";
3808 char extgz[5] = ".gz";
3809
3810 if( !nifti_validfilename(prefix) ) return NULL;
3811
3812 /* add space for extension, optional ".gz", and null char */
3813 iname = (char *)calloc(sizeof(char),strlen(prefix)+8);
3814 if( !iname ){ fprintf(stderr,"** small malloc failure!\n"); return NULL; }
3815 strcpy(iname, prefix);
3816
3817 /* use any valid extension */
3818 if( (ext = nifti_find_file_extension(iname)) != NULL ){
3819 /* if uppercase, convert all extensions */
3820 if( is_uppercase(ext) ) {
3821 make_uppercase(extnii);
3822 make_uppercase(exthdr);
3823 make_uppercase(extimg);
3824 make_uppercase(extnia);
3825 make_uppercase(extgz);
3826 }
3827
3828 if( strncmp(ext,extimg,4) == 0 )
3829 {
3830 memcpy(&(iname[strlen(iname)-strlen(ext)]),exthdr,4); /* then convert img name to hdr */
3831 }
3832 }
3833 /* otherwise, make one up */
3834 else if( nifti_type == NIFTI_FTYPE_NIFTI1_1 ) strcat(iname, extnii);
3835 else if( nifti_type == NIFTI_FTYPE_ASCII ) strcat(iname, extnia);
3836 else strcat(iname, exthdr);
3837
3838 #ifdef HAVE_ZLIB /* if compression is requested, make sure of suffix */
3839 if( comp && (!ext || !strstr(iname,extgz)) ) strcat(iname,extgz);
3840 #endif
3841
3842 /* check for existence failure */
3843 if( check && nifti_fileexists(iname) ){
3844 fprintf(stderr,"** failure: header file '%s' already exists\n",iname);
3845 free(iname);
3846 return NULL;
3847 }
3848
3849 if(g_opts.debug > 2) fprintf(stderr,"+d made header filename '%s'\n", iname);
3850
3851 return iname;
3852 }
3853
3854
3855 /*----------------------------------------------------------------------*/
3856 /*! creates a filename for storing the image, based on nifti_type
3857
3858 \param prefix - this will be copied before the suffix is added
3859 \param nifti_type - determines the extension, unless provided by prefix
3860 \param check - check for existence (fail condition)
3861 \param comp - add .gz for compressed name
3862
3863 Note that if prefix provides a file suffix, nifti_type is not used.
3864
3865 NB: it allocates memory which should be freed
3866
3867 \sa nifti_set_filenames
3868 *//*-------------------------------------------------------------------*/
nifti_makeimgname(const char * prefix,int nifti_type,int check,int comp)3869 char * nifti_makeimgname(const char * prefix, int nifti_type, int check,
3870 int comp)
3871 {
3872 char * iname;
3873 const char * ext;
3874 char extnii[5] = ".nii"; /* modifiable, for possible uppercase */
3875 char exthdr[5] = ".hdr";
3876 char extimg[5] = ".img";
3877 char extnia[5] = ".nia";
3878 char extgz[5] = ".gz";
3879
3880 if( !nifti_validfilename(prefix) ) return NULL;
3881
3882 /* add space for extension, optional ".gz", and null char */
3883 iname = (char *)calloc(sizeof(char),strlen(prefix)+8);
3884 if( !iname ){ fprintf(stderr,"** small malloc failure!\n"); return NULL; }
3885 strcpy(iname, prefix);
3886
3887 /* use any valid extension */
3888 if( (ext = nifti_find_file_extension(iname)) != NULL ){
3889 /* if uppercase, convert all extensions */
3890 if( is_uppercase(ext) ) {
3891 make_uppercase(extnii);
3892 make_uppercase(exthdr);
3893 make_uppercase(extimg);
3894 make_uppercase(extnia);
3895 make_uppercase(extgz);
3896 }
3897
3898 if( strncmp(ext,exthdr,4) == 0 )
3899 {
3900 memcpy(&(iname[strlen(iname)-strlen(ext)]),extimg,4); /* then convert hdr name to img */
3901 }
3902 }
3903 /* otherwise, make one up */
3904 else if( nifti_type == NIFTI_FTYPE_NIFTI1_1 ) strcat(iname, extnii);
3905 else if( nifti_type == NIFTI_FTYPE_ASCII ) strcat(iname, extnia);
3906 else strcat(iname, extimg);
3907
3908 #ifdef HAVE_ZLIB /* if compression is requested, make sure of suffix */
3909 if( comp && (!ext || !strstr(iname,extgz)) ) strcat(iname,extgz);
3910 #endif
3911
3912 /* check for existence failure */
3913 if( check && nifti_fileexists(iname) ){
3914 fprintf(stderr,"** failure: image file '%s' already exists\n",iname);
3915 free(iname);
3916 return NULL;
3917 }
3918
3919 if( g_opts.debug > 2 ) fprintf(stderr,"+d made image filename '%s'\n",iname);
3920
3921 return iname;
3922 }
3923
3924
3925 /*----------------------------------------------------------------------*/
3926 /*! create and set new filenames, based on prefix and image type
3927
3928 \param nim pointer to nifti_image in which to set filenames
3929 \param prefix (required) prefix for output filenames
3930 \param check check for previous existence of filename
3931 (existence is an error condition)
3932 \param set_byte_order flag to set nim->byteorder here
3933 (this is probably a logical place to do so)
3934
3935 \return 0 on successful update
3936
3937 \warning this will free() any existing names and create new ones
3938
3939 \sa nifti_makeimgname, nifti_makehdrname, nifti_type_and_names_match
3940 *//*--------------------------------------------------------------------*/
nifti_set_filenames(nifti_image * nim,const char * prefix,int check,int set_byte_order)3941 int nifti_set_filenames( nifti_image * nim, const char * prefix, int check,
3942 int set_byte_order )
3943 {
3944 int comp = nifti_is_gzfile(prefix);
3945
3946 if( !nim || !prefix ){
3947 fprintf(stderr,"** nifti_set_filenames, bad params %p, %p\n",
3948 (void *)nim,prefix);
3949 return -1;
3950 }
3951
3952 if( g_opts.debug > 1 )
3953 fprintf(stderr,"+d modifying output filenames using prefix %s\n", prefix);
3954
3955 /* set and test output filenames */
3956 if( nim->fname ) free(nim->fname);
3957 if( nim->iname ) free(nim->iname);
3958 nim->iname = NULL;
3959 nim->fname = nifti_makehdrname(prefix, nim->nifti_type, check, comp);
3960 if( nim->fname )
3961 nim->iname = nifti_makeimgname(prefix, nim->nifti_type, check, comp);
3962 if( !nim->fname || !nim->iname ) return -1; /* failure */
3963
3964 if( set_byte_order ) nim->byteorder = nifti_short_order() ;
3965
3966 if( nifti_set_type_from_names(nim) < 0 )
3967 return -1;
3968
3969 if( g_opts.debug > 2 )
3970 fprintf(stderr,"+d have new filenames %s and %s\n",nim->fname,nim->iname);
3971
3972 return 0;
3973 }
3974
3975
3976 /*--------------------------------------------------------------------------*/
3977 /*! check whether nifti_type matches fname and iname for the nifti_image
3978
3979 - if type 0 or 2, expect .hdr/.img pair
3980 - if type 1, expect .nii (and names must match)
3981
3982 \param nim given nifti_image
3983 \param show_warn if set, print a warning message for any mis-match
3984
3985 \return
3986 - 1 if the values seem to match
3987 - 0 if there is a mis-match
3988 - -1 if there is not sufficient information to create file(s)
3989
3990 \sa NIFTI_FTYPE_* codes in nifti1_io.h
3991 \sa nifti_set_type_from_names, is_valid_nifti_type
3992 *//*------------------------------------------------------------------------*/
nifti_type_and_names_match(nifti_image * nim,int show_warn)3993 int nifti_type_and_names_match( nifti_image * nim, int show_warn )
3994 {
3995 char func[] = "nifti_type_and_names_match";
3996 const char * ext_h; /* header filename extension */
3997 const char * ext_i; /* image filename extension */
3998 int errs = 0; /* error counter */
3999
4000 /* sanity checks */
4001 if( !nim ){
4002 if( show_warn ) fprintf(stderr,"** %s: missing nifti_image\n", func);
4003 return -1;
4004 }
4005 if( !nim->fname ){
4006 if( show_warn ) fprintf(stderr,"** %s: missing header filename\n", func);
4007 errs++;
4008 }
4009 if( !nim->iname ){
4010 if( show_warn ) fprintf(stderr,"** %s: missing image filename\n", func);
4011 errs++;
4012 }
4013 if( !is_valid_nifti_type(nim->nifti_type) ){
4014 if( show_warn )
4015 fprintf(stderr,"** %s: bad nifti_type %d\n", func, nim->nifti_type);
4016 errs++;
4017 }
4018
4019 if( errs ) return -1; /* then do not proceed */
4020
4021 /* get pointers to extensions */
4022 ext_h = nifti_find_file_extension( nim->fname );
4023 ext_i = nifti_find_file_extension( nim->iname );
4024
4025 /* check for filename extensions */
4026 if( !ext_h ){
4027 if( show_warn )
4028 fprintf(stderr,"-d missing NIFTI extension in header filename, %s\n",
4029 nim->fname);
4030 errs++;
4031 }
4032 if( !ext_i ){
4033 if( show_warn )
4034 fprintf(stderr,"-d missing NIFTI extension in image filename, %s\n",
4035 nim->iname);
4036 errs++;
4037 }
4038
4039 if( errs ) return 0; /* do not proceed, but this is just a mis-match */
4040
4041 /* general tests */
4042 if( nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ){ /* .nii */
4043 if( fileext_n_compare(ext_h,".nii",4) ) {
4044 if( show_warn )
4045 fprintf(stderr,
4046 "-d NIFTI_FTYPE 1, but no .nii extension in header filename, %s\n",
4047 nim->fname);
4048 errs++;
4049 }
4050 if( fileext_n_compare(ext_i,".nii",4) ) {
4051 if( show_warn )
4052 fprintf(stderr,
4053 "-d NIFTI_FTYPE 1, but no .nii extension in image filename, %s\n",
4054 nim->iname);
4055 errs++;
4056 }
4057 if( strcmp(nim->fname, nim->iname) != 0 ){
4058 if( show_warn )
4059 fprintf(stderr,
4060 "-d NIFTI_FTYPE 1, but header and image filenames differ: %s, %s\n",
4061 nim->fname, nim->iname);
4062 errs++;
4063 }
4064 }
4065 else if( (nim->nifti_type == NIFTI_FTYPE_NIFTI1_2) || /* .hdr/.img */
4066 (nim->nifti_type == NIFTI_FTYPE_ANALYZE) )
4067 {
4068 if( fileext_n_compare(ext_h,".hdr",4) != 0 ){
4069 if( show_warn )
4070 fprintf(stderr,"-d no '.hdr' extension, but NIFTI type is %d, %s\n",
4071 nim->nifti_type, nim->fname);
4072 errs++;
4073 }
4074 if( fileext_n_compare(ext_i,".img",4) != 0 ){
4075 if( show_warn )
4076 fprintf(stderr,"-d no '.img' extension, but NIFTI type is %d, %s\n",
4077 nim->nifti_type, nim->iname);
4078 errs++;
4079 }
4080 }
4081 /* ignore any other nifti_type */
4082
4083 return 1;
4084 }
4085
4086 /* like strcmp, but also check against capitalization of known_ext
4087 * (test as local string, with max length 7) */
fileext_compare(const char * test_ext,const char * known_ext)4088 static int fileext_compare(const char * test_ext, const char * known_ext)
4089 {
4090 char caps[8] = "";
4091 size_t c,len;
4092 /* if equal, don't need to check case (store to avoid multiple calls) */
4093 const int cmp = strcmp(test_ext, known_ext);
4094 if( cmp == 0 ) return cmp;
4095
4096 /* if anything odd, use default */
4097 if( !test_ext || !known_ext ) return cmp;
4098
4099 len = strlen(known_ext);
4100 if( len > 7 ) return cmp;
4101
4102 /* if here, strings are different but need to check upper-case */
4103
4104 for(c = 0; c < len; c++ ) caps[c] = toupper((int) known_ext[c]);
4105 caps[c] = '\0';
4106
4107 return strcmp(test_ext, caps);
4108 }
4109
4110 /* like strncmp, but also check against capitalization of known_ext
4111 * (test as local string, with max length 7) */
fileext_n_compare(const char * test_ext,const char * known_ext,size_t maxlen)4112 static int fileext_n_compare(const char * test_ext,
4113 const char * known_ext, size_t maxlen)
4114 {
4115 char caps[8] = "";
4116 size_t c,len;
4117 /* if equal, don't need to check case (store to avoid multiple calls) */
4118 const int cmp = strncmp(test_ext, known_ext, maxlen);
4119 if( cmp == 0 ) return cmp;
4120
4121 /* if anything odd, use default */
4122 if( !test_ext || !known_ext ) return cmp;
4123
4124 len = strlen(known_ext);
4125 if( len > maxlen ) len = maxlen; /* ignore anything past maxlen */
4126 if( len > 7 ) return cmp;
4127
4128 /* if here, strings are different but need to check upper-case */
4129 for(c = 0; c < len; c++ ) caps[c] = toupper((int) known_ext[c]);
4130 caps[c] = '\0';
4131
4132 return strncmp(test_ext, caps, maxlen);
4133 }
4134
4135 /* return 1 if there are uppercase but no lowercase */
is_uppercase(const char * str)4136 static int is_uppercase(const char * str)
4137 {
4138 size_t c;
4139 int hasupper = 0;
4140
4141 if( !str || !*str ) return 0;
4142
4143 for(c = 0; c < strlen(str); c++ ) {
4144 if( islower((int) str[c]) ) return 0;
4145 if( !hasupper && isupper((int) str[c]) ) hasupper = 1;
4146 }
4147
4148 return hasupper;
4149 }
4150
4151 /* return 1 if there are both uppercase and lowercase characters */
is_mixedcase(const char * str)4152 static int is_mixedcase(const char * str)
4153 {
4154 size_t c;
4155 int hasupper = 0, haslower = 0;
4156
4157 if( !str || !*str ) return 0;
4158
4159 for(c = 0; c < strlen(str); c++ ) {
4160 if( !haslower && islower((int) str[c]) ) haslower = 1;
4161 if( !hasupper && isupper((int) str[c]) ) hasupper = 1;
4162
4163 if( haslower && hasupper ) return 1;
4164 }
4165
4166 return 0;
4167 }
4168
4169 /* convert any lowercase chars to uppercase */
make_uppercase(char * str)4170 static int make_uppercase(char * str)
4171 {
4172 size_t c;
4173
4174 if( !str || !*str ) return 0;
4175
4176 for(c = 0; c < strlen(str); c++ )
4177 if( islower((int) str[c]) ) str[c] = toupper((int) str[c]);
4178
4179 return 0;
4180 }
4181
4182 /* convert any uppercase chars to lowercase */
make_lowercase(char * str)4183 static int make_lowercase(char * str)
4184 {
4185 size_t c;
4186 if( !str || !*str ) return 0;
4187
4188 for(c = 0; c < strlen(str); c++ )
4189 if( isupper((int) str[c]) ) str[c] = tolower((int) str[c]);
4190
4191 return 0;
4192 }
4193
4194 /* run strcmp against of list of strings
4195 * return index of equality, if found
4196 * else return -1 */
compare_strlist(const char * str,char ** strlist,int len)4197 static int compare_strlist(const char * str, char ** strlist, int len)
4198 {
4199 int c;
4200 if( len <= 0 || !str || !strlist ) return -1;
4201 for( c = 0; c < len; c++ )
4202 if( strlist[c] && !strcmp(str, strlist[c]) ) return c;
4203 return -1;
4204 }
4205
4206 /*--------------------------------------------------------------------------*/
4207 /*! check whether the given type is on the "approved" list
4208
4209 The code is valid if it is non-negative, and does not exceed
4210 NIFTI_MAX_FTYPE.
4211
4212 \return 1 if nifti_type is valid, 0 otherwise
4213 \sa NIFTI_FTYPE_* codes in nifti1_io.h
4214 *//*------------------------------------------------------------------------*/
is_valid_nifti_type(int nifti_type)4215 int is_valid_nifti_type( int nifti_type )
4216 {
4217 if( nifti_type >= NIFTI_FTYPE_ANALYZE && /* smallest type, 0 */
4218 nifti_type <= NIFTI_MAX_FTYPE )
4219 return 1;
4220 return 0;
4221 }
4222
4223
4224 /*--------------------------------------------------------------------------*/
4225 /*! check whether the given type is on the "approved" list
4226
4227 The type is explicitly checked against the NIFTI_TYPE_* list
4228 in nifti1.h.
4229
4230 \return 1 if dtype is valid, 0 otherwise
4231 \sa NIFTI_TYPE_* codes in nifti1.h
4232 *//*------------------------------------------------------------------------*/
nifti_is_valid_datatype(int dtype)4233 int nifti_is_valid_datatype( int dtype )
4234 {
4235 if( dtype == NIFTI_TYPE_UINT8 ||
4236 dtype == NIFTI_TYPE_INT16 ||
4237 dtype == NIFTI_TYPE_INT32 ||
4238 dtype == NIFTI_TYPE_FLOAT32 ||
4239 dtype == NIFTI_TYPE_COMPLEX64 ||
4240 dtype == NIFTI_TYPE_FLOAT64 ||
4241 dtype == NIFTI_TYPE_RGB24 ||
4242 dtype == NIFTI_TYPE_RGBA32 ||
4243 dtype == NIFTI_TYPE_INT8 ||
4244 dtype == NIFTI_TYPE_UINT16 ||
4245 dtype == NIFTI_TYPE_UINT32 ||
4246 dtype == NIFTI_TYPE_INT64 ||
4247 dtype == NIFTI_TYPE_UINT64 ||
4248 dtype == NIFTI_TYPE_FLOAT128 ||
4249 dtype == NIFTI_TYPE_COMPLEX128 ||
4250 dtype == NIFTI_TYPE_COMPLEX256 ) return 1;
4251 return 0;
4252 }
4253
4254
4255 /*--------------------------------------------------------------------------*/
4256 /*! set the nifti_type field based on fname and iname
4257
4258 Note that nifti_type is changed only when it does not match
4259 the filenames.
4260
4261 \return 0 on success, -1 on error
4262
4263 \sa is_valid_nifti_type, nifti_type_and_names_match
4264 *//*------------------------------------------------------------------------*/
nifti_set_type_from_names(nifti_image * nim)4265 int nifti_set_type_from_names( nifti_image * nim )
4266 {
4267 /* error checking first */
4268 if( !nim ){ fprintf(stderr,"** NSTFN: no nifti_image\n"); return -1; }
4269
4270 if( !nim->fname || !nim->iname ){
4271 fprintf(stderr,"** NSTFN: missing filename(s) fname @ %p, iname @ %p\n",
4272 nim->fname, nim->iname);
4273 return -1;
4274 }
4275
4276 if( ! nifti_validfilename ( nim->fname ) ||
4277 ! nifti_validfilename ( nim->iname ) ||
4278 ! nifti_find_file_extension( nim->fname ) ||
4279 ! nifti_find_file_extension( nim->iname )
4280 ) {
4281 fprintf(stderr,"** NSTFN: invalid filename(s) fname='%s', iname='%s'\n",
4282 nim->fname, nim->iname);
4283 return -1;
4284 }
4285
4286 if( g_opts.debug > 2 )
4287 fprintf(stderr,"-d verify nifti_type from filenames: %d",nim->nifti_type);
4288
4289 /* type should be NIFTI_FTYPE_ASCII if extension is .nia */
4290 if( (fileext_compare(nifti_find_file_extension(nim->fname),".nia")==0)){
4291 nim->nifti_type = NIFTI_FTYPE_ASCII;
4292 } else {
4293 /* not too picky here, do what must be done, and then verify */
4294 if( strcmp(nim->fname, nim->iname) == 0 ) /* one file, type 1 */
4295 nim->nifti_type = NIFTI_FTYPE_NIFTI1_1;
4296 else if( nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ) /* cannot be type 1 */
4297 nim->nifti_type = NIFTI_FTYPE_NIFTI1_2;
4298 }
4299
4300 if( g_opts.debug > 2 ) fprintf(stderr," -> %d\n",nim->nifti_type);
4301
4302 if( g_opts.debug > 1 ) /* warn user about anything strange */
4303 nifti_type_and_names_match(nim, 1);
4304
4305 if( is_valid_nifti_type(nim->nifti_type) ) return 0; /* success! */
4306
4307 fprintf(stderr,"** NSTFN: bad nifti_type %d, for '%s' and '%s'\n",
4308 nim->nifti_type, nim->fname, nim->iname);
4309
4310 return -1;
4311 }
4312
4313
4314 /*--------------------------------------------------------------------------*/
4315 /*! Determine if this is a NIFTI-formatted file.
4316
4317 <pre>
4318 \return 0 if file looks like ANALYZE 7.5 [checks sizeof_hdr field == 348]
4319 1 if file marked as NIFTI (header+data in 1 file)
4320 2 if file marked as NIFTI (header+data in 2 files)
4321 -1 if it can't tell, file doesn't exist, etc.
4322 </pre>
4323 *//*------------------------------------------------------------------------*/
is_nifti_file(const char * hname)4324 int is_nifti_file( const char *hname )
4325 {
4326 nifti_1_header nhdr ;
4327 znzFile fp ;
4328 int ii ;
4329 char *tmpname;
4330
4331 /* rcr - update to check for nifti-1 or -2 */
4332
4333 /* bad input name? */
4334
4335 if( !nifti_validfilename(hname) ) return -1 ;
4336
4337 /* open file */
4338
4339 tmpname = nifti_findhdrname(hname);
4340 if( tmpname == NULL ){
4341 if( g_opts.debug > 0 )
4342 fprintf(stderr,"** no header file found for '%s'\n",hname);
4343 return -1;
4344 }
4345 fp = znzopen( tmpname , "rb" , nifti_is_gzfile(tmpname) ) ;
4346 free(tmpname);
4347 if (znz_isnull(fp)) return -1 ; /* bad open? */
4348
4349 /* read header, close file */
4350
4351 ii = (int)znzread( &nhdr , 1 , sizeof(nhdr) , fp ) ;
4352 znzclose( fp ) ;
4353 if( ii < (int) sizeof(nhdr) ) return -1 ; /* bad read? */
4354
4355 /* check for NIFTI-ness */
4356
4357 if( NIFTI_VERSION(nhdr) != 0 ){
4358 return ( NIFTI_ONEFILE(nhdr) ) ? 1 : 2 ;
4359 }
4360
4361 /* check for ANALYZE-ness (sizeof_hdr field == 348) */
4362
4363 ii = nhdr.sizeof_hdr ;
4364 if( ii == (int)sizeof(nhdr) ) return 0 ; /* matches */
4365
4366 /* try byte-swapping header */
4367
4368 swap_4(ii) ;
4369 if( ii == (int)sizeof(nhdr) ) return 0 ; /* matches */
4370
4371 return -1 ; /* not good */
4372 }
4373
print_hex_vals(const char * data,int nbytes,FILE * fp)4374 static int print_hex_vals( const char * data, int nbytes, FILE * fp )
4375 {
4376 int c;
4377
4378 if ( !data || nbytes < 1 || !fp ) return -1;
4379
4380 fputs("0x", fp);
4381 for ( c = 0; c < nbytes; c++ )
4382 fprintf(fp, " %02x", data[c]);
4383
4384 return 0;
4385 }
4386
4387 /*----------------------------------------------------------------------*/
4388 /*! display the contents of the nifti_1_header (send to stdout)
4389
4390 \param info if non-NULL, print this character string
4391 \param hp pointer to nifti_1_header
4392 *//*--------------------------------------------------------------------*/
disp_nifti_1_header(const char * info,const nifti_1_header * hp)4393 int disp_nifti_1_header( const char * info, const nifti_1_header * hp )
4394 {
4395 int c;
4396
4397 fputs( "-------------------------------------------------------\n", stdout );
4398 if ( info ) fputs( info, stdout );
4399 if ( !hp ){ fputs(" ** no nifti_1_header to display!\n",stdout); return 1; }
4400
4401 fprintf(stdout," nifti_1_header :\n"
4402 " sizeof_hdr = %d\n"
4403 " data_type[10] = ", hp->sizeof_hdr);
4404 print_hex_vals(hp->data_type, 10, stdout);
4405 fprintf(stdout, "\n"
4406 " db_name[18] = ");
4407 print_hex_vals(hp->db_name, 18, stdout);
4408 fprintf(stdout, "\n"
4409 " extents = %d\n"
4410 " session_error = %d\n"
4411 " regular = 0x%x\n"
4412 " dim_info = 0x%x\n",
4413 hp->extents, hp->session_error, hp->regular, hp->dim_info );
4414 fprintf(stdout, " dim[8] =");
4415 for ( c = 0; c < 8; c++ ) fprintf(stdout," %d", hp->dim[c]);
4416 fprintf(stdout, "\n"
4417 " intent_p1 = %f\n"
4418 " intent_p2 = %f\n"
4419 " intent_p3 = %f\n"
4420 " intent_code = %d\n"
4421 " datatype = %d\n"
4422 " bitpix = %d\n"
4423 " slice_start = %d\n"
4424 " pixdim[8] =",
4425 hp->intent_p1, hp->intent_p2, hp->intent_p3, hp->intent_code,
4426 hp->datatype, hp->bitpix, hp->slice_start);
4427 /* break pixdim over 2 lines */
4428 for ( c = 0; c < 4; c++ ) fprintf(stdout," %f", hp->pixdim[c]);
4429 fprintf(stdout, "\n ");
4430 for ( c = 4; c < 8; c++ ) fprintf(stdout," %f", hp->pixdim[c]);
4431 fprintf(stdout, "\n"
4432 " vox_offset = %f\n"
4433 " scl_slope = %f\n"
4434 " scl_inter = %f\n"
4435 " slice_end = %d\n"
4436 " slice_code = %d\n"
4437 " xyzt_units = 0x%x\n"
4438 " cal_max = %f\n"
4439 " cal_min = %f\n"
4440 " slice_duration = %f\n"
4441 " toffset = %f\n"
4442 " glmax = %d\n"
4443 " glmin = %d\n",
4444 hp->vox_offset, hp->scl_slope, hp->scl_inter, hp->slice_end,
4445 hp->slice_code, hp->xyzt_units, hp->cal_max, hp->cal_min,
4446 hp->slice_duration, hp->toffset, hp->glmax, hp->glmin);
4447 fprintf(stdout,
4448 " descrip = '%.80s'\n"
4449 " aux_file = '%.24s'\n"
4450 " qform_code = %d\n"
4451 " sform_code = %d\n"
4452 " quatern_b = %f\n"
4453 " quatern_c = %f\n"
4454 " quatern_d = %f\n"
4455 " qoffset_x = %f\n"
4456 " qoffset_y = %f\n"
4457 " qoffset_z = %f\n"
4458 " srow_x[4] = %f, %f, %f, %f\n"
4459 " srow_y[4] = %f, %f, %f, %f\n"
4460 " srow_z[4] = %f, %f, %f, %f\n"
4461 " intent_name = '%-.16s'\n"
4462 " magic = '%-.4s'\n",
4463 hp->descrip, hp->aux_file, hp->qform_code, hp->sform_code,
4464 hp->quatern_b, hp->quatern_c, hp->quatern_d,
4465 hp->qoffset_x, hp->qoffset_y, hp->qoffset_z,
4466 hp->srow_x[0], hp->srow_x[1], hp->srow_x[2], hp->srow_x[3],
4467 hp->srow_y[0], hp->srow_y[1], hp->srow_y[2], hp->srow_y[3],
4468 hp->srow_z[0], hp->srow_z[1], hp->srow_z[2], hp->srow_z[3],
4469 hp->intent_name, hp->magic);
4470 fputs( "-------------------------------------------------------\n", stdout );
4471 fflush(stdout);
4472
4473 return 0;
4474 }
4475
4476
4477 /*----------------------------------------------------------------------*/
4478 /*! display the contents of the nifti_2_header (send to stdout)
4479
4480 \param info if non-NULL, print this character string
4481 \param hp pointer to nifti_2_header
4482 *//*--------------------------------------------------------------------*/
disp_nifti_2_header(const char * info,const nifti_2_header * hp)4483 int disp_nifti_2_header( const char * info, const nifti_2_header * hp )
4484 {
4485 FILE * fp = stdout;
4486 int c;
4487
4488 fputs( "-------------------------------------------------------\n", fp );
4489 if ( info ) fputs( info, fp );
4490 if ( !hp ){ fputs(" ** no nifti_2_header to display!\n",fp); return 1; }
4491
4492 /* print fields one by one, makes changing order and copying easier */
4493
4494 fprintf(fp," nifti_2_header :\n");
4495 fprintf(fp," sizeof_hdr = %d\n", hp->sizeof_hdr);
4496 fprintf(fp," magic[8] = '%-.4s' + ", hp->magic);
4497 print_hex_vals(hp->magic+4, 4, fp); fputc('\n', fp);
4498
4499 fprintf(fp," datatype = %d (%s)\n",
4500 hp->datatype, nifti_datatype_to_string(hp->datatype));
4501 fprintf(fp," bitpix = %d\n", hp->bitpix);
4502 fprintf(fp, " dim[8] =");
4503 for ( c = 0; c < 8; c++ ) fprintf(fp," %" PRId64 "", hp->dim[c]);
4504 fputc('\n', fp);
4505
4506 fprintf(fp, " intent_p1 = %lf\n", hp->intent_p1);
4507 fprintf(fp, " intent_p2 = %lf\n", hp->intent_p2);
4508 fprintf(fp, " intent_p3 = %lf\n", hp->intent_p3);
4509 fprintf(fp, " pixdim[8] =");
4510 for ( c = 0; c < 8; c++ ) fprintf(fp," %lf", hp->pixdim[c]);
4511 fputc('\n', fp);
4512
4513 fprintf(fp, " vox_offset = %" PRId64 "\n", hp->vox_offset);
4514
4515 fprintf(fp, " scl_slope = %lf\n", hp->scl_slope);
4516 fprintf(fp, " scl_inter = %lf\n", hp->scl_inter);
4517 fprintf(fp, " cal_max = %lf\n", hp->cal_max);
4518 fprintf(fp, " cal_min = %lf\n", hp->cal_min);
4519 fprintf(fp, " slice_duration = %lf\n", hp->slice_duration);
4520 fprintf(fp, " toffset = %lf\n", hp->toffset);
4521
4522 fprintf(fp, " slice_start = %" PRId64 "\n", hp->slice_start);
4523 fprintf(fp, " slice_end = %" PRId64 "\n", hp->slice_end);
4524
4525 fprintf(fp, " descrip = '%.80s'\n", hp->descrip);
4526 fprintf(fp, " aux_file = '%.24s'\n", hp->aux_file);
4527
4528 fprintf(fp, " qform_code = %d\n", hp->qform_code);
4529 fprintf(fp, " sform_code = %d\n", hp->sform_code);
4530
4531 fprintf(fp, " quatern_b = %lf\n", hp->quatern_b);
4532 fprintf(fp, " quatern_c = %lf\n", hp->quatern_c);
4533 fprintf(fp, " quatern_d = %lf\n", hp->quatern_d);
4534 fprintf(fp, " qoffset_x = %lf\n", hp->qoffset_x);
4535 fprintf(fp, " qoffset_y = %lf\n", hp->qoffset_y);
4536 fprintf(fp, " qoffset_z = %lf\n", hp->qoffset_z);
4537 fprintf(fp, " srow_x[4] = %lf, %lf, %lf, %lf\n",
4538 hp->srow_x[0], hp->srow_x[1], hp->srow_x[2], hp->srow_x[3]);
4539 fprintf(fp, " srow_y[4] = %lf, %lf, %lf, %lf\n",
4540 hp->srow_y[0], hp->srow_y[1], hp->srow_y[2], hp->srow_y[3]);
4541 fprintf(fp, " srow_z[4] = %lf, %lf, %lf, %lf\n",
4542 hp->srow_z[0], hp->srow_z[1], hp->srow_z[2], hp->srow_z[3]);
4543
4544 fprintf(fp, " slice_code = %d\n", hp->slice_code);
4545 fprintf(fp, " xyzt_units = %d\n", hp->xyzt_units);
4546 fprintf(fp, " intent_code = %d\n", hp->intent_code);
4547
4548 fprintf(fp, " intent_name = '%-.16s'\n", hp->intent_name);
4549 fprintf(fp, " dim_info = 0x%02x\n",(unsigned char)hp->dim_info);
4550 fprintf(fp, " unused_str = 0x ");
4551 for ( c = 0; c < 15; c++ ) fprintf(fp," %02x", hp->unused_str[c]);
4552 fputc('\n', fp);
4553
4554 fputs( "-------------------------------------------------------\n", fp );
4555 fflush(fp);
4556
4557 return 0;
4558 }
4559
4560
4561 #undef ERREX
4562 #define ERREX(msg) \
4563 do{ fprintf(stderr,"** ERROR: nifti_convert_n1hdr2nim: %s\n", (msg) ) ; \
4564 return NULL ; } while(0)
4565
4566 /*----------------------------------------------------------------------*/
4567 /*! convert a nifti_1_header into a nift1_image
4568
4569 \return an allocated nifti_image, or NULL on failure
4570 *//*--------------------------------------------------------------------*/
nifti_convert_n1hdr2nim(nifti_1_header nhdr,const char * fname)4571 nifti_image* nifti_convert_n1hdr2nim(nifti_1_header nhdr, const char * fname)
4572 {
4573 int ii , doswap , ioff ;
4574 int ni_ver , is_onefile ;
4575 nifti_image *nim;
4576
4577 nim = (nifti_image *)calloc( 1 , sizeof(nifti_image) ) ;
4578 if( !nim ) ERREX("failed to allocate nifti image");
4579
4580 /* be explicit with pointers */
4581 nim->fname = NULL;
4582 nim->iname = NULL;
4583 nim->data = NULL;
4584
4585 /**- check if we must swap bytes */
4586
4587 doswap = need_nhdr_swap(nhdr.dim[0], nhdr.sizeof_hdr); /* swap data flag */
4588
4589 if( doswap < 0 ){
4590 free(nim);
4591 if( doswap == -1 ) ERREX("bad dim[0]") ;
4592 ERREX("bad sizeof_hdr") ; /* else */
4593 }
4594
4595 /**- determine if this is a NIFTI-1 compliant header */
4596
4597 ni_ver = NIFTI_VERSION(nhdr) ;
4598 /*
4599 * before swapping header, record the Analyze75 orient code
4600 */
4601 if(ni_ver == 0)
4602 {
4603 /**- in analyze75, the orient code is at the same address as
4604 * qform_code, but it's just one byte
4605 * the qform_code will be zero, at which point you can check
4606 * analyze75_orient if you care to.
4607 */
4608 unsigned char c = *((char *)(&nhdr.qform_code));
4609 nim->analyze75_orient = (analyze_75_orient_code)c;
4610 }
4611 if( doswap ) {
4612 if ( g_opts.debug > 3 ) disp_nifti_1_header("-d ni1 pre-swap: ", &nhdr);
4613 swap_nifti_header( &nhdr , ni_ver ) ;
4614 }
4615
4616 if ( g_opts.debug > 2 ) disp_nifti_1_header("-d nhdr2nim : ", &nhdr);
4617
4618 if( nhdr.datatype == DT_BINARY || nhdr.datatype == DT_UNKNOWN )
4619 {
4620 free(nim);
4621 ERREX("bad datatype") ;
4622 }
4623
4624 if( nhdr.dim[1] <= 0 )
4625 {
4626 free(nim);
4627 ERREX("bad dim[1]") ;
4628 }
4629
4630 /* fix bad dim[] values in the defined dimension range */
4631 for( ii=2 ; ii <= nhdr.dim[0] ; ii++ )
4632 if( nhdr.dim[ii] <= 0 ) nhdr.dim[ii] = 1 ;
4633
4634 /* fix any remaining bad dim[] values, so garbage does not propagate */
4635 /* (only values 0 or 1 seem rational, otherwise set to arbirary 1) */
4636 for( ii=nhdr.dim[0]+1 ; ii <= 7 ; ii++ )
4637 if( nhdr.dim[ii] != 1 && nhdr.dim[ii] != 0) nhdr.dim[ii] = 1 ;
4638
4639 #if 0 /* rely on dim[0], do not attempt to modify it 16 Nov 2005 [rickr] */
4640
4641 /**- get number of dimensions (ignoring dim[0] now) */
4642 for( ii=7 ; ii >= 2 ; ii-- ) /* loop backwards until we */
4643 if( nhdr.dim[ii] > 1 ) break ; /* find a dim bigger than 1 */
4644 ndim = ii ;
4645 #endif
4646
4647 /**- set bad grid spacings to 1.0 */
4648
4649 for( ii=1 ; ii <= nhdr.dim[0] ; ii++ ){
4650 if( nhdr.pixdim[ii] == 0.0 ||
4651 !IS_GOOD_FLOAT(nhdr.pixdim[ii]) ) nhdr.pixdim[ii] = 1.0f ;
4652 }
4653
4654 is_onefile = (ni_ver > 0) && NIFTI_ONEFILE(nhdr) ;
4655
4656 if( ni_ver ) nim->nifti_type = (is_onefile) ? NIFTI_FTYPE_NIFTI1_1
4657 : NIFTI_FTYPE_NIFTI1_2 ;
4658 else nim->nifti_type = NIFTI_FTYPE_ANALYZE ;
4659
4660 ii = nifti_short_order() ;
4661 if( doswap ) nim->byteorder = REVERSE_ORDER(ii) ;
4662 else nim->byteorder = ii ;
4663
4664
4665 /**- set dimensions of data array */
4666
4667 nim->ndim = nim->dim[0] = nhdr.dim[0];
4668 nim->nx = nim->dim[1] = nhdr.dim[1];
4669 nim->ny = nim->dim[2] = nhdr.dim[2];
4670 nim->nz = nim->dim[3] = nhdr.dim[3];
4671 nim->nt = nim->dim[4] = nhdr.dim[4];
4672 nim->nu = nim->dim[5] = nhdr.dim[5];
4673 nim->nv = nim->dim[6] = nhdr.dim[6];
4674 nim->nw = nim->dim[7] = nhdr.dim[7];
4675
4676 for( ii=1, nim->nvox=1; ii <= nhdr.dim[0]; ii++ )
4677 nim->nvox *= nhdr.dim[ii];
4678
4679 /**- set the type of data in voxels and how many bytes per voxel */
4680
4681 nim->datatype = nhdr.datatype ;
4682
4683 nifti_datatype_sizes( nim->datatype , &(nim->nbyper) , &(nim->swapsize) ) ;
4684 if( nim->nbyper == 0 ){ free(nim); ERREX("bad datatype"); }
4685
4686 /**- set the grid spacings */
4687
4688 nim->dx = nim->pixdim[1] = nhdr.pixdim[1] ;
4689 nim->dy = nim->pixdim[2] = nhdr.pixdim[2] ;
4690 nim->dz = nim->pixdim[3] = nhdr.pixdim[3] ;
4691 nim->dt = nim->pixdim[4] = nhdr.pixdim[4] ;
4692 nim->du = nim->pixdim[5] = nhdr.pixdim[5] ;
4693 nim->dv = nim->pixdim[6] = nhdr.pixdim[6] ;
4694 nim->dw = nim->pixdim[7] = nhdr.pixdim[7] ;
4695
4696 /**- compute qto_xyz transformation from pixel indexes (i,j,k) to (x,y,z) */
4697
4698 if( !ni_ver || nhdr.qform_code <= 0 ){
4699 /**- if not nifti or qform_code <= 0, use grid spacing for qto_xyz */
4700
4701 nim->qto_xyz.m[0][0] = nim->dx ; /* grid spacings */
4702 nim->qto_xyz.m[1][1] = nim->dy ; /* along diagonal */
4703 nim->qto_xyz.m[2][2] = nim->dz ;
4704
4705 /* off diagonal is zero */
4706
4707 nim->qto_xyz.m[0][1]=nim->qto_xyz.m[0][2]=nim->qto_xyz.m[0][3] = 0.0f;
4708 nim->qto_xyz.m[1][0]=nim->qto_xyz.m[1][2]=nim->qto_xyz.m[1][3] = 0.0f;
4709 nim->qto_xyz.m[2][0]=nim->qto_xyz.m[2][1]=nim->qto_xyz.m[2][3] = 0.0f;
4710
4711 /* last row is always [ 0 0 0 1 ] */
4712
4713 nim->qto_xyz.m[3][0]=nim->qto_xyz.m[3][1]=nim->qto_xyz.m[3][2] = 0.0f;
4714 nim->qto_xyz.m[3][3]= 1.0f ;
4715
4716 nim->qform_code = NIFTI_XFORM_UNKNOWN ;
4717
4718 if( g_opts.debug > 1 ) fprintf(stderr,"-d no qform provided\n");
4719 } else {
4720 /**- else NIFTI: use the quaternion-specified transformation */
4721
4722 nim->quatern_b = FIXED_FLOAT( nhdr.quatern_b ) ;
4723 nim->quatern_c = FIXED_FLOAT( nhdr.quatern_c ) ;
4724 nim->quatern_d = FIXED_FLOAT( nhdr.quatern_d ) ;
4725
4726 nim->qoffset_x = FIXED_FLOAT(nhdr.qoffset_x) ;
4727 nim->qoffset_y = FIXED_FLOAT(nhdr.qoffset_y) ;
4728 nim->qoffset_z = FIXED_FLOAT(nhdr.qoffset_z) ;
4729
4730 nim->qfac = (nhdr.pixdim[0] < 0.0) ? -1.0f : 1.0f ; /* left-handedness? */
4731
4732 nim->qto_xyz = nifti_quatern_to_dmat44(
4733 nim->quatern_b, nim->quatern_c, nim->quatern_d,
4734 nim->qoffset_x, nim->qoffset_y, nim->qoffset_z,
4735 nim->dx , nim->dy , nim->dz ,
4736 nim->qfac ) ;
4737
4738 nim->qform_code = nhdr.qform_code ;
4739
4740 if( g_opts.debug > 1 )
4741 nifti_disp_matrix_orient("-d qform orientations:\n", nim->qto_xyz);
4742 }
4743
4744 /**- load inverse transformation (x,y,z) -> (i,j,k) */
4745
4746 nim->qto_ijk = nifti_dmat44_inverse( nim->qto_xyz ) ;
4747
4748 /**- load sto_xyz affine transformation, if present */
4749
4750 if( !ni_ver || nhdr.sform_code <= 0 ){
4751 /**- if not nifti or sform_code <= 0, then no sto transformation */
4752
4753 nim->sform_code = NIFTI_XFORM_UNKNOWN ;
4754
4755 if( g_opts.debug > 1 ) fprintf(stderr,"-d no sform provided\n");
4756
4757 } else {
4758 /**- else set the sto transformation from srow_*[] */
4759
4760 nim->sto_xyz.m[0][0] = nhdr.srow_x[0] ;
4761 nim->sto_xyz.m[0][1] = nhdr.srow_x[1] ;
4762 nim->sto_xyz.m[0][2] = nhdr.srow_x[2] ;
4763 nim->sto_xyz.m[0][3] = nhdr.srow_x[3] ;
4764
4765 nim->sto_xyz.m[1][0] = nhdr.srow_y[0] ;
4766 nim->sto_xyz.m[1][1] = nhdr.srow_y[1] ;
4767 nim->sto_xyz.m[1][2] = nhdr.srow_y[2] ;
4768 nim->sto_xyz.m[1][3] = nhdr.srow_y[3] ;
4769
4770 nim->sto_xyz.m[2][0] = nhdr.srow_z[0] ;
4771 nim->sto_xyz.m[2][1] = nhdr.srow_z[1] ;
4772 nim->sto_xyz.m[2][2] = nhdr.srow_z[2] ;
4773 nim->sto_xyz.m[2][3] = nhdr.srow_z[3] ;
4774
4775 /* last row is always [ 0 0 0 1 ] */
4776
4777 nim->sto_xyz.m[3][0]=nim->sto_xyz.m[3][1]=nim->sto_xyz.m[3][2] = 0.0f;
4778 nim->sto_xyz.m[3][3]= 1.0f ;
4779
4780 nim->sto_ijk = nifti_dmat44_inverse( nim->sto_xyz ) ;
4781
4782 nim->sform_code = nhdr.sform_code ;
4783
4784 if( g_opts.debug > 1 )
4785 nifti_disp_matrix_orient("-d sform orientations:\n", nim->sto_xyz);
4786 }
4787
4788 /**- set miscellaneous NIFTI stuff */
4789
4790 if( ni_ver ){
4791 nim->scl_slope = FIXED_FLOAT( nhdr.scl_slope ) ;
4792 nim->scl_inter = FIXED_FLOAT( nhdr.scl_inter ) ;
4793
4794 nim->intent_code = nhdr.intent_code ;
4795
4796 nim->intent_p1 = FIXED_FLOAT( nhdr.intent_p1 ) ;
4797 nim->intent_p2 = FIXED_FLOAT( nhdr.intent_p2 ) ;
4798 nim->intent_p3 = FIXED_FLOAT( nhdr.intent_p3 ) ;
4799
4800 nim->toffset = FIXED_FLOAT( nhdr.toffset ) ;
4801
4802 memcpy(nim->intent_name,nhdr.intent_name,15); nim->intent_name[15] = '\0';
4803
4804 nim->xyz_units = XYZT_TO_SPACE(nhdr.xyzt_units) ;
4805 nim->time_units = XYZT_TO_TIME (nhdr.xyzt_units) ;
4806
4807 nim->freq_dim = DIM_INFO_TO_FREQ_DIM ( nhdr.dim_info ) ;
4808 nim->phase_dim = DIM_INFO_TO_PHASE_DIM( nhdr.dim_info ) ;
4809 nim->slice_dim = DIM_INFO_TO_SLICE_DIM( nhdr.dim_info ) ;
4810
4811 nim->slice_code = nhdr.slice_code ;
4812 nim->slice_start = nhdr.slice_start ;
4813 nim->slice_end = nhdr.slice_end ;
4814 nim->slice_duration = FIXED_FLOAT(nhdr.slice_duration) ;
4815 }
4816
4817 /**- set Miscellaneous ANALYZE stuff */
4818
4819 nim->cal_min = FIXED_FLOAT(nhdr.cal_min) ;
4820 nim->cal_max = FIXED_FLOAT(nhdr.cal_max) ;
4821
4822 memcpy(nim->descrip ,nhdr.descrip ,79) ; nim->descrip [79] = '\0' ;
4823 memcpy(nim->aux_file,nhdr.aux_file,23) ; nim->aux_file[23] = '\0' ;
4824
4825 /**- set ioff from vox_offset (but at least sizeof(header)) */
4826
4827 is_onefile = ni_ver && NIFTI_ONEFILE(nhdr) ;
4828
4829 if( is_onefile ){
4830 ioff = (int)nhdr.vox_offset ;
4831 if( ioff < (int) sizeof(nhdr) ) ioff = (int) sizeof(nhdr) ;
4832 } else {
4833 ioff = (int)nhdr.vox_offset ;
4834 }
4835 nim->iname_offset = ioff ;
4836
4837
4838 /**- deal with file names if set */
4839 if (fname!=NULL) {
4840 nifti_set_filenames(nim,fname,0,0);
4841 if (nim->iname==NULL) { ERREX("bad filename"); }
4842 } else {
4843 nim->fname = NULL;
4844 nim->iname = NULL;
4845 }
4846
4847 /* clear extension fields */
4848 nim->num_ext = 0;
4849 nim->ext_list = NULL;
4850
4851 return nim;
4852 }
4853
4854 #undef ERREX
4855 #define ERREX(msg) \
4856 do{ fprintf(stderr,"** ERROR: nifti_convert_n2hdr2nim: %s\n", (msg) ) ; \
4857 return NULL ; } while(0)
4858
4859 /*----------------------------------------------------------------------*/
4860 /*! convert a nifti_1_header into a nift1_image
4861
4862 \return an allocated nifti_image, or NULL on failure
4863 *//*--------------------------------------------------------------------*/
nifti_convert_n2hdr2nim(nifti_2_header nhdr,const char * fname)4864 nifti_image* nifti_convert_n2hdr2nim(nifti_2_header nhdr, const char * fname)
4865 {
4866 int ii, doswap, ni_ver, is_onefile;
4867 nifti_image *nim;
4868
4869 nim = (nifti_image *)calloc( 1 , sizeof(nifti_image) ) ;
4870 if( !nim ) ERREX("failed to allocate nifti image");
4871
4872 /* be explicit with pointers */
4873 nim->fname = NULL;
4874 nim->iname = NULL;
4875 nim->data = NULL;
4876
4877 /**- check if we must swap bytes */
4878
4879 doswap = NIFTI2_NEEDS_SWAP(nhdr); /* swap data flag */
4880
4881 /**- determine if this is a NIFTI-2 compliant header */
4882
4883 ni_ver = NIFTI_VERSION(nhdr) ;
4884 if(ni_ver != 2) {
4885 free(nim);
4886 fprintf(stderr,"** convert NIFTI-2 hdr2nim: bad version %d\n", ni_ver);
4887 return NULL;
4888 }
4889
4890 if( doswap ) {
4891 if ( g_opts.debug > 3 ) disp_nifti_2_header("-d n2 pre-swap: ", &nhdr);
4892 swap_nifti_header( &nhdr , ni_ver ) ;
4893 } else if ( g_opts.debug > 3 ) fprintf(stderr,"-- n2hdr2nim: no swap\n");
4894
4895 if ( g_opts.debug > 2 ) disp_nifti_2_header("-d n2hdr2nim : ", &nhdr);
4896
4897 if( nhdr.datatype == DT_BINARY || nhdr.datatype == DT_UNKNOWN )
4898 {
4899 free(nim);
4900 ERREX("bad datatype") ;
4901 }
4902
4903 if( nhdr.dim[1] <= 0 )
4904 {
4905 free(nim);
4906 ERREX("bad dim[1]") ;
4907 }
4908
4909 /* fix bad dim[] values in the defined dimension range */
4910 for( ii=2 ; ii <= nhdr.dim[0] ; ii++ )
4911 if( nhdr.dim[ii] <= 0 ) nhdr.dim[ii] = 1 ;
4912
4913 /* fix any remaining bad dim[] values, so garbage does not propagate */
4914 /* (only values 0 or 1 seem rational, otherwise set to arbirary 1) */
4915 for( ii=nhdr.dim[0]+1 ; ii <= 7 ; ii++ )
4916 if( nhdr.dim[ii] != 1 && nhdr.dim[ii] != 0) nhdr.dim[ii] = 1 ;
4917
4918 /**- set bad grid spacings to 1.0 */
4919 for( ii=1 ; ii <= nhdr.dim[0] ; ii++ ){
4920 if( nhdr.pixdim[ii] == 0.0 ||
4921 !IS_GOOD_FLOAT(nhdr.pixdim[ii]) ) nhdr.pixdim[ii] = 1.0 ;
4922 }
4923
4924 is_onefile = (ni_ver > 0) && NIFTI_ONEFILE(nhdr) ;
4925
4926 nim->nifti_type = (is_onefile) ? NIFTI_FTYPE_NIFTI1_1 : NIFTI_FTYPE_NIFTI1_2;
4927
4928 ii = nifti_short_order() ;
4929 if( doswap ) nim->byteorder = REVERSE_ORDER(ii) ;
4930 else nim->byteorder = ii ;
4931
4932
4933 /**- set dimensions of data array */
4934
4935 nim->ndim = nim->dim[0] = nhdr.dim[0];
4936 nim->nx = nim->dim[1] = nhdr.dim[1];
4937 nim->ny = nim->dim[2] = nhdr.dim[2];
4938 nim->nz = nim->dim[3] = nhdr.dim[3];
4939 nim->nt = nim->dim[4] = nhdr.dim[4];
4940 nim->nu = nim->dim[5] = nhdr.dim[5];
4941 nim->nv = nim->dim[6] = nhdr.dim[6];
4942 nim->nw = nim->dim[7] = nhdr.dim[7];
4943
4944 for( ii=1, nim->nvox=1; ii <= nhdr.dim[0]; ii++ )
4945 nim->nvox *= nhdr.dim[ii];
4946
4947 /**- set the type of data in voxels and how many bytes per voxel */
4948
4949 nim->datatype = nhdr.datatype ;
4950
4951 nifti_datatype_sizes( nim->datatype , &(nim->nbyper) , &(nim->swapsize) ) ;
4952 if( nim->nbyper == 0 ){ free(nim); ERREX("bad datatype"); }
4953
4954 /**- set the grid spacings */
4955
4956 nim->dx = nim->pixdim[1] = nhdr.pixdim[1] ;
4957 nim->dy = nim->pixdim[2] = nhdr.pixdim[2] ;
4958 nim->dz = nim->pixdim[3] = nhdr.pixdim[3] ;
4959 nim->dt = nim->pixdim[4] = nhdr.pixdim[4] ;
4960 nim->du = nim->pixdim[5] = nhdr.pixdim[5] ;
4961 nim->dv = nim->pixdim[6] = nhdr.pixdim[6] ;
4962 nim->dw = nim->pixdim[7] = nhdr.pixdim[7] ;
4963
4964 /**- compute qto_xyz transformation from pixel indexes (i,j,k) to (x,y,z) */
4965
4966 if( !ni_ver || nhdr.qform_code <= 0 ){
4967 /**- if not nifti or qform_code <= 0, use grid spacing for qto_xyz */
4968
4969 nim->qto_xyz.m[0][0] = nim->dx ; /* grid spacings */
4970 nim->qto_xyz.m[1][1] = nim->dy ; /* along diagonal */
4971 nim->qto_xyz.m[2][2] = nim->dz ;
4972
4973 /* off diagonal is zero */
4974
4975 nim->qto_xyz.m[0][1]=nim->qto_xyz.m[0][2]=nim->qto_xyz.m[0][3] = 0.0f;
4976 nim->qto_xyz.m[1][0]=nim->qto_xyz.m[1][2]=nim->qto_xyz.m[1][3] = 0.0f;
4977 nim->qto_xyz.m[2][0]=nim->qto_xyz.m[2][1]=nim->qto_xyz.m[2][3] = 0.0f;
4978
4979 /* last row is always [ 0 0 0 1 ] */
4980
4981 nim->qto_xyz.m[3][0]=nim->qto_xyz.m[3][1]=nim->qto_xyz.m[3][2] = 0.0f;
4982 nim->qto_xyz.m[3][3]= 1.0f ;
4983
4984 nim->qform_code = NIFTI_XFORM_UNKNOWN ;
4985
4986 if( g_opts.debug > 1 ) fprintf(stderr,"-d no qform provided\n");
4987 } else {
4988 /**- else NIFTI: use the quaternion-specified transformation */
4989
4990 nim->quatern_b = FIXED_FLOAT( nhdr.quatern_b ) ;
4991 nim->quatern_c = FIXED_FLOAT( nhdr.quatern_c ) ;
4992 nim->quatern_d = FIXED_FLOAT( nhdr.quatern_d ) ;
4993
4994 nim->qoffset_x = FIXED_FLOAT(nhdr.qoffset_x) ;
4995 nim->qoffset_y = FIXED_FLOAT(nhdr.qoffset_y) ;
4996 nim->qoffset_z = FIXED_FLOAT(nhdr.qoffset_z) ;
4997
4998 nim->qfac = (nhdr.pixdim[0] < 0.0) ? -1.0 : 1.0 ; /* left-handedness? */
4999
5000 nim->qto_xyz = nifti_quatern_to_dmat44(
5001 nim->quatern_b, nim->quatern_c, nim->quatern_d,
5002 nim->qoffset_x, nim->qoffset_y, nim->qoffset_z,
5003 nim->dx , nim->dy , nim->dz ,
5004 nim->qfac ) ;
5005
5006 nim->qform_code = nhdr.qform_code ;
5007
5008 if( g_opts.debug > 1 )
5009 nifti_disp_matrix_orient("-d qform orientations:\n", nim->qto_xyz);
5010 }
5011
5012 /**- load inverse transformation (x,y,z) -> (i,j,k) */
5013
5014 nim->qto_ijk = nifti_dmat44_inverse( nim->qto_xyz ) ;
5015
5016 /**- load sto_xyz affine transformation, if present */
5017
5018 if( !ni_ver || nhdr.sform_code <= 0 ){
5019 /**- if not nifti or sform_code <= 0, then no sto transformation */
5020
5021 nim->sform_code = NIFTI_XFORM_UNKNOWN ;
5022
5023 if( g_opts.debug > 1 ) fprintf(stderr,"-d no sform provided\n");
5024
5025 } else {
5026 /**- else set the sto transformation from srow_*[] */
5027
5028 nim->sto_xyz.m[0][0] = nhdr.srow_x[0] ;
5029 nim->sto_xyz.m[0][1] = nhdr.srow_x[1] ;
5030 nim->sto_xyz.m[0][2] = nhdr.srow_x[2] ;
5031 nim->sto_xyz.m[0][3] = nhdr.srow_x[3] ;
5032
5033 nim->sto_xyz.m[1][0] = nhdr.srow_y[0] ;
5034 nim->sto_xyz.m[1][1] = nhdr.srow_y[1] ;
5035 nim->sto_xyz.m[1][2] = nhdr.srow_y[2] ;
5036 nim->sto_xyz.m[1][3] = nhdr.srow_y[3] ;
5037
5038 nim->sto_xyz.m[2][0] = nhdr.srow_z[0] ;
5039 nim->sto_xyz.m[2][1] = nhdr.srow_z[1] ;
5040 nim->sto_xyz.m[2][2] = nhdr.srow_z[2] ;
5041 nim->sto_xyz.m[2][3] = nhdr.srow_z[3] ;
5042
5043 /* last row is always [ 0 0 0 1 ] */
5044
5045 nim->sto_xyz.m[3][0]=nim->sto_xyz.m[3][1]=nim->sto_xyz.m[3][2] = 0.0f;
5046 nim->sto_xyz.m[3][3]= 1.0f ;
5047
5048 nim->sto_ijk = nifti_dmat44_inverse( nim->sto_xyz ) ;
5049
5050 nim->sform_code = nhdr.sform_code ;
5051
5052 if( g_opts.debug > 1 )
5053 nifti_disp_matrix_orient("-d sform orientations:\n", nim->sto_xyz);
5054 }
5055
5056 /**- set miscellaneous NIFTI stuff */
5057
5058 if( ni_ver ){
5059 nim->scl_slope = FIXED_FLOAT( nhdr.scl_slope ) ;
5060 nim->scl_inter = FIXED_FLOAT( nhdr.scl_inter ) ;
5061
5062 nim->intent_code = nhdr.intent_code ;
5063
5064 nim->intent_p1 = FIXED_FLOAT( nhdr.intent_p1 ) ;
5065 nim->intent_p2 = FIXED_FLOAT( nhdr.intent_p2 ) ;
5066 nim->intent_p3 = FIXED_FLOAT( nhdr.intent_p3 ) ;
5067
5068 nim->toffset = FIXED_FLOAT( nhdr.toffset ) ;
5069
5070 memcpy(nim->intent_name,nhdr.intent_name,15); nim->intent_name[15] = '\0';
5071
5072 nim->xyz_units = XYZT_TO_SPACE(nhdr.xyzt_units) ;
5073 nim->time_units = XYZT_TO_TIME (nhdr.xyzt_units) ;
5074
5075 nim->freq_dim = DIM_INFO_TO_FREQ_DIM ( nhdr.dim_info ) ;
5076 nim->phase_dim = DIM_INFO_TO_PHASE_DIM( nhdr.dim_info ) ;
5077 nim->slice_dim = DIM_INFO_TO_SLICE_DIM( nhdr.dim_info ) ;
5078
5079 nim->slice_code = nhdr.slice_code ;
5080 nim->slice_start = nhdr.slice_start ;
5081 nim->slice_end = nhdr.slice_end ;
5082 nim->slice_duration = FIXED_FLOAT(nhdr.slice_duration) ;
5083 }
5084
5085 /**- set Miscellaneous ANALYZE stuff */
5086
5087 nim->cal_min = FIXED_FLOAT(nhdr.cal_min) ;
5088 nim->cal_max = FIXED_FLOAT(nhdr.cal_max) ;
5089
5090 memcpy(nim->descrip ,nhdr.descrip ,79) ; nim->descrip [79] = '\0' ;
5091 memcpy(nim->aux_file,nhdr.aux_file,23) ; nim->aux_file[23] = '\0' ;
5092
5093 /**- set ioff from vox_offset (but at least sizeof(header)) */
5094
5095 nim->iname_offset = nhdr.vox_offset;
5096 if( is_onefile && nhdr.vox_offset < (int64_t)sizeof(nhdr) )
5097 nim->iname_offset = (int64_t)sizeof(nhdr);
5098
5099 /**- deal with file names if set */
5100 if (fname!=NULL) {
5101 nifti_set_filenames(nim,fname,0,0);
5102 if (nim->iname==NULL) { ERREX("bad filename"); }
5103 } else {
5104 nim->fname = NULL;
5105 nim->iname = NULL;
5106 }
5107
5108 /* clear extension fields */
5109 nim->num_ext = 0;
5110 nim->ext_list = NULL;
5111
5112 return nim;
5113 }
5114
5115 #undef ERREX
5116 #define ERREX(msg) \
5117 do{ fprintf(stderr,"** ERROR: nifti_image_open(%s): %s\n", \
5118 (hname != NULL) ? hname : "(null)" , (msg) ) ; \
5119 return fptr ; } while(0)
5120
5121 /***************************************************************
5122 * nifti_image_open
5123 ***************************************************************/
5124 /*! znzFile nifti_image_open( char *hname, char *opts , nifti_image **nim)
5125 \brief Read in NIFTI-1 or ANALYZE-7.5 file (pair) header information into a nifti_image struct.
5126
5127 - The image data is not read from disk (it may be read later using
5128 nifti_image_load(), for example).
5129 - The image data will be stored in whatever data format the
5130 input data is; no scaling will be applied.
5131 - DT_BINARY data is not supported.
5132 - nifti_image_free() can be used to delete the returned struct,
5133 when you are done with it.
5134
5135 \param hname filename of dataset .hdr or .nii file
5136 \param opts options string for opening the header file
5137 \param nim pointer to pointer to nifti_image struct
5138 (this routine allocates the nifti_image struct)
5139 \return file pointer (gzippable) to the file with the image data,
5140 ready for reading.
5141 <br>NULL if something fails badly.
5142 \sa nifti_image_load, nifti_image_free
5143 */
nifti_image_open(const char * hname,char * opts,nifti_image ** nim)5144 znzFile nifti_image_open(const char * hname, char * opts, nifti_image ** nim)
5145 {
5146 znzFile fptr=NULL;
5147 /* open the hdr and reading it in, but do not load the data */
5148 *nim = nifti_image_read(hname,0);
5149 /* open the image file, ready for reading (compressed works for all reads) */
5150 if( ((*nim) == NULL) || ((*nim)->iname == NULL) ||
5151 ((*nim)->nbyper <= 0) || ((*nim)->nvox <= 0) )
5152 ERREX("bad header info") ;
5153
5154 /* open image data file */
5155 fptr = znzopen( (*nim)->iname, opts, nifti_is_gzfile((*nim)->iname) );
5156 if( znz_isnull(fptr) ) ERREX("Can't open data file") ;
5157
5158 return fptr;
5159 }
5160
5161
5162 /*----------------------------------------------------------------------*/
5163 /*! return an allocated and filled nifti_1_header struct
5164
5165 Read the binary header from disk, and swap bytes if necessary.
5166
5167 \return an allocated nifti_1_header struct, or NULL on failure
5168
5169 \param hname name of file containing header
5170 \param swapped if not NULL, return whether header bytes were swapped
5171 \param check flag to check for invalid nifti_1_header
5172
5173 \warning ASCII header type is not supported
5174
5175 \sa nifti_image_read, nifti_image_free, nifti_image_read_bricks
5176 *//*--------------------------------------------------------------------*/
nifti_read_n1_hdr(const char * hname,int * swapped,int check)5177 nifti_1_header * nifti_read_n1_hdr(const char * hname, int *swapped, int check)
5178 {
5179 nifti_1_header nhdr, * hptr;
5180 znzFile fp;
5181 int bytes, lswap;
5182 char * hfile;
5183 char fname[] = { "nifti_read_n1_hdr" };
5184
5185 /* determine file name to use for header */
5186 hfile = nifti_findhdrname(hname);
5187 if( hfile == NULL ){
5188 if( g_opts.debug > 0 )
5189 LNI_FERR(fname,"failed to find header file for", hname);
5190 return NULL;
5191 } else if( g_opts.debug > 1 )
5192 fprintf(stderr,"-d %s: found header filename '%s'\n",fname,hfile);
5193
5194 fp = znzopen( hfile, "rb", nifti_is_gzfile(hfile) );
5195 if( znz_isnull(fp) ){
5196 if( g_opts.debug > 0 ) LNI_FERR(fname,"failed to open header file",hfile);
5197 free(hfile);
5198 return NULL;
5199 }
5200
5201 free(hfile); /* done with filename */
5202
5203 if( has_ascii_header(fp) == 1 ){
5204 znzclose( fp );
5205 if( g_opts.debug > 0 )
5206 LNI_FERR(fname,"ASCII header type not supported",hname);
5207 return NULL;
5208 }
5209
5210 /* read the binary header */
5211 bytes = (int)znzread( &nhdr, 1, sizeof(nhdr), fp );
5212 znzclose( fp ); /* we are done with the file now */
5213
5214 if( bytes < (int)sizeof(nhdr) ){
5215 if( g_opts.debug > 0 ){
5216 LNI_FERR(fname,"bad binary header read for file", hname);
5217 fprintf(stderr," - read %d of %d bytes\n",bytes, (int)sizeof(nhdr));
5218 }
5219 return NULL;
5220 }
5221
5222 /* now just decide on byte swapping */
5223 lswap = need_nhdr_swap(nhdr.dim[0], nhdr.sizeof_hdr); /* swap data flag */
5224 if( check && lswap < 0 ){
5225 LNI_FERR(fname,"bad nifti_1_header for file", hname);
5226 return NULL;
5227 } else if ( lswap < 0 ) {
5228 lswap = 0; /* if swapping does not help, don't do it */
5229 if(g_opts.debug > 1) fprintf(stderr,"-- swap failure, none applied\n");
5230 }
5231
5232 if( lswap ) {
5233 if ( g_opts.debug > 3 ) disp_nifti_1_header("-d nhdr pre-swap: ", &nhdr);
5234 swap_nifti_header( &nhdr , NIFTI_VERSION(nhdr) ) ;
5235 }
5236
5237 if ( g_opts.debug > 2 ) disp_nifti_1_header("-d nhdr post-swap: ", &nhdr);
5238
5239 if ( check && ! nifti_hdr1_looks_good(&nhdr) ){
5240 LNI_FERR(fname,"nifti_1_header looks bad for file", hname);
5241 return NULL;
5242 }
5243
5244 /* all looks good, so allocate memory for and return the header */
5245 hptr = (nifti_1_header *)malloc(sizeof(nifti_1_header));
5246 if( ! hptr ){
5247 fprintf(stderr,"** nifti_read_hdr: failed to alloc nifti_1_header\n");
5248 return NULL;
5249 }
5250
5251 if( swapped ) *swapped = lswap; /* only if they care <sniff!> */
5252
5253 memcpy(hptr, &nhdr, sizeof(nifti_1_header));
5254
5255 return hptr;
5256 }
5257
5258
5259 /*----------------------------------------------------------------------*/
5260 /*! return an allocated and filled nifti_2_header struct
5261
5262 Read the binary header from disk, and swap bytes if necessary.
5263
5264 \return an allocated nifti_2_header struct, or NULL on failure
5265
5266 \param hname name of file containing header
5267 \param swapped if not NULL, return whether header bytes were swapped
5268 \param check flag to check for invalid nifti_2_header
5269
5270 \warning ASCII header type is not supported
5271
5272 \sa nifti_read_header, nifti_read_n1_hdr,
5273 nifti_image_read, nifti_image_read_bricks
5274 *//*--------------------------------------------------------------------*/
nifti_read_n2_hdr(const char * hname,int * swapped,int check)5275 nifti_2_header * nifti_read_n2_hdr(const char * hname, int * swapped, int check)
5276 {
5277 nifti_2_header nhdr, * hptr;
5278 znzFile fp;
5279 int bytes, lswap;
5280 char * hfile;
5281 char fname[] = { "nifti_read_n2_hdr" };
5282
5283 /* determine file name to use for header */
5284 hfile = nifti_findhdrname(hname);
5285 if( hfile == NULL ){
5286 if( g_opts.debug > 0 )
5287 LNI_FERR(fname,"failed to find header file for", hname);
5288 return NULL;
5289 } else if( g_opts.debug > 1 )
5290 fprintf(stderr,"-d %s: found N2 header filename '%s'\n",fname,hfile);
5291
5292 fp = znzopen( hfile, "rb", nifti_is_gzfile(hfile) );
5293 if( znz_isnull(fp) ){
5294 if( g_opts.debug > 0 )
5295 LNI_FERR(fname,"failed to open N2 header file",hfile);
5296 free(hfile);
5297 return NULL;
5298 }
5299
5300 free(hfile); /* done with filename */
5301
5302 if( has_ascii_header(fp) == 1 ){
5303 znzclose( fp );
5304 if( g_opts.debug > 0 )
5305 LNI_FERR(fname,"ASCII header type not supported for NIFTI-2",hname);
5306 return NULL;
5307 }
5308
5309 /* read the binary header */
5310 bytes = (int)znzread( &nhdr, 1, sizeof(nhdr), fp );
5311 znzclose( fp ); /* we are done with the file now */
5312
5313 if( bytes < (int)sizeof(nhdr) ){
5314 if( g_opts.debug > 0 ){
5315 LNI_FERR(fname,"bad binary header read for N2 file", hname);
5316 fprintf(stderr," - read %d of %d bytes\n",bytes, (int)sizeof(nhdr));
5317 }
5318 return NULL;
5319 }
5320
5321 /* now just decide on byte swapping */
5322 lswap = NIFTI2_NEEDS_SWAP(nhdr);
5323 if( lswap ) {
5324 if ( g_opts.debug > 3 ) disp_nifti_2_header("-d n2hdr pre-swap: ", &nhdr);
5325 swap_nifti_header( &nhdr , 2 ); /* use explicit version */
5326 }
5327
5328 if ( g_opts.debug > 2 ) disp_nifti_2_header("-d nhdr post-swap: ", &nhdr);
5329
5330 if ( check && ! nifti_hdr2_looks_good(&nhdr) ){
5331 LNI_FERR(fname,"nifti_2_header looks bad for file", hname);
5332 return NULL;
5333 }
5334
5335 /* all looks good, so allocate memory for and return the header */
5336 hptr = (nifti_2_header *)malloc(sizeof(nifti_2_header));
5337 if( ! hptr ){
5338 fprintf(stderr,"** nifti2_read_hdr: failed to alloc nifti_2_header\n");
5339 return NULL;
5340 }
5341
5342 if( swapped ) *swapped = lswap; /* only if they care <sniff!> */
5343
5344 memcpy(hptr, &nhdr, sizeof(nifti_2_header));
5345
5346 return hptr;
5347 }
5348
5349
5350 /*----------------------------------------------------------------------*/
5351 /*! decide if this nifti_1_header structure looks reasonable
5352
5353 Check dim[0], dim[1], sizeof_hdr, and datatype.
5354 Check magic string for "n+1".
5355 Maybe more tests will follow.
5356
5357 \return 1 if the header seems valid, 0 otherwise
5358
5359 \sa nifti_nim_is_valid, valid_nifti_extensions
5360 *//*--------------------------------------------------------------------*/
nifti_hdr1_looks_good(const nifti_1_header * hdr)5361 int nifti_hdr1_looks_good(const nifti_1_header * hdr)
5362 {
5363 int ni_ver, c, errs = 0;
5364
5365 /* check dim[0] and sizeof_hdr */
5366 if( need_nhdr_swap(hdr->dim[0], hdr->sizeof_hdr) < 0 ){
5367 if( g_opts.debug > 0 )
5368 fprintf(stderr,"** bad nhdr fields: dim0, sizeof_hdr = %d, %d\n",
5369 hdr->dim[0], hdr->sizeof_hdr);
5370 errs++;
5371 }
5372
5373 /* check the valid dimension sizes (maybe dim[0] is bad) */
5374 for( c = 1; c <= hdr->dim[0] && c <= 7; c++ )
5375 if( hdr->dim[c] <= 0 ){
5376 if( g_opts.debug > 0 )
5377 fprintf(stderr,"** bad nhdr field: dim[%d] = %d\n",c,hdr->dim[c]);
5378 errs++;
5379 }
5380
5381 ni_ver = NIFTI_VERSION(*hdr); /* determine header type */
5382
5383 if( ni_ver > 0 ){ /* NIFTI */
5384
5385 if( ! nifti_datatype_is_valid(hdr->datatype, 1) ){
5386 if( g_opts.debug > 0 )
5387 fprintf(stderr,"** bad NIFTI datatype in hdr, %d\n",hdr->datatype);
5388 errs++;
5389 }
5390
5391 } else { /* ANALYZE 7.5 */
5392
5393 if( g_opts.debug > 1 ) /* maybe tell user it's an ANALYZE hdr */
5394 fprintf(stderr,
5395 "-- nhdr magic field implies ANALYZE: magic = '%.4s'\n",hdr->magic);
5396
5397 if( ! nifti_datatype_is_valid(hdr->datatype, 0) ){
5398 if( g_opts.debug > 0 )
5399 fprintf(stderr,"** bad ANALYZE datatype in hdr, %d\n",hdr->datatype);
5400 errs++;
5401 }
5402 }
5403
5404 if( errs ) return 0; /* problems */
5405
5406 if( g_opts.debug > 2 ) fprintf(stderr,"-d nifti header looks good\n");
5407
5408 return 1; /* looks good */
5409 }
5410
5411
5412 /*----------------------------------------------------------------------*/
5413 /*! check that sizeof() returns the proper size
5414 *
5415 * if ni_ver is valid (1 or 2 right now), check those sizes
5416 * if ni_ver == 0, check all known sizes
5417 * else whine and fail
5418 *//*--------------------------------------------------------------------*/
nifti_valid_header_size(int ni_ver,int whine)5419 int nifti_valid_header_size(int ni_ver, int whine)
5420 {
5421 int size, errs=0, checks=0;
5422
5423 if ( !ni_ver || (ni_ver == 1) ) {
5424 size = 348;
5425 checks++;
5426 if( sizeof(nifti_1_header) != size ) {
5427 if( whine )
5428 fprintf(stderr,
5429 "** warning: sizeof(nifti_1_header) = %d, expected %d\n",
5430 (int)sizeof(nifti_1_header), size);
5431 errs++;
5432 }
5433 }
5434
5435 if ( !ni_ver || (ni_ver == 2) ) {
5436 size = 540;
5437 checks++;
5438 if( sizeof(nifti_2_header) != size ) {
5439 if( whine )
5440 fprintf(stderr,
5441 "** warning: sizeof(nifti_2_header) = %d, expected %d\n",
5442 (int)sizeof(nifti_2_header), size);
5443 errs++;
5444 }
5445 }
5446
5447 if ( ! checks ) {
5448 fprintf(stderr,"** nifti_valid_header_size: bad ni_ver = %d\n",ni_ver);
5449 return 0;
5450 }
5451
5452 return errs ? 0 : 1; /* though !errs seems more fun */
5453 }
5454
5455
5456 /*----------------------------------------------------------------------*/
5457 /*! decide if this nifti_2_header structure looks reasonable
5458 * swapping should have already happened
5459
5460 Check sizeof() and sizeof_hdr.
5461 Check dim[0], dim[i], and datatype.
5462 Check magic string for "n+2".
5463
5464 \return 1 if the header seems valid, 0 otherwise
5465
5466 \sa nifti_nim_is_valid, valid_nifti_extensions
5467 *//*--------------------------------------------------------------------*/
nifti_hdr2_looks_good(const nifti_2_header * hdr)5468 int nifti_hdr2_looks_good(const nifti_2_header * hdr)
5469 {
5470 int ni_ver, c, errs = 0;
5471 int64_t d0;
5472
5473 if( !hdr ) { fprintf(stderr,"** n2hdr: hdr is NULL\n"); return 0; }
5474
5475 /* for now, just warn if the header sizes are not right */
5476 if( g_opts.debug > 0 ) (void)nifti_valid_header_size(0, 1);
5477
5478 if( hdr->sizeof_hdr != sizeof(nifti_2_header) ) {
5479 if( g_opts.debug > 0 )
5480 fprintf(stderr,"** bad n2hdr: sizeof_hdr = %d\n", hdr->sizeof_hdr);
5481 errs++;
5482 }
5483
5484 /* check the valid dimension sizes (maybe dim[0] is bad) */
5485 d0 = hdr->dim[0];
5486 if( d0 < 0 || d0 > 7 ) {
5487 if( g_opts.debug > 0 ) fprintf(stderr,"** bad n2hdr: dim0 = %" PRId64 "\n", d0);
5488 errs++;
5489 } else { /* only check dims if d0 is okay */
5490 for( c = 1; c <= d0; c++ )
5491 if( hdr->dim[c] <= 0 ){
5492 if( g_opts.debug > 0 )
5493 fprintf(stderr,"** bad nhdr field: dim[%d] = %" PRId64 "\n",c,hdr->dim[c]);
5494 errs++;
5495 }
5496 }
5497
5498 ni_ver = NIFTI_VERSION(*hdr); /* note version */
5499
5500 if( ! nifti_datatype_is_valid(hdr->datatype, ni_ver) ){
5501 if( g_opts.debug > 0 )
5502 fprintf(stderr,"** bad %s NIFTI datatype in hdr, %d\n",
5503 ni_ver ? "NIFTI" : "ANALYZE", hdr->datatype);
5504 errs++;
5505 }
5506
5507 /* NIFTI_VERSION must return 2, or else sizes will not match */
5508 if( ni_ver != 2 || memcmp((hdr->magic+4), nifti2_magic+4, 4) ) {
5509 if( g_opts.debug > 0 ) {
5510 fprintf(stderr, "-- header magic not NIFTI-2, magic = '%.4s' + ",
5511 hdr->magic);
5512 print_hex_vals(hdr->magic+4, 4, stderr); fputc('\n', stderr);
5513 }
5514 errs++;
5515 }
5516
5517 if( errs ) return 0; /* problems */
5518
5519 if( g_opts.debug > 2 ) fprintf(stderr,"-d nifti header looks good\n");
5520
5521 return 1; /* looks good */
5522 }
5523
5524
5525 /*----------------------------------------------------------------------
5526 * check whether byte swapping is needed
5527 *
5528 * dim[0] should be in [0,7], and sizeof_hdr should be accurate
5529 *
5530 * \returns > 0 : needs swap
5531 * 0 : does not need swap
5532 * < 0 : error condition
5533 *----------------------------------------------------------------------*/
need_nhdr_swap(short dim0,int hdrsize)5534 static int need_nhdr_swap( short dim0, int hdrsize )
5535 {
5536 short d0 = dim0; /* so we won't have to swap them on the stack */
5537 int hsize = hdrsize;
5538
5539 if( d0 != 0 ){ /* then use it for the check */
5540 if( d0 > 0 && d0 <= 7 ) return 0;
5541
5542 nifti_swap_2bytes(1, &d0); /* swap? */
5543 if( d0 > 0 && d0 <= 7 ) return 1;
5544
5545 if( g_opts.debug > 1 ){
5546 fprintf(stderr,"** NIFTI: bad swapped d0 = %d, unswapped = ", d0);
5547 nifti_swap_2bytes(1, &d0); /* swap? */
5548 fprintf(stderr,"%d\n", d0);
5549 }
5550
5551 return -1; /* bad, naughty d0 */
5552 }
5553
5554 /* dim[0] == 0 should not happen, but could, so try hdrsize */
5555 if( hsize == sizeof(nifti_1_header) ) return 0;
5556
5557 nifti_swap_4bytes(1, &hsize); /* swap? */
5558 if( hsize == sizeof(nifti_1_header) ) return 1;
5559
5560 if( g_opts.debug > 1 ){
5561 fprintf(stderr,"** NIFTI: bad swapped hsize = %d, unswapped = ", hsize);
5562 nifti_swap_4bytes(1, &hsize); /* swap? */
5563 fprintf(stderr,"%d\n", hsize);
5564 }
5565
5566 return -2; /* bad, naughty hsize */
5567 }
5568
5569
5570 /* use macro LNI_FILE_ERROR instead of ERREX()
5571 #undef ERREX
5572 #define ERREX(msg) \
5573 do{ fprintf(stderr,"** ERROR: nifti_image_read(%s): %s\n", \
5574 (hname != NULL) ? hname : "(null)" , (msg) ) ; \
5575 return NULL ; } while(0)
5576 */
5577
5578
5579 /***************************************************************
5580 * nifti_read_header
5581 ***************************************************************/
5582 /*! \brief Read and return a nifti header, along with the found type
5583
5584 - The data buffer will be byteswapped if necessary.
5585 - The data buffer will not be scaled.
5586 - The data buffer is allocated with calloc().
5587
5588 \param hname filename of the nifti dataset
5589 \param nver :
5590 \return A void pointer, which should be cast based on the returned nver.
5591 It points to an allocated header struct.
5592 */
nifti_read_header(const char * hname,int * nver,int check)5593 void * nifti_read_header( const char *hname, int *nver, int check )
5594 {
5595 nifti_1_header n1hdr;
5596 nifti_2_header n2hdr;
5597 znzFile fp;
5598 void * hresult = NULL;
5599 int64_t remain, h1size=0, h2size=0;
5600 char fname[] = { "nifti_read_header" };
5601 char *hfile=NULL, *posn;
5602 int ii, ni_ver;
5603
5604 if( g_opts.debug > 2 ){
5605 fprintf(stderr,"-d reading header from '%s'",hname);
5606 fprintf(stderr,", HAVE_ZLIB = %d\n", nifti_compiled_with_zlib());
5607 }
5608
5609 /**- determine filename to use for header */
5610 hfile = nifti_findhdrname(hname);
5611 if( hfile == NULL ){
5612 if(g_opts.debug > 0)
5613 LNI_FERR(fname,"failed to find header file for", hname);
5614 return NULL; /* check return */
5615 } else if( g_opts.debug > 2 )
5616 fprintf(stderr,"-d %s: found header filename '%s'\n",fname,hfile);
5617
5618 h1size = sizeof(nifti_1_header);
5619 h2size = sizeof(nifti_2_header);
5620
5621 /**- open file, separate reading of header, extensions and data */
5622 fp = znzopen(hfile, "rb", nifti_is_gzfile(hfile));
5623 if( znz_isnull(fp) ){
5624 if( g_opts.debug > 0 ) LNI_FERR(fname,"failed to open header file",hfile);
5625 free(hfile);
5626 return NULL;
5627 }
5628
5629 /**- next read into nifti_1_header and determine nifti type */
5630 ii = (int)znzread(&n1hdr, 1, h1size, fp);
5631
5632 if( ii < (int)h1size ){ /* failure? */
5633 if( g_opts.debug > 0 ){
5634 LNI_FERR(fname,"bad binary header read for file", hfile);
5635 fprintf(stderr," - read %d of %d bytes\n",ii, (int)h1size);
5636 }
5637 znzclose(fp) ;
5638 free(hfile);
5639 return NULL;
5640 }
5641
5642 /* find out what type of header we have */
5643 ni_ver = nifti_header_version((char *)&n1hdr, h1size);
5644 if( g_opts.debug > 2 )
5645 fprintf(stderr,"-- %s: NIFTI version = %d", fname, ni_ver);
5646
5647 /* maybe set return NIFTI version */
5648 if( nver ) *nver = ni_ver;
5649
5650 /* if NIFTI-2, copy and finish reading header */
5651 if ( ni_ver == 2 ) {
5652 if( g_opts.debug > 2 )
5653 fprintf(stderr,"-- %s: copying and filling NIFTI-2 header...", fname);
5654 memcpy(&n2hdr, &n1hdr, h1size); /* copy first part */
5655 remain = h2size - h1size;
5656 posn = (char *)&n2hdr + h1size;
5657 ii = (int)znzread(posn, 1, remain, fp); /* read remaining part */
5658 if( ii < (int)remain) {
5659 LNI_FERR(fname,"short NIFTI-2 header read for file", hfile);
5660 znzclose(fp); free(hfile); return NULL;
5661 }
5662 }
5663
5664 /* clean up */
5665 znzclose(fp);
5666 free(hfile);
5667
5668 /* allocate header space and return */
5669 if( ni_ver == 0 || ni_ver == 1 ) {
5670 hresult = malloc(h1size);
5671 if( ! hresult ) {
5672 LNI_FERR(fname,"failed to alloc NIFTI-1 header for file", hname);
5673 return NULL;
5674 }
5675 memcpy(hresult, (void *)&n1hdr, h1size);
5676
5677 if ( check && ! nifti_hdr1_looks_good((nifti_1_header *)hresult) ){
5678 LNI_FERR(fname,"nifti_1_header looks bad for file", hname);
5679 return hresult;
5680 }
5681 } else if ( ni_ver == 2 ) {
5682 hresult = malloc(h2size);
5683 if( ! hresult ) {
5684 LNI_FERR(fname,"failed to alloc NIFTI-2 header for file", hname);
5685 return NULL;
5686 }
5687 memcpy(hresult, &n2hdr, h2size);
5688
5689 if ( check && ! nifti_hdr2_looks_good((nifti_2_header *)hresult) ){
5690 LNI_FERR(fname,"nifti_2_header looks bad for file", hname);
5691 return hresult;
5692 }
5693 } else {
5694 if( g_opts.debug > 0 )
5695 fprintf(stderr, "** %s: bad nifti header version %d\n", hname, ni_ver);
5696
5697 /* return a nifti-1 header anyway */
5698 hresult = malloc(h1size);
5699 if( ! hresult ) {
5700 LNI_FERR(fname,"failed to alloc NIFTI-?? header for file", hname);
5701 return NULL;
5702 }
5703 memcpy(hresult, (void *)&n1hdr, h1size);
5704 }
5705
5706 if( g_opts.debug > 1 )
5707 fprintf(stderr,"-- returning NIFTI-%d header in %s\n", ni_ver, hname);
5708
5709 return hresult;
5710 }
5711
5712
5713 /***************************************************************
5714 * nifti_image_read
5715 ***************************************************************/
5716 /*! \brief Read a nifti header and optionally the data, creating a nifti_image.
5717
5718 - The data buffer will be byteswapped if necessary.
5719 - The data buffer will not be scaled.
5720 - The data buffer is allocated with calloc().
5721
5722 \param hname filename of the nifti dataset
5723 \param read_data Flag, true=read data blob, false=don't read blob.
5724 \return A pointer to the nifti_image data structure.
5725
5726 \sa nifti_image_free, nifti_free_extensions, nifti_image_read_bricks
5727 */
nifti_image_read(const char * hname,int read_data)5728 nifti_image *nifti_image_read( const char *hname , int read_data )
5729 {
5730 nifti_1_header n1hdr;
5731 nifti_2_header n2hdr;
5732 nifti_image *nim;
5733 znzFile fp;
5734 int rv, ii, ni_ver, onefile=0;
5735 int64_t filesize, remain, h1size=0, h2size=0;
5736 char fname[] = { "nifti_image_read" };
5737 char *hfile=NULL, *posn;
5738
5739 if( g_opts.debug > 1 ){
5740 fprintf(stderr,"-d image_read from '%s', read_data = %d",hname,read_data);
5741 fprintf(stderr,", HAVE_ZLIB = %d\n", nifti_compiled_with_zlib());
5742 }
5743
5744 /**- determine filename to use for header */
5745 hfile = nifti_findhdrname(hname);
5746 if( hfile == NULL ){
5747 if(g_opts.debug > 0)
5748 LNI_FERR(fname,"failed to find header file for", hname);
5749 return NULL; /* check return */
5750 } else if( g_opts.debug > 1 )
5751 fprintf(stderr,"-d %s: found header filename '%s'\n",fname,hfile);
5752
5753 if( nifti_is_gzfile(hfile) ) filesize = -1; /* unknown */
5754 else filesize = nifti_get_filesize(hfile);
5755
5756 /**- open file, separate reading of header, extensions and data */
5757 fp = znzopen(hfile, "rb", nifti_is_gzfile(hfile));
5758 if( znz_isnull(fp) ){
5759 if( g_opts.debug > 0 ) LNI_FERR(fname,"failed to open header file",hfile);
5760 free(hfile);
5761 return NULL;
5762 }
5763
5764 /**- first try to read dataset as ASCII (and return if so) */
5765 rv = has_ascii_header( fp );
5766 if( rv < 0 ){
5767 if( g_opts.debug > 0 ) LNI_FERR(fname,"short header read",hfile);
5768 znzclose( fp );
5769 free(hfile);
5770 return NULL;
5771 }
5772 else if ( rv == 1 ) /* process special file type */
5773 return nifti_read_ascii_image( fp, hfile, filesize, read_data );
5774
5775 h1size = sizeof(nifti_1_header);
5776 h2size = sizeof(nifti_2_header);
5777
5778 /**- next read into nifti_1_header and determine nifti type */
5779 ii = (int)znzread(&n1hdr, 1, h1size, fp);
5780
5781 if( ii < (int)h1size ){ /* failure? */
5782 if( g_opts.debug > 0 ){
5783 LNI_FERR(fname,"bad binary header read for file", hfile);
5784 fprintf(stderr," - read %d of %d bytes\n",ii, (int)h1size);
5785 }
5786 znzclose(fp) ;
5787 free(hfile);
5788 return NULL;
5789 }
5790
5791 /* find out what type of header we have */
5792 ni_ver = nifti_header_version((char *)&n1hdr, h1size);
5793 if( g_opts.debug > 2 )
5794 fprintf(stderr,"-- %s: NIFTI version = %d", fname, ni_ver);
5795
5796 if( ni_ver == 0 || ni_ver == 1 ) {
5797 nim = nifti_convert_n1hdr2nim(n1hdr,hfile);
5798 onefile = NIFTI_ONEFILE(n1hdr);
5799 } else if ( ni_ver == 2 ) {
5800 /* fill nifti-2 header and convert */
5801 if( g_opts.debug > 2 )
5802 fprintf(stderr,"-- %s: copying and filling NIFTI-2 header...", fname);
5803 memcpy(&n2hdr, &n1hdr, h1size); /* copy first part */
5804 remain = h2size - h1size;
5805 posn = (char *)&n2hdr + h1size;
5806 ii = (int)znzread(posn, 1, remain, fp); /* read remaining part */
5807 if( ii < (int)remain) {
5808 LNI_FERR(fname,"short NIFTI-2 header read for file", hfile);
5809 znzclose(fp); free(hfile); return NULL;
5810 }
5811 nim = nifti_convert_n2hdr2nim(n2hdr,hfile);
5812 onefile = NIFTI_ONEFILE(n2hdr);
5813 } else {
5814 if( g_opts.debug > 0 )
5815 fprintf(stderr,"** %s: bad nifti im header version %d\n",fname,ni_ver);
5816 znzclose(fp); free(hfile); return NULL;
5817 }
5818
5819 if( nim == NULL ){
5820 znzclose( fp ) ; /* close the file */
5821 if( g_opts.debug > 0 )
5822 LNI_FERR(fname,"cannot create nifti image from header",hfile);
5823 free(hfile); /* had to save this for debug message */
5824 return NULL;
5825 }
5826
5827 if( g_opts.debug > 3 ){
5828 fprintf(stderr,"+d nifti_image_read(), have nifti image:\n");
5829 if( g_opts.debug > 2 ) nifti_image_infodump(nim);
5830 }
5831
5832 /**- check for extensions (any errors here means no extensions) */
5833 if ( onefile ) remain = nim->iname_offset;
5834 else remain = filesize;
5835
5836 if ( ni_ver <= 1 ) remain -= h1size;
5837 else remain -= h2size;
5838
5839 (void)nifti_read_extensions(nim, fp, remain);
5840
5841 znzclose( fp ) ; /* close the file */
5842 free(hfile);
5843
5844 if ( g_opts.alter_cifti && nifti_looks_like_cifti(nim) )
5845 nifti_alter_cifti_dims(nim);
5846
5847 /**- read the data if desired, then bug out */
5848 if( read_data ){
5849 if( nifti_image_load( nim ) < 0 ){
5850 nifti_image_free(nim); /* take ball, go home. */
5851 return NULL;
5852 }
5853 }
5854 else nim->data = NULL ;
5855
5856 return nim ;
5857 }
5858
5859
5860 /*----------------------------------------------------------------------
5861 # return the index of the first occurrence of the given ecode, else -1
5862 *----------------------------------------------------------------------*/
nifti_ext_type_index(nifti_image * nim,int ecode)5863 static int nifti_ext_type_index(nifti_image * nim, int ecode)
5864 {
5865 int ind;
5866
5867 if ( !nim || ecode < 0 ) return -1;
5868
5869 for( ind = 0; ind < nim->num_ext; ind++ )
5870 if( nim->ext_list[ind].ecode == ecode )
5871 return ind;
5872
5873 return -1;
5874 }
5875
5876 /*----------------------------------------------------------------------
5877 *! does this dataset look like CIFTI?
5878 *
5879 * check dimensions and extension ecodes for CIFTI
5880 *
5881 * should have - nx=ny=nz=nt=1, nu,nv>1, nw optional
5882 * - CIFTI extension
5883 *----------------------------------------------------------------------*/
nifti_looks_like_cifti(nifti_image * nim)5884 int nifti_looks_like_cifti(nifti_image * nim)
5885 {
5886 if( ! nim ) return 0;
5887
5888 if( nifti_ext_type_index(nim, NIFTI_ECODE_CIFTI) < 0 ) return 0;
5889
5890 if( nim->nx > 1 || nim->ny > 1 || nim->nz > 1 || nim->nt > 1 ) return 0;
5891
5892 if( nim->nu > 1 || nim->nv > 1 ) return 1; /* looks like it */
5893
5894 return 0;
5895 }
5896
5897 /*----------------------------------------------------------------------
5898 *! alter the dims[] from CIFTI style
5899 *
5900 * convert nu -> nx, nv -> nt/nu, nw -> nv
5901 *----------------------------------------------------------------------*/
nifti_alter_cifti_dims(nifti_image * nim)5902 int nifti_alter_cifti_dims(nifti_image * nim)
5903 {
5904 if( ! nifti_looks_like_cifti(nim) ) return 0;
5905
5906 /* the main effect, move position axis to x ... */
5907 if( nim->nu > 1 || nim->dim[5] ) {
5908 nim->nx = nim->nu;
5909 nim->nu = 1;
5910
5911 nim->dim[1] = nim->dim[5];
5912 nim->dim[5] = 1;
5913 }
5914
5915 return 0;
5916 }
5917
5918
5919 /*----------------------------------------------------------------------
5920 * has_ascii_header - see if the NIFTI header is an ASCII format
5921 *
5922 * If the file starts with the ASCII string "<nifti_image", then
5923 * process the dataset as a type-3 .nia file.
5924 *
5925 * return: -1 on error, 1 if true, or 0 if false
5926 *
5927 * NOTE: this is NOT part of the NIFTI-1 standard
5928 *----------------------------------------------------------------------*/
has_ascii_header(znzFile fp)5929 static int has_ascii_header( znzFile fp )
5930 {
5931 char buf[16];
5932 int nread;
5933
5934 if( znz_isnull(fp) ) return 0;
5935
5936 nread = (int)znzread( buf, 1, 12, fp );
5937 buf[12] = '\0';
5938
5939 if( nread < 12 ) return -1;
5940
5941 znzrewind(fp); /* move back to the beginning, and check */
5942
5943 if( strcmp(buf, "<nifti_image") == 0 ) return 1;
5944
5945 return 0;
5946 }
5947
5948
5949 /*----------------------------------------------------------------------*/
5950 /*! nifti_read_ascii_image - process as a type-3 .nia image file
5951
5952 return NULL on failure
5953
5954 NOTE: this is NOT part of the NIFTI-1 standard
5955 *//*--------------------------------------------------------------------*/
nifti_read_ascii_image(znzFile fp,char * fname,int flen,int read_data)5956 nifti_image * nifti_read_ascii_image(znzFile fp, char *fname, int flen,
5957 int read_data)
5958 {
5959 nifti_image * nim;
5960 int slen, txt_size, remain, rv = 0;
5961 char * sbuf, lfunc[25] = { "nifti_read_ascii_image" };
5962
5963 if( nifti_is_gzfile(fname) ){
5964 LNI_FERR(lfunc,"compression not supported for file type NIFTI_FTYPE_ASCII",
5965 fname);
5966 free(fname); znzclose(fp); return NULL;
5967 }
5968 slen = flen; /* slen will be our buffer length */
5969
5970 if( g_opts.debug > 1 )
5971 fprintf(stderr,"-d %s: have ASCII NIFTI file of size %d\n",fname,slen);
5972
5973 if( slen > 65530 ) slen = 65530 ;
5974 sbuf = (char *)calloc(sizeof(char),slen+1) ;
5975 if( !sbuf ){
5976 fprintf(stderr,"** %s: failed to alloc %d bytes for sbuf",lfunc,65530);
5977 free(fname); znzclose(fp); return NULL;
5978 }
5979 znzread( sbuf , 1 , slen , fp ) ;
5980 nim = nifti_image_from_ascii( sbuf, &txt_size ) ; free( sbuf ) ;
5981 if( nim == NULL ){
5982 LNI_FERR(lfunc,"failed nifti_image_from_ascii()",fname);
5983 free(fname); znzclose(fp); return NULL;
5984 }
5985 nim->nifti_type = NIFTI_FTYPE_ASCII ;
5986
5987 /* compute remaining space for extensions */
5988 remain = flen - txt_size - (int)nifti_get_volsize(nim);
5989 if( remain > 4 ){
5990 /* read extensions (reposition file pointer, first) */
5991 znzseek(fp, txt_size, SEEK_SET);
5992 (void) nifti_read_extensions(nim, fp, (int64_t)remain);
5993 }
5994
5995 free(fname);
5996 znzclose( fp ) ;
5997
5998 nim->iname_offset = -1 ; /* check from the end of the file */
5999
6000 if( read_data ) rv = nifti_image_load( nim ) ;
6001 else nim->data = NULL ;
6002
6003 /* check for nifti_image_load() failure, maybe bail out */
6004 if( read_data && rv != 0 ){
6005 if( g_opts.debug > 1 )
6006 fprintf(stderr,"-d failed image_load, free nifti image struct\n");
6007 free(nim);
6008 return NULL;
6009 }
6010
6011 return nim ;
6012 }
6013
6014
6015 /*----------------------------------------------------------------------
6016 * Read the extensions into the nifti_image struct 08 Dec 2004 [rickr]
6017 *
6018 * This function is called just after the header struct is read in, and
6019 * it is assumed the file pointer has not moved. The value in remain
6020 * is assumed to be accurate, reflecting the bytes of space for potential
6021 * extensions.
6022 *
6023 * return the number of extensions read in, or < 0 on error
6024 *----------------------------------------------------------------------*/
nifti_read_extensions(nifti_image * nim,znzFile fp,int64_t remain)6025 static int nifti_read_extensions( nifti_image *nim, znzFile fp, int64_t remain )
6026 {
6027 nifti1_extender extdr; /* defines extension existence */
6028 nifti1_extension extn; /* single extension to process */
6029 nifti1_extension * Elist; /* list of processed extensions */
6030 int64_t posn, count;
6031
6032 /* rcr n2 - add and use nifti2_extension type? */
6033
6034 if( !nim || znz_isnull(fp) ) {
6035 if( g_opts.debug > 0 )
6036 fprintf(stderr,"** nifti_read_extensions: bad inputs (%p,%p)\n",
6037 (void *)nim, (void *)fp);
6038 return -1;
6039 }
6040
6041 posn = znztell(fp);
6042
6043 if( g_opts.debug > 2 )
6044 fprintf(stderr,"-d nre: posn=%" PRId64 ", offset=%" PRId64 ", type=%d, remain=%" PRId64 "\n",
6045 posn, nim->iname_offset, nim->nifti_type, remain);
6046
6047 if( remain < 16 ){
6048 if( g_opts.debug > 2 ){
6049 if( g_opts.skip_blank_ext )
6050 fprintf(stderr,"-d no extender in '%s' is okay, as "
6051 "skip_blank_ext is set\n",nim->fname);
6052 else
6053 fprintf(stderr,"-d remain=%" PRId64 ", no space for extensions\n",remain);
6054 }
6055 return 0;
6056 }
6057
6058 count = znzread( extdr.extension, 1, 4, fp ); /* get extender */
6059
6060 if( count < 4 ){
6061 if( g_opts.debug > 1 )
6062 fprintf(stderr,"-d file '%s' is too short for an extender\n",
6063 nim->fname);
6064 return 0;
6065 }
6066
6067 if( extdr.extension[0] != 1 ){
6068 if( g_opts.debug > 2 )
6069 fprintf(stderr,"-d extender[0] (%d) shows no extensions for '%s'\n",
6070 extdr.extension[0], nim->fname);
6071 return 0;
6072 }
6073
6074 remain -= 4;
6075 if( g_opts.debug > 2 )
6076 fprintf(stderr,"-d found valid 4-byte extender, remain = %" PRId64 "\n", remain);
6077
6078 /* so we expect extensions, but have no idea of how many there may be */
6079
6080 count = 0;
6081 Elist = NULL;
6082 while (nifti_read_next_extension(&extn, nim, remain, fp) > 0)
6083 {
6084 if( nifti_add_exten_to_list(&extn, &Elist, (int)count+1) < 0 ){
6085 if( g_opts.debug > 0 )
6086 fprintf(stderr,"** failed adding ext %" PRId64 " to list\n", count);
6087 return -1;
6088 }
6089
6090 /* we have a new extension */
6091 if( g_opts.debug > 1 ){
6092 fprintf(stderr,"+d found extension #%" PRId64 ", code = 0x%x, size = %d\n",
6093 count, extn.ecode, extn.esize);
6094 if( extn.ecode == NIFTI_ECODE_AFNI && g_opts.debug > 2 ) /* ~XML */
6095 fprintf(stderr," AFNI extension: %.*s\n",
6096 extn.esize-8,extn.edata);
6097 else if( extn.ecode == NIFTI_ECODE_COMMENT && g_opts.debug > 2 )
6098 fprintf(stderr," COMMENT extension: %.*s\n", /* TEXT */
6099 extn.esize-8,extn.edata);
6100 }
6101 remain -= extn.esize;
6102 count++;
6103 }
6104
6105 if( g_opts.debug > 2 ) fprintf(stderr,"+d found %" PRId64 " extension(s)\n", count);
6106
6107 /* rcr n2 - allow int64_t num ext? */
6108 nim->num_ext = (int)count;
6109 nim->ext_list = Elist;
6110
6111 return count;
6112 }
6113
6114
6115 /*----------------------------------------------------------------------*/
6116 /*! nifti_add_extension - add an extension, with a copy of the data
6117
6118 Add an extension to the nim->ext_list array.
6119 Fill this extension with a copy of the data, noting the
6120 length and extension code.
6121
6122 \param nim - nifti_image to add extension to
6123 \param data - raw extension data
6124 \param length - length of raw extension data
6125 \param ecode - extension code
6126
6127 \sa extension codes NIFTI_ECODE_* in nifti1_io.h
6128 \sa nifti_free_extensions, valid_nifti_extensions, nifti_copy_extensions
6129
6130 \return 0 on success, -1 on error (and free the entire list)
6131 *//*--------------------------------------------------------------------*/
nifti_add_extension(nifti_image * nim,const char * data,int len,int ecode)6132 int nifti_add_extension(nifti_image *nim, const char * data, int len, int ecode)
6133 {
6134 nifti1_extension ext;
6135
6136 /* error are printed in functions */
6137 if( nifti_fill_extension(&ext, data, len, ecode) ) return -1;
6138 if( nifti_add_exten_to_list(&ext, &nim->ext_list, nim->num_ext+1)) return -1;
6139
6140 nim->num_ext++; /* success, so increment */
6141
6142 return 0;
6143 }
6144
6145
6146 /*----------------------------------------------------------------------*/
6147 /* nifti_add_exten_to_list - add a new nifti1_extension to the list
6148
6149 We will append via "malloc, copy and free", because on an error,
6150 the list will revert to the previous one (sorry realloc(), only
6151 quality dolphins get to become part of St@rk!st brand tunafish).
6152
6153 return 0 on success, -1 on error (and free the entire list)
6154 *//*--------------------------------------------------------------------*/
nifti_add_exten_to_list(nifti1_extension * new_ext,nifti1_extension ** list,int new_length)6155 static int nifti_add_exten_to_list( nifti1_extension * new_ext,
6156 nifti1_extension ** list, int new_length )
6157 {
6158 nifti1_extension * tmplist;
6159
6160 tmplist = *list;
6161 *list = (nifti1_extension *)malloc(new_length * sizeof(nifti1_extension));
6162
6163 /* check for failure first */
6164 if( ! *list ){
6165 fprintf(stderr,"** failed to alloc %d extension structs (%d bytes)\n",
6166 new_length, new_length*(int)sizeof(nifti1_extension));
6167 if( !tmplist ) return -1; /* no old list to lose */
6168
6169 *list = tmplist; /* reset list to old one */
6170 return -1;
6171 }
6172
6173 /* if an old list exists, copy the pointers and free the list */
6174 if( tmplist ){
6175 memcpy(*list, tmplist, (new_length-1)*sizeof(nifti1_extension));
6176 free(tmplist);
6177 }
6178
6179 /* for some reason, I just don't like struct copy... */
6180 (*list)[new_length-1].esize = new_ext->esize;
6181 (*list)[new_length-1].ecode = new_ext->ecode;
6182 (*list)[new_length-1].edata = new_ext->edata;
6183
6184 if( g_opts.debug > 2 )
6185 fprintf(stderr,"+d allocated and appended extension #%d to list\n",
6186 new_length);
6187
6188 return 0;
6189 }
6190
6191
6192 /*----------------------------------------------------------------------*/
6193 /* nifti_fill_extension - given data and length, fill an extension struct
6194
6195 Allocate memory for data, copy data, set the size and code.
6196
6197 return 0 on success, -1 on error (and free the entire list)
6198 *//*--------------------------------------------------------------------*/
nifti_fill_extension(nifti1_extension * ext,const char * data,int len,int ecode)6199 static int nifti_fill_extension( nifti1_extension *ext, const char * data,
6200 int len, int ecode)
6201 {
6202 int esize;
6203
6204 if( !ext || !data || len < 0 ){
6205 fprintf(stderr,"** fill_ext: bad params (%p,%p,%d)\n",
6206 (void *)ext, data, len);
6207 return -1;
6208 } else if( ! nifti_is_valid_ecode(ecode) ){
6209 fprintf(stderr,"** fill_ext: invalid ecode %d\n", ecode);
6210 /* should not be fatal 29 Apr 2015 [rickr] */
6211 }
6212
6213 /* compute esize, first : len+8, and take ceiling up to a mult of 16 */
6214 esize = len+8;
6215 if( esize & 0xf ) esize = (esize + 0xf) & ~0xf;
6216 ext->esize = esize;
6217
6218 /* allocate esize-8 (maybe more than len), using calloc for fill */
6219 ext->edata = (char *)calloc(esize-8, sizeof(char));
6220 if( !ext->edata ){
6221 fprintf(stderr,"** NFE: failed to alloc %d bytes for extension\n",len);
6222 return -1;
6223 }
6224
6225 memcpy(ext->edata, data, len); /* copy the data, using len */
6226 ext->ecode = ecode; /* set the ecode */
6227
6228 if( g_opts.debug > 2 )
6229 fprintf(stderr,"+d alloc %d bytes for ext len %d, ecode %d, esize %d\n",
6230 esize-8, len, ecode, esize);
6231
6232 return 0;
6233 }
6234
6235
6236 /*----------------------------------------------------------------------
6237 * nifti_read_next_extension - read a single extension from the file
6238 *
6239 * return (>= 0 is okay):
6240 *
6241 * success : esize
6242 * no extension : 0
6243 * error : -1
6244 *----------------------------------------------------------------------*/
nifti_read_next_extension(nifti1_extension * nex,nifti_image * nim,int remain,znzFile fp)6245 static int nifti_read_next_extension( nifti1_extension * nex, nifti_image *nim,
6246 int remain, znzFile fp )
6247 {
6248 int swap = nim->byteorder != nifti_short_order();
6249 int count, size, code;
6250
6251 /* first clear nex */
6252 nex->esize = nex->ecode = 0;
6253 nex->edata = NULL;
6254
6255 if( remain < 16 ){
6256 if( g_opts.debug > 2 )
6257 fprintf(stderr,"-d only %d bytes remain, so no extension\n", remain);
6258 return 0;
6259 }
6260
6261 /* must start with 4-byte size and code */
6262 count = (int)znzread( &size, 4, 1, fp );
6263 if( count == 1 ) count += (int)znzread( &code, 4, 1, fp );
6264
6265 if( count != 2 ){
6266 if( g_opts.debug > 2 )
6267 fprintf(stderr,"-d current extension read failed\n");
6268 znzseek(fp, -4*count, SEEK_CUR); /* back up past any read */
6269 return 0; /* no extension, no error condition */
6270 }
6271
6272 if( swap ){
6273 if( g_opts.debug > 2 )
6274 fprintf(stderr,"-d pre-swap exts: code %d, size %d\n", code, size);
6275
6276 nifti_swap_4bytes(1, &size);
6277 nifti_swap_4bytes(1, &code);
6278 }
6279
6280 if( g_opts.debug > 2 )
6281 fprintf(stderr,"-d potential extension: code %d, size %d\n", code, size);
6282
6283 if( !nifti_check_extension(nim, size, code, remain) ){
6284 if( znzseek(fp, -8, SEEK_CUR) < 0 ){ /* back up past any read */
6285 fprintf(stderr,"** failure to back out of extension read!\n");
6286 return -1;
6287 }
6288 return 0;
6289 }
6290
6291 /* now get the actual data */
6292 nex->esize = size;
6293 nex->ecode = code;
6294
6295 size -= 8; /* subtract space for size and code in extension */
6296 nex->edata = (char *)malloc(size * sizeof(char));
6297 if( !nex->edata ){
6298 fprintf(stderr,"** failed to allocate %d bytes for extension\n",size);
6299 return -1;
6300 }
6301
6302 count = (int)znzread(nex->edata, 1, size, fp);
6303 if( count < size ){
6304 if( g_opts.debug > 0 )
6305 fprintf(stderr,"-d read only %d (of %d) bytes for extension\n",
6306 count, size);
6307 free(nex->edata);
6308 nex->edata = NULL;
6309 return -1;
6310 }
6311
6312 /* success! */
6313 if( g_opts.debug > 2 )
6314 fprintf(stderr,"+d successfully read extension, code %d, size %d\n",
6315 nex->ecode, nex->esize);
6316
6317 return nex->esize;
6318 }
6319
6320
6321 /*----------------------------------------------------------------------*/
6322 /*! for each extension, check code, size and data pointer
6323 *//*--------------------------------------------------------------------*/
valid_nifti_extensions(const nifti_image * nim)6324 int valid_nifti_extensions(const nifti_image * nim)
6325 {
6326 nifti1_extension * ext;
6327 int c, errs;
6328
6329 if( nim->num_ext <= 0 || nim->ext_list == NULL ){
6330 if( g_opts.debug > 2 ) fprintf(stderr,"-d empty extension list\n");
6331 return 0;
6332 }
6333
6334 /* for each extension, check code, size and data pointer */
6335 ext = nim->ext_list;
6336 errs = 0;
6337 for ( c = 0; c < nim->num_ext; c++ ){
6338 if( ! nifti_is_valid_ecode(ext->ecode) ) {
6339 if( g_opts.debug > 1 )
6340 fprintf(stderr,"-d ext %d, invalid code %d\n", c, ext->ecode);
6341 /* should not be fatal 29 Apr 2015 [rickr] */
6342 }
6343
6344 if( ext->esize <= 0 ){
6345 if( g_opts.debug > 1 )
6346 fprintf(stderr,"-d ext %d, bad size = %d\n", c, ext->esize);
6347 errs++;
6348 } else if( ext->esize & 0xf ){
6349 if( g_opts.debug > 1 )
6350 fprintf(stderr,"-d ext %d, size %d not multiple of 16\n",
6351 c, ext->esize);
6352 errs++;
6353 }
6354
6355 if( ext->edata == NULL ){
6356 if( g_opts.debug > 1 ) fprintf(stderr,"-d ext %d, missing data\n", c);
6357 errs++;
6358 }
6359
6360 ext++;
6361 }
6362
6363 if( errs > 0 ){
6364 if( g_opts.debug > 0 )
6365 fprintf(stderr,"-d had %d extension errors, none will be written\n",
6366 errs);
6367 return 0;
6368 }
6369
6370 /* if we're here, we're good */
6371 return 1;
6372 }
6373
6374 /*----------------------------------------------------------------------*/
6375 /*! determine NIFTI version from buffer (check sizeof_hdr and magic)
6376
6377 \return -1 on error, else NIFTI version
6378 *//*--------------------------------------------------------------------*/
nifti_header_version(const char * buf,int nbytes)6379 int nifti_header_version(const char * buf, int nbytes){
6380 nifti_1_header *n1p = (nifti_1_header *)buf;
6381 nifti_2_header *n2p = (nifti_2_header *)buf;
6382 char fname[] = { "nifti_header_version" };
6383 int sizeof_hdr, sver, nver;
6384
6385 if( !buf ) {
6386 if(g_opts.debug > 0)
6387 fprintf(stderr,"** %s: have NULL buffer pointer", fname);
6388 return -1;
6389 }
6390
6391 if( nbytes < sizeof(nifti_1_header) ) {
6392 if(g_opts.debug > 0)
6393 fprintf(stderr,"** %s: nbytes=%d, too small for test", fname, nbytes);
6394 return -1;
6395 }
6396
6397 /* try to determine the version based on sizeof_hdr */
6398 sver = -1;
6399 sizeof_hdr = n1p->sizeof_hdr;
6400 if ( sizeof_hdr == (int)sizeof(nifti_1_header) ) sver = 1;
6401 else if( sizeof_hdr == (int)sizeof(nifti_2_header) ) sver = 2;
6402 else { /* try swapping */
6403 nifti_swap_4bytes(1, &sizeof_hdr);
6404 if ( sizeof_hdr == (int)sizeof(nifti_1_header) ) sver = 1;
6405 else if( sizeof_hdr == (int)sizeof(nifti_2_header) ) sver = 2;
6406 }
6407
6408 /* and check magic field */
6409 if ( sver == 1 ) nver = NIFTI_VERSION(*n1p);
6410 else if ( sver == 2 ) nver = NIFTI_VERSION(*n2p);
6411 else nver = -1;
6412
6413 /* now compare and return */
6414
6415 if( g_opts.debug > 2 )
6416 fprintf(stderr,"-- %s: size ver = %d, ni ver = %d\n", fname, sver, nver);
6417
6418 if( sver == 1 ) {
6419 nver = NIFTI_VERSION(*n1p);
6420 if( nver == 0 ) return 0; /* ANALYZE */
6421 if( nver == 1 ) return 1; /* NIFTI-1 */
6422 if( g_opts.debug > 1 )
6423 fprintf(stderr,"** %s: bad NIFTI-1 magic= %.4s", fname, n1p->magic);
6424 return -1;
6425 } else if ( sver == 2 ) {
6426 nver = NIFTI_VERSION(*n2p);
6427 if( nver == 2 ) return 2; /* NIFTI-2 */
6428 if( g_opts.debug > 1 )
6429 fprintf(stderr,"** %s: bad NIFTI-2 magic4= %.4s", fname, n2p->magic);
6430 return -1;
6431 }
6432
6433 /* failure */
6434
6435 if( g_opts.debug > 0 )
6436 fprintf(stderr,"** %s: bad sizeof_hdr = %d\n", fname, n1p->sizeof_hdr);
6437
6438 return -1;
6439 }
6440
6441
6442
6443 /*----------------------------------------------------------------------*/
6444 /*! check whether the extension code is valid
6445
6446 \return 1 if valid, 0 otherwise
6447 *//*--------------------------------------------------------------------*/
nifti_is_valid_ecode(int ecode)6448 int nifti_is_valid_ecode( int ecode )
6449 {
6450 if( ecode < NIFTI_ECODE_IGNORE || /* minimum code number (0) */
6451 ecode > NIFTI_MAX_ECODE || /* maximum code number */
6452 ecode & 1 ) /* cannot be odd */
6453 return 0;
6454
6455 return 1;
6456 }
6457
6458
6459 /*----------------------------------------------------------------------
6460 * check for valid size and code, as well as can be done
6461 *----------------------------------------------------------------------*/
nifti_check_extension(nifti_image * nim,int size,int code,int rem)6462 static int nifti_check_extension(nifti_image *nim, int size, int code, int rem)
6463 {
6464 /* check for bad code before bad size */
6465 if( ! nifti_is_valid_ecode(code) ) {
6466 if( g_opts.debug > 2 )
6467 fprintf(stderr,"-d invalid extension code %d\n",code);
6468 /* should not be fatal 29 Apr 2015 [rickr] */
6469 }
6470
6471 if( size < 16 ){
6472 if( g_opts.debug > 2 )
6473 fprintf(stderr,"-d ext size %d, no extension\n",size);
6474 return 0;
6475 }
6476
6477 if( size > rem ){
6478 if( g_opts.debug > 2 )
6479 fprintf(stderr,"-d ext size %d, space %d, no extension\n", size, rem);
6480 return 0;
6481 }
6482
6483 if( size & 0xf ){
6484 if( g_opts.debug > 2 )
6485 fprintf(stderr,"-d nifti extension size %d not multiple of 16\n",size);
6486 return 0;
6487 }
6488
6489 if( nim->nifti_type == NIFTI_FTYPE_ASCII && size > LNI_MAX_NIA_EXT_LEN ){
6490 if( g_opts.debug > 2 )
6491 fprintf(stderr,"-d NVE, bad nifti_type 3 size %d\n", size);
6492 return 0;
6493 }
6494
6495 return 1;
6496 }
6497
6498
6499 /*----------------------------------------------------------------------
6500 * nifti_image_load_prep - prepare to read data
6501 *
6502 * Check nifti_image fields, open the file and seek to the appropriate
6503 * offset for reading.
6504 *
6505 * return NULL on failure
6506 *----------------------------------------------------------------------*/
nifti_image_load_prep(nifti_image * nim)6507 static znzFile nifti_image_load_prep( nifti_image *nim )
6508 {
6509 /* set up data space, open data file and seek, then call nifti_read_buffer */
6510 int64_t ntot , ii , ioff;
6511 znzFile fp;
6512 char *tmpimgname;
6513 char fname[] = { "nifti_image_load_prep" };
6514
6515 /**- perform sanity checks */
6516 if( nim == NULL || nim->iname == NULL ||
6517 nim->nbyper <= 0 || nim->nvox <= 0 )
6518 {
6519 if ( g_opts.debug > 0 ){
6520 if( !nim ) fprintf(stderr,"** ERROR: N_image_load: no nifti image\n");
6521 else fprintf(stderr,"** ERROR: N_image_load: bad params (%p,%d,%" PRId64 ")\n",
6522 nim->iname, nim->nbyper, nim->nvox);
6523 }
6524 return NULL;
6525 }
6526
6527 ntot = nifti_get_volsize(nim) ; /* total bytes to read */
6528
6529 /**- open image data file */
6530
6531 tmpimgname = nifti_findimgname(nim->iname , nim->nifti_type);
6532 if( tmpimgname == NULL ){
6533 if( g_opts.debug > 0 )
6534 fprintf(stderr,"** no image file found for '%s'\n",nim->iname);
6535 return NULL;
6536 }
6537
6538 fp = znzopen(tmpimgname, "rb", nifti_is_gzfile(tmpimgname));
6539 if (znz_isnull(fp)){
6540 if(g_opts.debug > 0) LNI_FERR(fname,"cannot open data file",tmpimgname);
6541 free(tmpimgname);
6542 return NULL; /* bad open? */
6543 }
6544 free(tmpimgname);
6545
6546 /**- get image offset: a negative offset means to figure from end of file */
6547 if( nim->iname_offset < 0 ){
6548 if( nifti_is_gzfile(nim->iname) ){
6549 if( g_opts.debug > 0 )
6550 LNI_FERR(fname,"negative offset for compressed file",nim->iname);
6551 znzclose(fp);
6552 return NULL;
6553 }
6554 ii = nifti_get_filesize( nim->iname ) ;
6555 if( ii <= 0 ){
6556 if( g_opts.debug > 0 ) LNI_FERR(fname,"empty data file",nim->iname);
6557 znzclose(fp);
6558 return NULL;
6559 }
6560 ioff = (ii > ntot) ? ii-ntot : 0 ;
6561 } else { /* non-negative offset */
6562 ioff = nim->iname_offset ; /* means use it directly */
6563 }
6564
6565 /**- seek to the appropriate read position */
6566 if( znzseek(fp , (long)ioff , SEEK_SET) < 0 ){
6567 fprintf(stderr,"** could not seek to offset %" PRId64 " in file '%s'\n",
6568 ioff, nim->iname);
6569 znzclose(fp);
6570 return NULL;
6571 }
6572
6573 /**- and return the File pointer */
6574 return fp;
6575 }
6576
6577
6578 /*----------------------------------------------------------------------
6579 * nifti_image_load
6580 *----------------------------------------------------------------------*/
6581 /*! \fn int nifti_image_load( nifti_image *nim )
6582 \brief Load the image blob into a previously initialized nifti_image.
6583
6584 - If not yet set, the data buffer is allocated with calloc().
6585 - The data buffer will be byteswapped if necessary.
6586 - The data buffer will not be scaled.
6587
6588 This function is used to read the image from disk. It should be used
6589 after a function such as nifti_image_read(), so that the nifti_image
6590 structure is already initialized.
6591
6592 \param nim pointer to a nifti_image (previously initialized)
6593 \return 0 on success, -1 on failure
6594 \sa nifti_image_read, nifti_image_free, nifti_image_unload
6595 */
nifti_image_load(nifti_image * nim)6596 int nifti_image_load( nifti_image *nim )
6597 {
6598 /* set up data space, open data file and seek, then call nifti_read_buffer */
6599 int64_t ntot , ii ;
6600 znzFile fp ;
6601
6602 /**- open the file and position the FILE pointer */
6603 fp = nifti_image_load_prep( nim );
6604
6605 if( fp == NULL ){
6606 if( g_opts.debug > 0 )
6607 fprintf(stderr,"** nifti_image_load, failed load_prep\n");
6608 return -1;
6609 }
6610
6611 ntot = nifti_get_volsize(nim);
6612
6613 /**- if the data pointer is not yet set, get memory space for the image */
6614
6615 if( nim->data == NULL )
6616 {
6617 nim->data = (void *)calloc(1,ntot) ; /* create image memory */
6618 if( nim->data == NULL ){
6619 if( g_opts.debug > 0 )
6620 fprintf(stderr,"** failed to alloc %d bytes for image data\n",
6621 (int)ntot);
6622 znzclose(fp);
6623 return -1;
6624 }
6625 }
6626
6627 /**- now that everything is set up, do the reading */
6628 ii = nifti_read_buffer(fp,nim->data,ntot,nim);
6629 if( ii < ntot ){
6630 znzclose(fp) ;
6631 free(nim->data) ;
6632 nim->data = NULL ;
6633 return -1 ; /* errors were printed in nifti_read_buffer() */
6634 }
6635
6636 /**- close the file */
6637 znzclose( fp ) ;
6638
6639 return 0 ;
6640 }
6641
6642
6643 /* 30 Nov 2004 [rickr]
6644 #undef ERREX
6645 #define ERREX(msg) \
6646 do{ fprintf(stderr,"** ERROR: nifti_read_buffer: %s\n",(msg)) ; \
6647 return 0; } while(0)
6648 */
6649
6650 /*----------------------------------------------------------------------*/
6651 /*! read ntot bytes of data from an open file and byte swaps if necessary
6652
6653 note that nifti_image is required for information on datatype, bsize
6654 (for any needed byte swapping), etc.
6655
6656 This function does not allocate memory, so dataptr must be valid.
6657 *//*--------------------------------------------------------------------*/
nifti_read_buffer(znzFile fp,void * dataptr,int64_t ntot,nifti_image * nim)6658 int64_t nifti_read_buffer(znzFile fp, void* dataptr, int64_t ntot,
6659 nifti_image *nim)
6660 {
6661 int64_t ii;
6662
6663 if( dataptr == NULL ){
6664 if( g_opts.debug > 0 )
6665 fprintf(stderr,"** ERROR: nifti_read_buffer: NULL dataptr\n");
6666 return -1;
6667 }
6668
6669 ii = znzread( dataptr , 1 , ntot , fp ) ; /* data input */
6670
6671 /* if read was short, fail */
6672 if( ii < ntot ){
6673 if( g_opts.debug > 0 )
6674 fprintf(stderr,"++ WARNING: nifti_read_buffer(%s):\n"
6675 " data bytes needed = %" PRId64 "\n"
6676 " data bytes input = %" PRId64 "\n"
6677 " number missing = %" PRId64 " (set to 0)\n",
6678 nim->iname , ntot , ii , (ntot-ii) ) ;
6679 /* memset( (char *)(dataptr)+ii , 0 , ntot-ii ) ; now failure [rickr] */
6680 return -1 ;
6681 }
6682
6683 if( g_opts.debug > 2 )
6684 fprintf(stderr,"+d nifti_read_buffer: read %" PRId64 " bytes\n", ii);
6685
6686 /* byte swap array if needed */
6687
6688 /* ntot/swapsize might not fit as int, use int64_t 6 Jul 2010 [rickr] */
6689 if( nim->swapsize > 1 && nim->byteorder != nifti_short_order() ) {
6690 if( g_opts.debug > 1 )
6691 fprintf(stderr,"+d nifti_read_buffer: swapping data bytes...\n");
6692 nifti_swap_Nbytes( (int)(ntot / nim->swapsize), nim->swapsize , dataptr ) ;
6693 }
6694
6695 #ifdef isfinite
6696 {
6697 /* check input float arrays for goodness, and fix bad floats */
6698 int fix_count = 0 ;
6699
6700 switch( nim->datatype ){
6701
6702 case NIFTI_TYPE_FLOAT32:
6703 case NIFTI_TYPE_COMPLEX64:{
6704 float *far = (float *)dataptr ; int64_t jj,nj ;
6705 nj = ntot / sizeof(float) ;
6706 for( jj=0 ; jj < nj ; jj++ ) /* count fixes 30 Nov 2004 [rickr] */
6707 if( !IS_GOOD_FLOAT(far[jj]) ){
6708 far[jj] = 0 ;
6709 fix_count++ ;
6710 }
6711 }
6712 break ;
6713
6714 case NIFTI_TYPE_FLOAT64:
6715 case NIFTI_TYPE_COMPLEX128:{
6716 double *far = (double *)dataptr ; int64_t jj,nj ;
6717 nj = ntot / sizeof(double) ;
6718 for( jj=0 ; jj < nj ; jj++ ) /* count fixes 30 Nov 2004 [rickr] */
6719 if( !IS_GOOD_FLOAT(far[jj]) ){
6720 far[jj] = 0 ;
6721 fix_count++ ;
6722 }
6723 }
6724 break ;
6725
6726 }
6727
6728 if( g_opts.debug > 1 )
6729 fprintf(stderr,"+d in image, %d bad floats were set to 0\n", fix_count);
6730 }
6731 #endif
6732
6733 return ii;
6734 }
6735
6736 /*--------------------------------------------------------------------------*/
6737 /*! Unload the data in a nifti_image struct, but keep the metadata.
6738 *//*------------------------------------------------------------------------*/
nifti_image_unload(nifti_image * nim)6739 void nifti_image_unload( nifti_image *nim )
6740 {
6741 if( nim != NULL && nim->data != NULL ){
6742 free(nim->data) ; nim->data = NULL ;
6743 }
6744 return ;
6745 }
6746
6747 /*--------------------------------------------------------------------------*/
6748 /*! free 'everything' about a nifti_image struct (including the passed struct)
6749
6750 free (only fields which are not NULL):
6751 - fname and iname
6752 - data
6753 - any ext_list[i].edata
6754 - ext_list
6755 - nim
6756 *//*------------------------------------------------------------------------*/
nifti_image_free(nifti_image * nim)6757 void nifti_image_free( nifti_image *nim )
6758 {
6759 if( nim == NULL ) return ;
6760 if( nim->fname != NULL ) free(nim->fname) ;
6761 if( nim->iname != NULL ) free(nim->iname) ;
6762 if( nim->data != NULL ) free(nim->data ) ;
6763 (void)nifti_free_extensions( nim ) ;
6764 free(nim) ; return ;
6765 }
6766
6767
6768 /*--------------------------------------------------------------------------*/
6769 /*! free the nifti extensions
6770
6771 - If any edata pointer is set in the extension list, free() it.
6772 - Free ext_list, if it is set.
6773 - Clear num_ext and ext_list from nim.
6774
6775 \return 0 on success, -1 on error
6776
6777 \sa nifti_add_extension, nifti_copy_extensions
6778 *//*------------------------------------------------------------------------*/
nifti_free_extensions(nifti_image * nim)6779 int nifti_free_extensions( nifti_image *nim )
6780 {
6781 int c ;
6782 if( nim == NULL ) return -1;
6783 if( nim->num_ext > 0 && nim->ext_list ){
6784 for( c = 0; c < nim->num_ext; c++ )
6785 if ( nim->ext_list[c].edata ) free(nim->ext_list[c].edata);
6786 free(nim->ext_list);
6787 }
6788 /* or if it is inconsistent, warn the user (if we are not in quiet mode) */
6789 else if ( (nim->num_ext > 0 || nim->ext_list != NULL) && (g_opts.debug > 0) )
6790 fprintf(stderr,"** warning: nifti extension num/ptr mismatch (%d,%p)\n",
6791 nim->num_ext, (void *)nim->ext_list);
6792
6793 if( g_opts.debug > 2 )
6794 fprintf(stderr,"+d free'd %d extension(s)\n", nim->num_ext);
6795
6796 nim->num_ext = 0;
6797 nim->ext_list = NULL;
6798
6799 return 0;
6800 }
6801
6802
6803 /*--------------------------------------------------------------------------*/
6804 /*! Print to stdout some info about a nifti_image struct.
6805 *//*------------------------------------------------------------------------*/
nifti_image_infodump(const nifti_image * nim)6806 void nifti_image_infodump( const nifti_image *nim )
6807 {
6808 char *str = nifti_image_to_ascii( nim ) ;
6809 /* stdout -> stderr 2 Dec 2004 [rickr] */
6810 if( str != NULL ){ fputs(str,stderr) ; free(str) ; }
6811 return ;
6812 }
6813
6814
6815 /*--------------------------------------------------------------------------
6816 * nifti_write_buffer just check for a null znzFile and call znzwrite
6817 *--------------------------------------------------------------------------*/
6818 /*! \fn int64_t nifti_write_buffer(znzFile fp, void *buffer, int64_t numbytes)
6819 \brief write numbytes of buffer to file, fp
6820
6821 \param fp File pointer (from znzopen) to gzippable nifti datafile
6822 \param buffer data buffer to be written
6823 \param numbytes number of bytes in buffer to write
6824 \return number of bytes successfully written
6825 */
nifti_write_buffer(znzFile fp,const void * buffer,int64_t numbytes)6826 int64_t nifti_write_buffer(znzFile fp, const void *buffer, int64_t numbytes)
6827 {
6828 /* Write all the image data at once (no swapping here) */
6829 int64_t ss;
6830 if (znz_isnull(fp)){
6831 fprintf(stderr,"** ERROR: nifti_write_buffer: null file pointer\n");
6832 return 0;
6833 }
6834 ss = znzwrite( (const void*)buffer , 1 , numbytes , fp ) ;
6835 return ss;
6836 }
6837
6838
6839 /*----------------------------------------------------------------------*/
6840 /*! write the nifti_image data to file (from nim->data or from NBL)
6841
6842 If NBL is not NULL, write the data from that structure. Otherwise,
6843 write it out from nim->data. No swapping is done here.
6844
6845 \param fp : File pointer
6846 \param nim : nifti_image corresponding to the data
6847 \param NBL : optional source of write data (if NULL use nim->data)
6848
6849 \return 0 on success, -1 on failure
6850
6851 Note: the nifti_image byte_order is set as that of the current CPU.
6852 This is because such a conversion was made to the data upon
6853 reading, while byte_order was not set (so the programs would
6854 know what format the data was on disk). Effectively, since
6855 byte_order should match what is on disk, it should bet set to
6856 that of the current CPU whenever new filenames are assigned.
6857 *//*--------------------------------------------------------------------*/
nifti_write_all_data(znzFile fp,nifti_image * nim,const nifti_brick_list * NBL)6858 int nifti_write_all_data(znzFile fp, nifti_image * nim,
6859 const nifti_brick_list * NBL)
6860 {
6861 int64_t ss, bnum;
6862
6863 if( !NBL ){ /* just write one buffer and get out of here */
6864 if( nim->data == NULL ){
6865 fprintf(stderr,"** NWAD: no image data to write\n");
6866 return -1;
6867 }
6868
6869 ss = nifti_write_buffer(fp,nim->data,nim->nbyper * nim->nvox);
6870 if (ss < nim->nbyper * nim->nvox){
6871 fprintf(stderr,
6872 "** ERROR: NWAD: wrote only %" PRId64 " of %" PRId64 " bytes to file\n",
6873 ss, nim->nbyper * nim->nvox);
6874 return -1;
6875 }
6876
6877 if( g_opts.debug > 1 )
6878 fprintf(stderr,"+d wrote single image of %" PRId64 " bytes\n", ss);
6879 } else {
6880 if( ! NBL->bricks || NBL->nbricks <= 0 || NBL->bsize <= 0 ){
6881 fprintf(stderr,"** NWAD: no brick data to write (%p,%" PRId64 ",%" PRId64 ")\n",
6882 (void *)NBL->bricks, NBL->nbricks, NBL->bsize);
6883 return -1;
6884 }
6885
6886 for( bnum = 0; bnum < NBL->nbricks; bnum++ ){
6887 ss = nifti_write_buffer(fp, NBL->bricks[bnum], NBL->bsize);
6888 if( ss < NBL->bsize ){
6889 fprintf(stderr,
6890 "** NWAD ERROR: wrote %" PRId64 " of %" PRId64 " bytes of brick %" PRId64 " of %" PRId64 " to file",
6891 ss, NBL->bsize, bnum+1, NBL->nbricks);
6892 return -1;
6893 }
6894 }
6895 if( g_opts.debug > 1 )
6896 fprintf(stderr,"+d wrote image of %" PRId64 " brick(s), each of %" PRId64 " bytes\n",
6897 NBL->nbricks, NBL->bsize);
6898 }
6899
6900 /* mark as being in this CPU byte order */
6901 nim->byteorder = nifti_short_order() ;
6902
6903 return 0;
6904 }
6905
6906 /* return number of extensions written, or -1 on error */
nifti_write_extensions(znzFile fp,nifti_image * nim)6907 static int nifti_write_extensions(znzFile fp, nifti_image *nim)
6908 {
6909 nifti1_extension * list;
6910 char extdr[4] = { 0, 0, 0, 0 };
6911 int c, size, ok = 1;
6912
6913 if( znz_isnull(fp) || !nim || nim->num_ext < 0 ){
6914 if( g_opts.debug > 0 )
6915 fprintf(stderr,"** nifti_write_extensions, bad params\n");
6916 return -1;
6917 }
6918
6919 /* if no extensions and user requests it, skip extender */
6920 if( g_opts.skip_blank_ext && (nim->num_ext == 0 || ! nim->ext_list ) ){
6921 if( g_opts.debug > 1 )
6922 fprintf(stderr,"-d no exts and skip_blank_ext set, "
6923 "so skipping 4-byte extender\n");
6924 return 0;
6925 }
6926
6927 /* if invalid extension list, clear num_ext */
6928 if( ! valid_nifti_extensions(nim) ) nim->num_ext = 0;
6929
6930 /* write out extender block */
6931 if( nim->num_ext > 0 ) extdr[0] = 1;
6932 if( nifti_write_buffer(fp, extdr, 4) != 4 ){
6933 fprintf(stderr,"** failed to write extender\n");
6934 return -1;
6935 }
6936
6937 list = nim->ext_list;
6938 for ( c = 0; c < nim->num_ext; c++ ){
6939 size = (int)nifti_write_buffer(fp, &list->esize, sizeof(int));
6940 ok = (size == (int)sizeof(int));
6941 if( ok ){
6942 size = (int)nifti_write_buffer(fp, &list->ecode, sizeof(int));
6943 ok = (size == (int)sizeof(int));
6944 }
6945 if( ok ){
6946 size = (int)nifti_write_buffer(fp, list->edata, list->esize - 8);
6947 ok = (size == list->esize - 8);
6948 }
6949
6950 if( !ok ){
6951 fprintf(stderr,"** failed while writing extension #%d\n",c);
6952 return -1;
6953 } else if ( g_opts.debug > 2 )
6954 fprintf(stderr,"+d wrote extension %d of %d bytes\n", c, size);
6955
6956 list++;
6957 }
6958
6959 if( g_opts.debug > 1 )
6960 fprintf(stderr,"+d wrote out %d extension(s)\n", nim->num_ext);
6961
6962 return nim->num_ext;
6963 }
6964
6965
6966 /*----------------------------------------------------------------------*/
6967 /*! basic initialization of a nifti_image struct (to a 1x1x1 image)
6968 *//*--------------------------------------------------------------------*/
nifti_simple_init_nim(void)6969 nifti_image* nifti_simple_init_nim(void)
6970 {
6971 nifti_image *nim;
6972 nifti_2_header nhdr;
6973 int nbyper, swapsize;
6974
6975 memset(&nhdr,0,sizeof(nhdr)) ; /* zero out header, to be safe */
6976
6977 nhdr.sizeof_hdr = sizeof(nhdr) ;
6978
6979 nhdr.dim[0] = 3 ;
6980 nhdr.dim[1] = 1 ; nhdr.dim[2] = 1 ; nhdr.dim[3] = 1 ;
6981 nhdr.dim[4] = 0 ;
6982
6983 nhdr.pixdim[0] = 0.0 ;
6984 nhdr.pixdim[1] = 1.0 ; nhdr.pixdim[2] = 1.0 ; nhdr.pixdim[3] = 1.0 ;
6985
6986 nhdr.datatype = DT_FLOAT32 ;
6987 nifti_datatype_sizes( nhdr.datatype , &nbyper, &swapsize );
6988 nhdr.bitpix = 8 * nbyper ;
6989
6990 memcpy(nhdr.magic, nifti2_magic, 8); /* init to single file */
6991
6992 nim = nifti_convert_n2hdr2nim(nhdr,NULL);
6993 nim->fname = NULL;
6994 nim->iname = NULL;
6995 return nim;
6996 }
6997
6998
6999 /*----------------------------------------------------------------------*/
7000 /*! basic initialization of a nifti_2_header struct (with given dimensions)
7001
7002 Return an allocated nifti_2_header struct, based on the given
7003 dimensions and datatype.
7004
7005 \param arg_dims : optional dim[8] array (default {3,1,1,1,0,0,0,0})
7006 \param arg_dtype : optional datatype (default DT_FLOAT32)
7007
7008 \return pointer to allocated nifti_2_header struct
7009 *//*--------------------------------------------------------------------*/
nifti_make_new_n2_header(const int64_t arg_dims[],int arg_dtype)7010 nifti_2_header * nifti_make_new_n2_header(const int64_t arg_dims[],
7011 int arg_dtype)
7012 {
7013 nifti_2_header * nhdr;
7014 const int64_t default_dims[8] = { 3, 1, 1, 1, 0, 0, 0, 0 };
7015 const int64_t * dim; /* either passed or default dims */
7016 int dtype; /* either passed or default dtype */
7017 int c, nbyper, swapsize;
7018
7019 /* if arg_dims is passed, apply it */
7020 if( arg_dims ) dim = arg_dims;
7021 else dim = default_dims;
7022
7023 /* validate dim: if there is any problem, apply default_dims */
7024 if( dim[0] < 1 || dim[0] > 7 ) {
7025 fprintf(stderr,"** nifti_simple_hdr_with_dims: bad dim[0]=%" PRId64 "\n",dim[0]);
7026 dim = default_dims;
7027 } else {
7028 for( c = 1; c <= dim[0]; c++ )
7029 if( dim[c] < 1 )
7030 {
7031 fprintf(stderr,
7032 "** nifti_simple_hdr_with_dims: bad dim[%d]=%" PRId64 "\n",c,dim[c]);
7033 dim = default_dims;
7034 break;
7035 }
7036 }
7037
7038 /* validate dtype, too */
7039 dtype = arg_dtype;
7040 if( ! nifti_is_valid_datatype(dtype) ) {
7041 fprintf(stderr,"** nifti_simple_hdr_with_dims: bad dtype %d\n",dtype);
7042 dtype = DT_FLOAT32;
7043 }
7044
7045 /* now populate the header struct */
7046
7047 if( g_opts.debug > 1 )
7048 fprintf(stderr,"+d make_new_n2_header, dim[0] = %" PRId64 ", datatype = %d\n",
7049 dim[0], dtype);
7050
7051 nhdr = (nifti_2_header *)calloc(1,sizeof(nifti_2_header));
7052 if( !nhdr ){
7053 fprintf(stderr,"** make_new_n2_header: failed to alloc hdr\n");
7054 return NULL;
7055 }
7056
7057 nhdr->sizeof_hdr = sizeof(nifti_2_header) ;
7058
7059 /* init dim and pixdim */
7060 nhdr->dim[0] = dim[0];
7061 nhdr->pixdim[0] = 0.0;
7062 for( c = 1; c <= dim[0]; c++ ) {
7063 nhdr->dim[c] = dim[c];
7064 nhdr->pixdim[c] = 1.0;
7065 }
7066
7067 nhdr->datatype = dtype ;
7068 nifti_datatype_sizes( nhdr->datatype , &nbyper, &swapsize );
7069 nhdr->bitpix = 8 * nbyper ;
7070
7071 memcpy(nhdr->magic, nifti2_magic, 8); /* init to single file */
7072
7073 return nhdr;
7074 }
7075
7076
7077 /*----------------------------------------------------------------------*/
7078 /*! basic initialization of a nifti_1_header struct (with given dimensions)
7079
7080 Return an allocated nifti_1_header struct, based on the given
7081 dimensions and datatype.
7082
7083 \param arg_dims : optional dim[8] array (default {3,1,1,1,0,0,0,0})
7084 \param arg_dtype : optional datatype (default DT_FLOAT32)
7085
7086 \return pointer to allocated nifti_1_header struct
7087 *//*--------------------------------------------------------------------*/
nifti_make_new_n1_header(const int64_t arg_dims[],int arg_dtype)7088 nifti_1_header * nifti_make_new_n1_header(const int64_t arg_dims[],
7089 int arg_dtype)
7090 {
7091 nifti_1_header * nhdr;
7092 const int64_t default_dims[8] = { 3, 1, 1, 1, 0, 0, 0, 0 };
7093 const int64_t * dim; /* either passed or default dims */
7094 int dtype; /* either passed or default dtype */
7095 int c, nbyper, swapsize;
7096
7097 /* if arg_dims is passed, apply it */
7098 if( arg_dims ) dim = arg_dims;
7099 else dim = default_dims;
7100
7101 /* validate dim: if there is any problem, apply default_dims */
7102 if( dim[0] < 1 || dim[0] > 7 ) {
7103 fprintf(stderr,"** nifti_simple_hdr_with_dims: bad dim[0]=%" PRId64 "\n",dim[0]);
7104 dim = default_dims;
7105 } else {
7106 for( c = 1; c <= dim[0]; c++ )
7107 if( dim[c] < 1 )
7108 {
7109 fprintf(stderr,
7110 "** nifti_simple_hdr_with_dims: bad dim[%d]=%" PRId64 "\n",c,dim[c]);
7111 dim = default_dims;
7112 break;
7113 }
7114 }
7115
7116 /* validate dtype, too */
7117 dtype = arg_dtype;
7118 if( ! nifti_is_valid_datatype(dtype) ) {
7119 fprintf(stderr,"** nifti_simple_hdr_with_dims: bad dtype %d\n",dtype);
7120 dtype = DT_FLOAT32;
7121 }
7122
7123 /* now populate the header struct */
7124
7125 if( g_opts.debug > 1 )
7126 fprintf(stderr,"+d make_new_n1_header, dim[0] = %" PRId64 ", datatype = %d\n",
7127 dim[0], dtype);
7128
7129 nhdr = (nifti_1_header *)calloc(1,sizeof(nifti_1_header));
7130 if( !nhdr ){
7131 fprintf(stderr,"** make_new_n1_header: failed to alloc hdr\n");
7132 return NULL;
7133 }
7134
7135 nhdr->sizeof_hdr = sizeof(nifti_1_header) ;
7136 nhdr->regular = 'r' ; /* for some stupid reason */
7137
7138 /* init dim and pixdim */
7139 nhdr->dim[0] = (int)dim[0]; /* rcr n2 - check dim sizes for nifti-1 */
7140 /* (verify vals are < 2^15) */
7141 nhdr->pixdim[0] = 0.0f;
7142 for( c = 1; c <= dim[0]; c++ ) {
7143 nhdr->dim[c] = (int)dim[c];
7144 nhdr->pixdim[c] = 1.0f;
7145 }
7146
7147 nhdr->datatype = dtype ;
7148 nifti_datatype_sizes( nhdr->datatype , &nbyper, &swapsize );
7149 nhdr->bitpix = 8 * nbyper ;
7150
7151 strcpy(nhdr->magic, "n+1"); /* init to single file */
7152
7153 return nhdr;
7154 }
7155
7156
7157 /*----------------------------------------------------------------------*/
7158 /*! basic creation of a nifti_image struct
7159
7160 Create a nifti_image from the given dimensions and data type.
7161 Optinally, allocate zero-filled data.
7162
7163 \param dims : optional dim[8] (default {3,1,1,1,0,0,0,0})
7164 \param datatype : optional datatype (default DT_FLOAT32)
7165 \param data_fill : if flag is set, allocate zero-filled data for image
7166
7167 \return pointer to allocated nifti_image struct
7168 *//*--------------------------------------------------------------------*/
nifti_make_new_nim(const int64_t dims[],int datatype,int data_fill)7169 nifti_image * nifti_make_new_nim(const int64_t dims[], int datatype,
7170 int data_fill)
7171 {
7172 nifti_image * nim;
7173 nifti_2_header * nhdr;
7174
7175 nhdr = nifti_make_new_n2_header(dims, datatype);
7176 if( !nhdr ) return NULL; /* error already printed */
7177
7178 nim = nifti_convert_n2hdr2nim(*nhdr,NULL);
7179 free(nhdr); /* in any case, we are done with this */
7180 if( !nim ){
7181 fprintf(stderr,"** NMNN: nifti_convert_n2hdr2nim failure\n");
7182 return NULL;
7183 }
7184
7185 if( g_opts.debug > 1 )
7186 fprintf(stderr,"+d nifti_make_new_nim, data_fill = %d\n",data_fill);
7187
7188 if( data_fill ) {
7189 nim->data = calloc(nim->nvox, nim->nbyper);
7190
7191 /* if we cannot allocate data, take ball and go home */
7192 if( !nim->data ) {
7193 fprintf(stderr,"** NMNN: failed to alloc %" PRId64 " bytes for data\n",
7194 nim->nvox*nim->nbyper);
7195 nifti_image_free(nim);
7196 nim = NULL;
7197 }
7198 }
7199
7200 return nim;
7201 }
7202
7203 #undef N_CHECK_2BYTE_VAL
7204 #define N_CHECK_2BYTE_VAL(fn) do { if( ! NIFTI_IS_16_BIT_INT(nim->fn) ) { \
7205 fprintf(stderr,"** nim->%s = %lld does not fit into NIFTI-1 header\n", \
7206 #fn, (long long)nim->fn); return 1; } } while(0)
7207
7208
7209 /*----------------------------------------------------------------------*/
7210 /*! convert a nifti_image structure to a nifti_1_header struct
7211
7212 No allocation is done, this should be used via structure copy.
7213 As in:
7214 <pre>
7215 nifti_1_header my_header;
7216 my_header = nifti_convert_nim2n1hdr(my_nim_pointer);
7217 </pre>
7218 *//*--------------------------------------------------------------------*/
nifti_convert_nim2n1hdr(const nifti_image * nim,nifti_1_header * hdr)7219 int nifti_convert_nim2n1hdr(const nifti_image * nim, nifti_1_header * hdr)
7220 {
7221 nifti_1_header nhdr;
7222
7223 if( !hdr ) {
7224 fprintf(stderr,"** nifti_CN2N1hdr: no hdr to fill\n");
7225 return 1;
7226 }
7227
7228 memset(&nhdr,0,sizeof(nhdr)) ; /* zero out header, to be safe */
7229
7230
7231 /**- load the ANALYZE-7.5 generic parts of the header struct */
7232
7233 nhdr.sizeof_hdr = sizeof(nhdr) ;
7234 nhdr.regular = 'r' ; /* for some stupid reason */
7235
7236 N_CHECK_2BYTE_VAL(ndim);
7237 N_CHECK_2BYTE_VAL(nx);
7238 N_CHECK_2BYTE_VAL(ny);
7239 N_CHECK_2BYTE_VAL(nz);
7240 N_CHECK_2BYTE_VAL(nt);
7241 N_CHECK_2BYTE_VAL(nu);
7242 N_CHECK_2BYTE_VAL(nv);
7243 N_CHECK_2BYTE_VAL(nw);
7244 N_CHECK_2BYTE_VAL(datatype);
7245 N_CHECK_2BYTE_VAL(nbyper);
7246
7247 nhdr.dim[0] = nim->ndim ;
7248 nhdr.dim[1] = nim->nx ; nhdr.dim[2] = nim->ny ; nhdr.dim[3] = nim->nz ;
7249 nhdr.dim[4] = nim->nt ; nhdr.dim[5] = nim->nu ; nhdr.dim[6] = nim->nv ;
7250 nhdr.dim[7] = nim->nw ;
7251
7252 nhdr.pixdim[0] = 0.0f ;
7253 nhdr.pixdim[1] = nim->dx ; nhdr.pixdim[2] = nim->dy ;
7254 nhdr.pixdim[3] = nim->dz ; nhdr.pixdim[4] = nim->dt ;
7255 nhdr.pixdim[5] = nim->du ; nhdr.pixdim[6] = nim->dv ;
7256 nhdr.pixdim[7] = nim->dw ;
7257
7258 nhdr.datatype = nim->datatype ;
7259 nhdr.bitpix = 8 * nim->nbyper ;
7260
7261 if( nim->cal_max > nim->cal_min ){
7262 nhdr.cal_max = nim->cal_max ;
7263 nhdr.cal_min = nim->cal_min ;
7264 }
7265
7266 if( nim->scl_slope != 0.0 ){
7267 nhdr.scl_slope = nim->scl_slope ;
7268 nhdr.scl_inter = nim->scl_inter ;
7269 }
7270
7271 if( nim->descrip[0] != '\0' ){
7272 memcpy(nhdr.descrip ,nim->descrip ,79) ; nhdr.descrip[79] = '\0' ;
7273 }
7274 if( nim->aux_file[0] != '\0' ){
7275 memcpy(nhdr.aux_file ,nim->aux_file ,23) ; nhdr.aux_file[23] = '\0' ;
7276 }
7277
7278 /**- Load NIFTI specific stuff into the header */
7279
7280 if( nim->nifti_type > NIFTI_FTYPE_ANALYZE ){ /* then not ANALYZE */
7281
7282 if( nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ) strcpy(nhdr.magic,"n+1") ;
7283 else strcpy(nhdr.magic,"ni1") ;
7284
7285 nhdr.pixdim[1] = (float)fabs(nhdr.pixdim[1]) ;
7286 nhdr.pixdim[2] = (float)fabs(nhdr.pixdim[2]) ;
7287 nhdr.pixdim[3] = (float)fabs(nhdr.pixdim[3]) ;
7288 nhdr.pixdim[4] = (float)fabs(nhdr.pixdim[4]) ;
7289 nhdr.pixdim[5] = (float)fabs(nhdr.pixdim[5]) ;
7290 nhdr.pixdim[6] = (float)fabs(nhdr.pixdim[6]) ;
7291 nhdr.pixdim[7] = (float)fabs(nhdr.pixdim[7]) ;
7292
7293 N_CHECK_2BYTE_VAL(intent_code);
7294 N_CHECK_2BYTE_VAL(qform_code);
7295 N_CHECK_2BYTE_VAL(sform_code);
7296
7297 nhdr.intent_code = nim->intent_code ;
7298 nhdr.intent_p1 = nim->intent_p1 ;
7299 nhdr.intent_p2 = nim->intent_p2 ;
7300 nhdr.intent_p3 = nim->intent_p3 ;
7301 if( nim->intent_name[0] != '\0' ){
7302 memcpy(nhdr.intent_name,nim->intent_name,15) ;
7303 nhdr.intent_name[15] = '\0' ;
7304 }
7305
7306 nhdr.vox_offset = (float) nim->iname_offset ;
7307 nhdr.xyzt_units = SPACE_TIME_TO_XYZT( nim->xyz_units, nim->time_units ) ;
7308 nhdr.toffset = nim->toffset ;
7309
7310 if( nim->qform_code > 0 ){
7311 nhdr.qform_code = nim->qform_code ;
7312 nhdr.quatern_b = nim->quatern_b ;
7313 nhdr.quatern_c = nim->quatern_c ;
7314 nhdr.quatern_d = nim->quatern_d ;
7315 nhdr.qoffset_x = nim->qoffset_x ;
7316 nhdr.qoffset_y = nim->qoffset_y ;
7317 nhdr.qoffset_z = nim->qoffset_z ;
7318 nhdr.pixdim[0] = (nim->qfac >= 0.0) ? 1.0f : -1.0f ;
7319 }
7320
7321 if( nim->sform_code > 0 ){
7322 nhdr.sform_code = nim->sform_code ;
7323 nhdr.srow_x[0] = nim->sto_xyz.m[0][0] ;
7324 nhdr.srow_x[1] = nim->sto_xyz.m[0][1] ;
7325 nhdr.srow_x[2] = nim->sto_xyz.m[0][2] ;
7326 nhdr.srow_x[3] = nim->sto_xyz.m[0][3] ;
7327 nhdr.srow_y[0] = nim->sto_xyz.m[1][0] ;
7328 nhdr.srow_y[1] = nim->sto_xyz.m[1][1] ;
7329 nhdr.srow_y[2] = nim->sto_xyz.m[1][2] ;
7330 nhdr.srow_y[3] = nim->sto_xyz.m[1][3] ;
7331 nhdr.srow_z[0] = nim->sto_xyz.m[2][0] ;
7332 nhdr.srow_z[1] = nim->sto_xyz.m[2][1] ;
7333 nhdr.srow_z[2] = nim->sto_xyz.m[2][2] ;
7334 nhdr.srow_z[3] = nim->sto_xyz.m[2][3] ;
7335 }
7336
7337 N_CHECK_2BYTE_VAL(sform_code);
7338 N_CHECK_2BYTE_VAL(slice_start);
7339 N_CHECK_2BYTE_VAL(slice_end);
7340
7341 nhdr.dim_info = FPS_INTO_DIM_INFO( nim->freq_dim ,
7342 nim->phase_dim , nim->slice_dim ) ;
7343 nhdr.slice_code = nim->slice_code ;
7344 nhdr.slice_start = nim->slice_start ;
7345 nhdr.slice_end = nim->slice_end ;
7346 nhdr.slice_duration = nim->slice_duration ;
7347 }
7348
7349 memcpy(hdr, &nhdr, sizeof(nhdr));
7350
7351 return 0;
7352 }
7353
7354
7355 /*----------------------------------------------------------------------*/
7356 /*! convert a nifti_image structure to a nifti_2_header struct
7357
7358 No allocation is done, this should be used via structure copy.
7359 As in:
7360 <pre>
7361 nifti_2_header my_header;
7362 my_header = nifti_convert_nim2n2hdr(my_nim_pointer);
7363 </pre>
7364 *//*--------------------------------------------------------------------*/
nifti_convert_nim2n2hdr(const nifti_image * nim,nifti_2_header * hdr)7365 int nifti_convert_nim2n2hdr(const nifti_image * nim, nifti_2_header * hdr)
7366 {
7367 nifti_2_header nhdr;
7368
7369 if( !hdr ) {
7370 fprintf(stderr,"** nifti_CN2N2hdr: no hdr to fill\n");
7371 return 1;
7372 }
7373
7374 memset(&nhdr,0,sizeof(nhdr)) ; /* zero out header, to be safe */
7375
7376
7377 /**- load the ANALYZE-7.5 generic parts of the header struct */
7378
7379 nhdr.sizeof_hdr = sizeof(nhdr) ;
7380 if( nim->nifti_type == NIFTI_FTYPE_NIFTI2_1 ) strcpy(nhdr.magic,"n+2") ;
7381 else strcpy(nhdr.magic,"ni2") ;
7382
7383 nhdr.datatype = nim->datatype ;
7384 nhdr.bitpix = 8 * nim->nbyper ;
7385
7386 nhdr.dim[0] = nim->ndim ;
7387 nhdr.dim[1] = nim->nx ; nhdr.dim[2] = nim->ny ; nhdr.dim[3] = nim->nz ;
7388 nhdr.dim[4] = nim->nt ; nhdr.dim[5] = nim->nu ; nhdr.dim[6] = nim->nv ;
7389 nhdr.dim[7] = nim->nw ;
7390
7391 nhdr.intent_p1 = nim->intent_p1 ;
7392 nhdr.intent_p2 = nim->intent_p2 ;
7393 nhdr.intent_p3 = nim->intent_p3 ;
7394
7395 nhdr.pixdim[0] = 0.0 ;
7396 nhdr.pixdim[1] = fabs(nim->dx) ; nhdr.pixdim[2] = fabs(nim->dy) ;
7397 nhdr.pixdim[3] = fabs(nim->dz) ; nhdr.pixdim[4] = fabs(nim->dt) ;
7398 nhdr.pixdim[5] = fabs(nim->du) ; nhdr.pixdim[6] = fabs(nim->dv) ;
7399 nhdr.pixdim[7] = fabs(nim->dw) ;
7400
7401 nhdr.vox_offset = nim->iname_offset ;
7402
7403 nhdr.scl_slope = nim->scl_slope ;
7404 nhdr.scl_inter = nim->scl_inter ;
7405
7406 nhdr.cal_max = nim->cal_max ;
7407 nhdr.cal_min = nim->cal_min ;
7408
7409 nhdr.slice_duration = nim->slice_duration ;
7410 nhdr.toffset = nim->toffset ;
7411 nhdr.slice_start = nim->slice_start ;
7412 nhdr.slice_end = nim->slice_end ;
7413
7414 if( nim->descrip[0] != '\0' ){
7415 memcpy(nhdr.descrip ,nim->descrip ,79) ; nhdr.descrip[79] = '\0' ;
7416 }
7417 if( nim->aux_file[0] != '\0' ){
7418 memcpy(nhdr.aux_file ,nim->aux_file ,23) ; nhdr.aux_file[23] = '\0' ;
7419 }
7420
7421 if( nim->qform_code > 0 ){
7422 nhdr.qform_code = nim->qform_code ;
7423 nhdr.quatern_b = nim->quatern_b ;
7424 nhdr.quatern_c = nim->quatern_c ;
7425 nhdr.quatern_d = nim->quatern_d ;
7426 nhdr.qoffset_x = nim->qoffset_x ;
7427 nhdr.qoffset_y = nim->qoffset_y ;
7428 nhdr.qoffset_z = nim->qoffset_z ;
7429 nhdr.pixdim[0] = (nim->qfac >= 0.0) ? 1.0f : -1.0f ;
7430 }
7431
7432 if( nim->sform_code > 0 ){
7433 nhdr.sform_code = nim->sform_code ;
7434 nhdr.srow_x[0] = nim->sto_xyz.m[0][0] ;
7435 nhdr.srow_x[1] = nim->sto_xyz.m[0][1] ;
7436 nhdr.srow_x[2] = nim->sto_xyz.m[0][2] ;
7437 nhdr.srow_x[3] = nim->sto_xyz.m[0][3] ;
7438 nhdr.srow_y[0] = nim->sto_xyz.m[1][0] ;
7439 nhdr.srow_y[1] = nim->sto_xyz.m[1][1] ;
7440 nhdr.srow_y[2] = nim->sto_xyz.m[1][2] ;
7441 nhdr.srow_y[3] = nim->sto_xyz.m[1][3] ;
7442 nhdr.srow_z[0] = nim->sto_xyz.m[2][0] ;
7443 nhdr.srow_z[1] = nim->sto_xyz.m[2][1] ;
7444 nhdr.srow_z[2] = nim->sto_xyz.m[2][2] ;
7445 nhdr.srow_z[3] = nim->sto_xyz.m[2][3] ;
7446 }
7447
7448 nhdr.slice_code = nim->slice_code ;
7449 nhdr.xyzt_units = SPACE_TIME_TO_XYZT( nim->xyz_units, nim->time_units ) ;
7450 nhdr.intent_code = nim->intent_code ;
7451 if( nim->intent_name[0] != '\0' ){
7452 memcpy(nhdr.intent_name,nim->intent_name,15) ;
7453 nhdr.intent_name[15] = '\0' ;
7454 }
7455
7456 nhdr.dim_info = FPS_INTO_DIM_INFO( nim->freq_dim ,
7457 nim->phase_dim , nim->slice_dim ) ;
7458
7459 nhdr.unused_str[0] = '\0' ; /* not needed, but complete */
7460
7461 memcpy(hdr, &nhdr, sizeof(nhdr));
7462
7463 return 0;
7464 }
7465
7466
7467 /*----------------------------------------------------------------------*/
7468 /*! \fn int nifti_copy_extensions(nifti_image * nim_dest, nifti_image * nim_src)
7469 \brief copy the nifti1_extension list from src to dest
7470
7471 Duplicate the list of nifti1_extensions. The dest structure must
7472 be clear of extensions.
7473 \return 0 on success, -1 on failure
7474
7475 \sa nifti_add_extension, nifti_free_extensions
7476 */
nifti_copy_extensions(nifti_image * nim_dest,const nifti_image * nim_src)7477 int nifti_copy_extensions(nifti_image * nim_dest, const nifti_image * nim_src)
7478 {
7479 char * data;
7480 int64_t bytes;
7481 int c, size, old_size;
7482
7483 if( nim_dest->num_ext > 0 || nim_dest->ext_list != NULL ){
7484 fprintf(stderr,"** will not copy extensions over existing ones\n");
7485 return -1;
7486 }
7487
7488 if( g_opts.debug > 1 )
7489 fprintf(stderr,"+d duplicating %d extension(s)\n", nim_src->num_ext);
7490
7491 if( nim_src->num_ext <= 0 ) return 0;
7492
7493 bytes = nim_src->num_ext * sizeof(nifti1_extension); /* I'm lazy */
7494 nim_dest->ext_list = (nifti1_extension *)malloc(bytes);
7495 if( !nim_dest->ext_list ){
7496 fprintf(stderr,"** failed to allocate %d nifti1_extension structs\n",
7497 nim_src->num_ext);
7498 return -1;
7499 }
7500
7501 /* copy the extension data */
7502 nim_dest->num_ext = 0;
7503 for( c = 0; c < nim_src->num_ext; c++ ){
7504 size = old_size = nim_src->ext_list[c].esize;
7505 if( size & 0xf ) size = (size + 0xf) & ~0xf; /* make multiple of 16 */
7506 if( g_opts.debug > 2 )
7507 fprintf(stderr,"+d dup'ing ext #%d of size %d (from size %d)\n",
7508 c, size, old_size);
7509 /* data length is size-8, as esize includes space for esize and ecode */
7510 data = (char *)calloc(size-8,sizeof(char)); /* maybe size > old */
7511 if( !data ){
7512 fprintf(stderr,"** failed to alloc %d bytes for extention\n", size);
7513 if( c == 0 ) { free(nim_dest->ext_list); nim_dest->ext_list = NULL; }
7514 /* otherwise, keep what we have (a.o.t. deleting them all) */
7515 return -1;
7516 }
7517 /* finally, fill the new structure */
7518 nim_dest->ext_list[c].esize = size;
7519 nim_dest->ext_list[c].ecode = nim_src->ext_list[c].ecode;
7520 nim_dest->ext_list[c].edata = data;
7521 memcpy(data, nim_src->ext_list[c].edata, old_size-8);
7522
7523 nim_dest->num_ext++;
7524 }
7525
7526 return 0;
7527 }
7528
7529
7530 /*----------------------------------------------------------------------*/
7531 /*! compute the total size of all extensions
7532
7533 \return the total of all esize fields
7534
7535 Note that each esize includes 4 bytes for ecode, 4 bytes for esize,
7536 and the bytes used for the data. Each esize also needs to be a
7537 multiple of 16, so it may be greater than the sum of its 3 parts.
7538 *//*--------------------------------------------------------------------*/
nifti_extension_size(nifti_image * nim)7539 int nifti_extension_size(nifti_image *nim)
7540 {
7541 int c, size = 0;
7542
7543 if( !nim || nim->num_ext <= 0 ) return 0;
7544
7545 if( g_opts.debug > 2 ) fprintf(stderr,"-d ext sizes:");
7546
7547 for ( c = 0; c < nim->num_ext; c++ ){
7548 size += nim->ext_list[c].esize;
7549 if( g_opts.debug > 2 ) fprintf(stderr," %d",nim->ext_list[c].esize);
7550 }
7551
7552 if( g_opts.debug > 2 ) fprintf(stderr," (total = %d)\n",size);
7553
7554 return size;
7555 }
7556
7557
7558 /*----------------------------------------------------------------------*/
7559 /*! set the nifti_image iname_offset field, based on nifti_type
7560
7561 - if writing to 2 files, set offset to 0
7562 - if writing to a single NIFTI-1 file, set the offset to
7563 352 + total extension size, then align to 16-byte boundary
7564 - if writing an ASCII header, set offset to -1
7565 *//*--------------------------------------------------------------------*/
nifti_set_iname_offset(nifti_image * nim)7566 void nifti_set_iname_offset(nifti_image *nim)
7567 {
7568 int64_t offset;
7569
7570 switch( nim->nifti_type ){
7571
7572 default: /* writing into 2 files */
7573 /* we only write files with 0 offset in the 2 file format */
7574 nim->iname_offset = 0 ;
7575 break ;
7576
7577 /* NIFTI-1 single binary file - always update */
7578 case NIFTI_FTYPE_NIFTI1_1:
7579 offset = nifti_extension_size(nim)+sizeof(nifti_1_header)+4;
7580 /* be sure offset is aligned to a 16 byte boundary */
7581 if ( ( offset % 16 ) != 0 ) offset = ((offset + 0xf) & ~0xf);
7582 if( nim->iname_offset != offset ){
7583 if( g_opts.debug > 1 )
7584 fprintf(stderr,"+d changing offset from %" PRId64 " to %" PRId64 "\n",
7585 nim->iname_offset, offset);
7586 nim->iname_offset = offset;
7587 }
7588 break ;
7589
7590 /* non-standard case: NIFTI-1 ASCII header + binary data (single file) */
7591 case NIFTI_FTYPE_ASCII:
7592 nim->iname_offset = -1 ; /* compute offset from filesize */
7593 break ;
7594 }
7595 }
7596
7597
7598 /*----------------------------------------------------------------------*/
7599 /*! write the nifti_image dataset to disk, optionally including data
7600
7601 This is just a front-end for nifti_image_write_hdr_img2.
7602
7603 \param nim nifti_image to write to disk
7604 \param write_data write options (see nifti_image_write_hdr_img2)
7605 \param opts file open options ("wb" from nifti_image_write)
7606
7607 \sa nifti_image_write, nifti_image_write_hdr_img2, nifti_image_free,
7608 nifti_set_filenames
7609 *//*--------------------------------------------------------------------*/
nifti_image_write_hdr_img(nifti_image * nim,int write_data,const char * opts)7610 znzFile nifti_image_write_hdr_img( nifti_image *nim , int write_data ,
7611 const char* opts )
7612 {
7613 return nifti_image_write_hdr_img2(nim,write_data,opts,NULL,NULL);
7614 }
7615
7616
7617 #undef ERREX
7618 #define ERREX(msg) \
7619 do{ fprintf(stderr,"** ERROR: nifti_image_write_hdr_img: %s\n",(msg)) ; \
7620 return fp ; } while(0)
7621
7622
7623 /* ----------------------------------------------------------------------*/
7624 /*! This writes the header (and optionally the image data) to file
7625 *
7626 * If the image data file is left open it returns a valid znzFile handle.
7627 * It also uses imgfile as the open image file is not null, and modifies
7628 * it inside.
7629 *
7630 * \param nim nifti_image to write to disk
7631 * \param write_opts flags whether to write data and/or close file (see below)
7632 * \param opts file-open options, probably "wb" from nifti_image_write()
7633 * \param imgfile optional open znzFile struct, for writing image data
7634 (may be NULL)
7635 * \param NBL optional nifti_brick_list, containing the image data
7636 (may be NULL)
7637 *
7638 * Values for write_opts mode are based on two binary flags
7639 * ( 0/1 for no-write/write data, and 0/2 for close/leave-open files ) :
7640 * - 0 = do not write data and close (do not open data file)
7641 * - 1 = write data and close
7642 * - 2 = do not write data and leave data file open
7643 * - 3 = write data and leave data file open
7644 *
7645 * \sa nifti_image_write, nifti_image_write_hdr_img, nifti_image_free,
7646 * nifti_set_filenames
7647 *//*---------------------------------------------------------------------*/
nifti_image_write_hdr_img2(nifti_image * nim,int write_opts,const char * opts,znzFile imgfile,const nifti_brick_list * NBL)7648 znzFile nifti_image_write_hdr_img2(nifti_image *nim, int write_opts,
7649 const char * opts, znzFile imgfile, const nifti_brick_list * NBL)
7650 {
7651 nifti_1_header n1hdr ;
7652 nifti_2_header n2hdr ;
7653 znzFile fp=NULL;
7654 int64_t ss ;
7655 int write_data, leave_open;
7656 int nver=1, hsize=(int)sizeof(nifti_1_header); /* 5 Aug 2015 */
7657 char func[] = { "nifti_image_write_hdr_img2" };
7658
7659 write_data = write_opts & 1; /* just separate the bits now */
7660 leave_open = write_opts & 2;
7661
7662 if( ! nim ) ERREX("NULL input") ;
7663 if( ! nifti_validfilename(nim->fname) ) ERREX("bad fname input") ;
7664 if( write_data && ! nim->data && ! NBL ) ERREX("no image data") ;
7665
7666 if( write_data && NBL && ! nifti_NBL_matches_nim(nim, NBL) )
7667 ERREX("NBL does not match nim");
7668
7669 nifti_set_iname_offset(nim);
7670
7671 if( g_opts.debug > 1 ){
7672 fprintf(stderr,"-d writing nifti file '%s'...\n", nim->fname);
7673 if( g_opts.debug > 2 )
7674 fprintf(stderr,"-d nifti type %d, offset %" PRId64 "\n",
7675 nim->nifti_type, nim->iname_offset);
7676 }
7677
7678 if( nim->nifti_type == NIFTI_FTYPE_ASCII ) /* non-standard case */
7679 return nifti_write_ascii_image(nim,NBL,opts,write_data,leave_open);
7680
7681 /* create the nifti header struct 5 Aug, 2015 [rickr]
7682 - default is NIFTI-1 (option?)
7683 - if that fails try NIFTI-2
7684 */
7685 if( nifti_convert_nim2n1hdr(nim, &n1hdr) ) {
7686 if( nifti_convert_nim2n2hdr(nim, &n2hdr) ) return NULL;
7687 fprintf(stderr,"+d writing %s as NIFTI-2, instead...\n", nim->fname);
7688 nver = 2; /* we will write NIFTI-2 */
7689 hsize = (int)sizeof(nifti_2_header);
7690 }
7691
7692 /* if writing to 2 files, make sure iname is set and different from fname */
7693 if( nim->nifti_type != NIFTI_FTYPE_NIFTI1_1 ){
7694 if( nim->iname && strcmp(nim->iname,nim->fname) == 0 ){
7695 free(nim->iname) ; nim->iname = NULL ;
7696 }
7697 if( nim->iname == NULL ){ /* then make a new one */
7698 nim->iname = nifti_makeimgname(nim->fname,nim->nifti_type,0,0);
7699 if( nim->iname == NULL ) return NULL;
7700 }
7701 }
7702
7703 /* if we have an imgfile and will write the header there, use it */
7704 if( ! znz_isnull(imgfile) && nim->nifti_type == NIFTI_FTYPE_NIFTI1_1 ){
7705 if( g_opts.debug > 2 ) fprintf(stderr,"+d using passed file for hdr\n");
7706 fp = imgfile;
7707 }
7708 else {
7709 if( g_opts.debug > 2 )
7710 fprintf(stderr,"+d opening output file %s [%s]\n",nim->fname,opts);
7711 fp = znzopen( nim->fname , opts , nifti_is_gzfile(nim->fname) ) ;
7712 if( znz_isnull(fp) ){
7713 LNI_FERR(func,"cannot open output file",nim->fname);
7714 return fp;
7715 }
7716 }
7717
7718 /* write the header and extensions */
7719
7720 if( nver == 2 ) ss = znzwrite(&n2hdr , 1 , hsize , fp); /* write header */
7721 else ss = znzwrite(&n1hdr , 1 , hsize , fp); /* write header */
7722
7723 if( ss < hsize ){
7724 LNI_FERR(func,"bad header write to output file",nim->fname);
7725 znzclose(fp); return fp;
7726 }
7727
7728 /* partial file exists, and errors have been printed, so ignore return */
7729 if( nim->nifti_type != NIFTI_FTYPE_ANALYZE )
7730 (void)nifti_write_extensions(fp,nim);
7731
7732 /* if the header is all we want, we are done */
7733 if( ! write_data && ! leave_open ){
7734 if( g_opts.debug > 2 ) fprintf(stderr,"-d header is all we want: done\n");
7735 znzclose(fp); return(fp);
7736 }
7737
7738 if( nim->nifti_type != NIFTI_FTYPE_NIFTI1_1 ){ /* get a new file pointer */
7739 znzclose(fp); /* first, close header file */
7740 if( ! znz_isnull(imgfile) ){
7741 if(g_opts.debug > 2) fprintf(stderr,"+d using passed file for img\n");
7742 fp = imgfile;
7743 }
7744 else {
7745 if( g_opts.debug > 2 )
7746 fprintf(stderr,"+d opening img file '%s'\n", nim->iname);
7747 fp = znzopen( nim->iname , opts , nifti_is_gzfile(nim->iname) ) ;
7748 if( znz_isnull(fp) ) ERREX("cannot open image file") ;
7749 }
7750 }
7751
7752 znzseek(fp, nim->iname_offset, SEEK_SET); /* in any case, seek to offset */
7753
7754 if( write_data ) nifti_write_all_data(fp,nim,NBL);
7755 if( ! leave_open ) znzclose(fp);
7756
7757 return fp;
7758 }
7759
7760
7761 /*----------------------------------------------------------------------*/
7762 /*! write a nifti_image to disk in ASCII format
7763 *//*--------------------------------------------------------------------*/
nifti_write_ascii_image(nifti_image * nim,const nifti_brick_list * NBL,const char * opts,int write_data,int leave_open)7764 znzFile nifti_write_ascii_image(nifti_image *nim, const nifti_brick_list * NBL,
7765 const char *opts, int write_data, int leave_open)
7766 {
7767 znzFile fp;
7768 char * hstr;
7769
7770 hstr = nifti_image_to_ascii( nim ) ; /* get header in ASCII form */
7771 if( ! hstr ){ fprintf(stderr,"** failed image_to_ascii()\n"); return NULL; }
7772
7773 fp = znzopen( nim->fname , opts , nifti_is_gzfile(nim->fname) ) ;
7774 if( znz_isnull(fp) ){
7775 free(hstr);
7776 fprintf(stderr,"** failed to open '%s' for ascii write\n",nim->fname);
7777 return fp;
7778 }
7779
7780 znzputs(hstr,fp); /* header */
7781 nifti_write_extensions(fp,nim); /* extensions */
7782
7783 if ( write_data ) { nifti_write_all_data(fp,nim,NBL); } /* data */
7784 if ( ! leave_open ) { znzclose(fp); }
7785 free(hstr);
7786 return fp; /* returned but may be closed */
7787 }
7788
7789
7790 /*--------------------------------------------------------------------------*/
7791 /*! Write a nifti_image to disk.
7792
7793 Since data is properly byte-swapped upon reading, it is assumed
7794 to be in the byte-order of the current CPU at write time. Thus,
7795 nim->byte_order should match that of the current CPU. Note that
7796 the nifti_set_filenames() function takes the flag, set_byte_order.
7797
7798 The following fields of nim affect how the output appears:
7799 - nifti_type = 0 ==> ANALYZE-7.5 format file pair will be written
7800 - nifti_type = 1 ==> NIFTI-1 format single file will be written
7801 (data offset will be 352+extensions)
7802 - nifti_type = 2 ==> NIFTI_1 format file pair will be written
7803 - nifti_type = 3 ==> NIFTI_1 ASCII single file will be written
7804 - fname is the name of the output file (header or header+data)
7805 - if a file pair is being written, iname is the name of the data file
7806 - existing files WILL be overwritten with extreme prejudice
7807 - if qform_code > 0, the quatern_*, qoffset_*, and qfac fields determine
7808 the qform output, NOT the qto_xyz matrix; if you want to compute these
7809 fields from the qto_xyz matrix, you can use the utility function
7810 nifti_mat44_to_quatern()
7811
7812 \sa nifti_image_write_bricks, nifti_image_free, nifti_set_filenames,
7813 nifti_image_write_hdr_img
7814 *//*------------------------------------------------------------------------*/
nifti_image_write(nifti_image * nim)7815 void nifti_image_write( nifti_image *nim )
7816 {
7817 znzFile fp = nifti_image_write_hdr_img(nim,1,"wb");
7818 if( fp ){
7819 if( g_opts.debug > 2 ) fprintf(stderr,"-d niw: done with znzFile\n");
7820 free(fp);
7821 }
7822 if( g_opts.debug > 1 ) fprintf(stderr,"-d nifti_image_write: done\n");
7823 }
7824
7825
7826 /*----------------------------------------------------------------------*/
7827 /*! similar to nifti_image_write, but data is in NBL struct, not nim->data
7828
7829 \sa nifti_image_write, nifti_image_free, nifti_set_filenames, nifti_free_NBL
7830 *//*--------------------------------------------------------------------*/
nifti_image_write_bricks(nifti_image * nim,const nifti_brick_list * NBL)7831 void nifti_image_write_bricks( nifti_image *nim, const nifti_brick_list * NBL )
7832 {
7833 znzFile fp = nifti_image_write_hdr_img2(nim,1,"wb",NULL,NBL);
7834 if( fp ){
7835 if( g_opts.debug > 2 ) fprintf(stderr,"-d niwb: done with znzFile\n");
7836 free(fp);
7837 }
7838 if( g_opts.debug > 1 ) fprintf(stderr,"-d niwb: done writing bricks\n");
7839 }
7840
7841
7842 /*----------------------------------------------------------------------*/
7843 /*! copy the nifti_image structure, without data
7844
7845 Duplicate the structure, including fname, iname and extensions.
7846 Leave the data pointer as NULL.
7847 *//*--------------------------------------------------------------------*/
nifti_copy_nim_info(const nifti_image * src)7848 nifti_image * nifti_copy_nim_info(const nifti_image * src)
7849 {
7850 nifti_image *dest;
7851 dest = (nifti_image *)calloc(1,sizeof(nifti_image));
7852 if( !dest ){
7853 fprintf(stderr,"** NCNI: failed to alloc nifti_image\n");
7854 return NULL;
7855 }
7856 memcpy(dest, src, sizeof(nifti_image));
7857 if( src->fname ) dest->fname = nifti_strdup(src->fname);
7858 if( src->iname ) dest->iname = nifti_strdup(src->iname);
7859 dest->num_ext = 0;
7860 dest->ext_list = NULL;
7861 /* errors will be printed in NCE(), continue in either case */
7862 (void)nifti_copy_extensions(dest, src);
7863
7864 dest->data = NULL;
7865
7866 return dest;
7867 }
7868
7869
7870 /*------------------------------------------------------------------------*/
7871 /* Un-escape a C string in place -- that is, convert XML escape sequences
7872 back into their characters. (This can be done in place since the
7873 replacement is always smaller than the input.) Escapes recognized are:
7874 - < -> <
7875 - > -> >
7876 - " -> "
7877 - ' -> '
7878 - & -> &
7879 Also replace CR LF pair (Microsoft), or CR alone (Macintosh) with
7880 LF (Unix), per the XML standard.
7881 Return value is number of replacements made (if you care).
7882 --------------------------------------------------------------------------*/
7883
7884 #undef CR
7885 #undef LF
7886 #define CR 0x0D
7887 #define LF 0x0A
7888
unescape_string(char * str)7889 static int unescape_string( char *str )
7890 {
7891 int ii,jj , nn,ll ;
7892
7893 if( str == NULL ) return 0 ; /* no string? */
7894 ll = (int)strlen(str) ; if( ll == 0 ) return 0 ;
7895
7896 /* scan for escapes: &something; */
7897
7898 for( ii=jj=nn=0 ; ii<ll ; ii++,jj++ ){ /* scan at ii; results go in at jj */
7899
7900 if( str[ii] == '&' ){ /* start of escape? */
7901
7902 if( ii+3 < ll && /* < */
7903 str[ii+1] == 'l' &&
7904 str[ii+2] == 't' &&
7905 str[ii+3] == ';' ){ str[jj] = '<' ; ii += 3 ; nn++ ; }
7906
7907 else if( ii+3 < ll && /* > */
7908 str[ii+1] == 'g' &&
7909 str[ii+2] == 't' &&
7910 str[ii+3] == ';' ){ str[jj] = '>' ; ii += 3 ; nn++ ; }
7911
7912 else if( ii+5 < ll && /* " */
7913 str[ii+1] == 'q' &&
7914 str[ii+2] == 'u' &&
7915 str[ii+3] == 'o' &&
7916 str[ii+4] == 't' &&
7917 str[ii+5] == ';' ){ str[jj] = '"' ; ii += 5 ; nn++ ; }
7918
7919 else if( ii+5 < ll && /* ' */
7920 str[ii+1] == 'a' &&
7921 str[ii+2] == 'p' &&
7922 str[ii+3] == 'o' &&
7923 str[ii+4] == 's' &&
7924 str[ii+5] == ';' ){ str[jj] = '\'' ; ii += 5 ; nn++ ; }
7925
7926 else if( ii+4 < ll && /* & */
7927 str[ii+1] == 'a' &&
7928 str[ii+2] == 'm' &&
7929 str[ii+3] == 'p' &&
7930 str[ii+4] == ';' ){ str[jj] = '&' ; ii += 4 ; nn++ ; }
7931
7932 /* although the comments above don't mention it,
7933 we also look for XML style numeric escapes
7934 of the forms   (decimal) and ý (hex) */
7935
7936 else if( ii+3 < ll &&
7937 str[ii+1] == '#' &&
7938 isdigit((int) str[ii+2]) ){ /* &#dec; */
7939
7940 unsigned int val='?' ; int kk=ii+3 ;
7941 while( kk < ll && kk != ';' ) kk++ ;
7942 sscanf( str+ii+2 , "%u" , &val ) ;
7943 str[jj] = (char) val ; ii = kk ; nn++ ;
7944 }
7945
7946 else if( ii+4 < ll &&
7947 str[ii+1] == '#' &&
7948 str[ii+2] == 'x' &&
7949 isxdigit((int) str[ii+3]) ){ /* &#hex; */
7950
7951 unsigned int val='?' ; int kk=ii+4 ;
7952 while( kk < ll && kk != ';' ) kk++ ;
7953 sscanf( str+ii+3 , "%x" , &val ) ;
7954 str[jj] = (char) val ; ii = kk ; nn++ ;
7955 }
7956
7957 /* didn't start a recognized escape, so just copy as normal */
7958
7959 else if( jj < ii ){ str[jj] = str[ii] ; }
7960
7961 } else if( str[ii] == CR ) { /* is a carriage return */
7962
7963 if( str[ii+1] == LF ){ str[jj] = LF ; ii++ ; nn++ ; } /* CR LF */
7964 else { str[jj] = LF ; ; nn++ ; } /* CR only */
7965
7966 } else { /* is a normal character, just copy to output */
7967
7968 if( jj < ii ){ str[jj] = str[ii] ; }
7969 }
7970
7971 /* at this point, ii=index of last character used up in scan
7972 jj=index of last character written to (jj <= ii) */
7973 }
7974
7975 if( jj < ll ) str[jj] = '\0' ; /* end string properly */
7976
7977 return nn ;
7978 }
7979
7980 /*------------------------------------------------------------------------*/
7981 /* Quotize (and escapize) one string, returning a new string.
7982 Approximately speaking, this is the inverse of unescape_string().
7983 The result should be free()-ed when you are done with it.
7984 --------------------------------------------------------------------------*/
7985
escapize_string(const char * str)7986 static char *escapize_string( const char * str )
7987 {
7988 int ii,jj , lstr,lout ;
7989 char *out ;
7990
7991 if( str == NULL || (lstr=(int)strlen(str)) == 0 ){ /* 0 length */
7992 out = nifti_strdup("''") ; return out ; /* string?? */
7993 }
7994
7995 lout = 4 ; /* initialize length of output */
7996 for( ii=0 ; ii < lstr ; ii++ ){ /* count characters for output */
7997 switch( str[ii] ){
7998 case '&': lout += 5 ; break ; /* replace '&' with "&" */
7999
8000 case '<':
8001 case '>': lout += 4 ; break ; /* replace '<' with "<" */
8002
8003 case '"' :
8004 case '\'': lout += 6 ; break ; /* replace '"' with """ */
8005
8006 case CR:
8007 case LF: lout += 6 ; break ; /* replace CR with "
"
8008 LF with "
" */
8009
8010 default: lout++ ; break ; /* copy all other chars */
8011 }
8012 }
8013 out = (char *)calloc(1,lout) ; /* allocate output string */
8014 if( !out ){
8015 fprintf(stderr,"** escapize_string: failed to alloc %d bytes\n",lout);
8016 return NULL;
8017 }
8018 out[0] = '\'' ; /* opening quote mark */
8019 for( ii=0,jj=1 ; ii < lstr ; ii++ ){
8020 switch( str[ii] ){
8021 default: out[jj++] = str[ii] ; break ; /* normal characters */
8022
8023 case '&': memcpy(out+jj,"&",5) ; jj+=5 ; break ;
8024
8025 case '<': memcpy(out+jj,"<",4) ; jj+=4 ; break ;
8026 case '>': memcpy(out+jj,">",4) ; jj+=4 ; break ;
8027
8028 case '"' : memcpy(out+jj,""",6) ; jj+=6 ; break ;
8029
8030 case '\'': memcpy(out+jj,"'",6) ; jj+=6 ; break ;
8031
8032 case CR: memcpy(out+jj,"
",6) ; jj+=6 ; break ;
8033 case LF: memcpy(out+jj,"
",6) ; jj+=6 ; break ;
8034 }
8035 }
8036 out[jj++] = '\'' ; /* closing quote mark */
8037 out[jj] = '\0' ; /* terminate the string */
8038 return out ;
8039 }
8040
8041 /*---------------------------------------------------------------------------*/
8042 /*! Dump the information in a NIFTI image header to an XML-ish ASCII string
8043 that can later be converted back into a NIFTI header in
8044 nifti_image_from_ascii().
8045
8046 The resulting string can be free()-ed when you are done with it.
8047 *//*-------------------------------------------------------------------------*/
nifti_image_to_ascii(const nifti_image * nim)8048 char *nifti_image_to_ascii( const nifti_image *nim )
8049 {
8050 char *buf , *ebuf ; int nbuf ;
8051
8052 if( nim == NULL ) return NULL ; /* stupid caller */
8053
8054 buf = (char *)calloc(1,65534); nbuf = 0; /* longer than needed, to be safe */
8055 if( !buf ){
8056 fprintf(stderr,"** NITA: failed to alloc %d bytes\n",65534);
8057 return NULL;
8058 }
8059
8060 sprintf( buf , "<nifti_image\n" ) ; /* XML-ish opener */
8061
8062 sprintf( buf+strlen(buf) , " nifti_type = '%s'\n" ,
8063 (nim->nifti_type == NIFTI_FTYPE_NIFTI1_1) ? "NIFTI-1+"
8064 :(nim->nifti_type == NIFTI_FTYPE_NIFTI1_2) ? "NIFTI-1"
8065 :(nim->nifti_type == NIFTI_FTYPE_ASCII ) ? "NIFTI-1A"
8066 : "ANALYZE-7.5" ) ;
8067
8068 /** Strings that we don't control (filenames, etc.) that might
8069 contain "weird" characters (like quotes) are "escaped":
8070 - A few special characters are replaced by XML-style escapes, using
8071 the function escapize_string().
8072 - On input, function unescape_string() reverses this process.
8073 - The result is that the NIFTI ASCII-format header is XML-compliant. */
8074
8075 ebuf = escapize_string(nim->fname) ;
8076 sprintf( buf+strlen(buf) , " header_filename = %s\n",ebuf); free(ebuf);
8077
8078 ebuf = escapize_string(nim->iname) ;
8079 sprintf( buf+strlen(buf) , " image_filename = %s\n", ebuf); free(ebuf);
8080
8081 sprintf( buf+strlen(buf) , " image_offset = '%" PRId64 "'\n" , nim->iname_offset );
8082
8083 sprintf( buf+strlen(buf), " ndim = '%" PRId64 "'\n",nim->ndim);
8084 sprintf( buf+strlen(buf), " nx = '%" PRId64 "'\n", nim->nx );
8085 if( nim->ndim > 1 ) sprintf( buf+strlen(buf), " ny = '%" PRId64 "'\n", nim->ny );
8086 if( nim->ndim > 2 ) sprintf( buf+strlen(buf), " nz = '%" PRId64 "'\n", nim->nz );
8087 if( nim->ndim > 3 ) sprintf( buf+strlen(buf), " nt = '%" PRId64 "'\n", nim->nt );
8088 if( nim->ndim > 4 ) sprintf( buf+strlen(buf), " nu = '%" PRId64 "'\n", nim->nu );
8089 if( nim->ndim > 5 ) sprintf( buf+strlen(buf), " nv = '%" PRId64 "'\n", nim->nv );
8090 if( nim->ndim > 6 ) sprintf( buf+strlen(buf), " nw = '%" PRId64 "'\n", nim->nw );
8091 sprintf( buf+strlen(buf), " dx = '%g'\n", nim->dx );
8092 if( nim->ndim > 1 ) sprintf( buf+strlen(buf), " dy = '%g'\n", nim->dy );
8093 if( nim->ndim > 2 ) sprintf( buf+strlen(buf), " dz = '%g'\n", nim->dz );
8094 if( nim->ndim > 3 ) sprintf( buf+strlen(buf), " dt = '%g'\n", nim->dt );
8095 if( nim->ndim > 4 ) sprintf( buf+strlen(buf), " du = '%g'\n", nim->du );
8096 if( nim->ndim > 5 ) sprintf( buf+strlen(buf), " dv = '%g'\n", nim->dv );
8097 if( nim->ndim > 6 ) sprintf( buf+strlen(buf), " dw = '%g'\n", nim->dw );
8098
8099 sprintf( buf+strlen(buf) , " datatype = '%d'\n" , nim->datatype ) ;
8100 sprintf( buf+strlen(buf) , " datatype_name = '%s'\n" ,
8101 nifti_datatype_string(nim->datatype) ) ;
8102
8103 sprintf( buf+strlen(buf) , " nvox = '%" PRId64 "'\n" , nim->nvox ) ;
8104 sprintf( buf+strlen(buf) , " nbyper = '%d'\n" , nim->nbyper ) ;
8105
8106 sprintf( buf+strlen(buf) , " byteorder = '%s'\n" ,
8107 (nim->byteorder==MSB_FIRST) ? "MSB_FIRST" : "LSB_FIRST" ) ;
8108
8109 if( nim->cal_min < nim->cal_max ){
8110 sprintf( buf+strlen(buf) , " cal_min = '%g'\n", nim->cal_min ) ;
8111 sprintf( buf+strlen(buf) , " cal_max = '%g'\n", nim->cal_max ) ;
8112 }
8113
8114 if( nim->scl_slope != 0.0 ){
8115 sprintf( buf+strlen(buf) , " scl_slope = '%g'\n" , nim->scl_slope ) ;
8116 sprintf( buf+strlen(buf) , " scl_inter = '%g'\n" , nim->scl_inter ) ;
8117 }
8118
8119 if( nim->intent_code > 0 ){
8120 sprintf( buf+strlen(buf) , " intent_code = '%d'\n", nim->intent_code ) ;
8121 sprintf( buf+strlen(buf) , " intent_code_name = '%s'\n" ,
8122 nifti_intent_string(nim->intent_code) ) ;
8123 sprintf( buf+strlen(buf) , " intent_p1 = '%g'\n" , nim->intent_p1 ) ;
8124 sprintf( buf+strlen(buf) , " intent_p2 = '%g'\n" , nim->intent_p2 ) ;
8125 sprintf( buf+strlen(buf) , " intent_p3 = '%g'\n" , nim->intent_p3 ) ;
8126
8127 if( nim->intent_name[0] != '\0' ){
8128 ebuf = escapize_string(nim->intent_name) ;
8129 sprintf( buf+strlen(buf) , " intent_name = %s\n",ebuf) ;
8130 free(ebuf) ;
8131 }
8132 }
8133
8134 if( nim->toffset != 0.0 )
8135 sprintf( buf+strlen(buf) , " toffset = '%g'\n",nim->toffset ) ;
8136
8137 if( nim->xyz_units > 0 )
8138 sprintf( buf+strlen(buf) ,
8139 " xyz_units = '%d'\n"
8140 " xyz_units_name = '%s'\n" ,
8141 nim->xyz_units , nifti_units_string(nim->xyz_units) ) ;
8142
8143 if( nim->time_units > 0 )
8144 sprintf( buf+strlen(buf) ,
8145 " time_units = '%d'\n"
8146 " time_units_name = '%s'\n" ,
8147 nim->time_units , nifti_units_string(nim->time_units) ) ;
8148
8149 if( nim->freq_dim > 0 )
8150 sprintf( buf+strlen(buf) , " freq_dim = '%d'\n",nim->freq_dim ) ;
8151 if( nim->phase_dim > 0 )
8152 sprintf( buf+strlen(buf) , " phase_dim = '%d'\n",nim->phase_dim ) ;
8153 if( nim->slice_dim > 0 )
8154 sprintf( buf+strlen(buf) , " slice_dim = '%d'\n",nim->slice_dim ) ;
8155 if( nim->slice_code > 0 )
8156 sprintf( buf+strlen(buf) ,
8157 " slice_code = '%d'\n"
8158 " slice_code_name = '%s'\n" ,
8159 nim->slice_code , nifti_slice_string(nim->slice_code) ) ;
8160 if( nim->slice_start >= 0 && nim->slice_end > nim->slice_start )
8161 sprintf( buf+strlen(buf) ,
8162 " slice_start = '%" PRId64 "'\n"
8163 " slice_end = '%" PRId64 "'\n" , nim->slice_start , nim->slice_end ) ;
8164 if( nim->slice_duration != 0.0 )
8165 sprintf( buf+strlen(buf) , " slice_duration = '%g'\n",
8166 nim->slice_duration ) ;
8167
8168 if( nim->descrip[0] != '\0' ){
8169 ebuf = escapize_string(nim->descrip) ;
8170 sprintf( buf+strlen(buf) , " descrip = %s\n",ebuf) ;
8171 free(ebuf) ;
8172 }
8173
8174 if( nim->aux_file[0] != '\0' ){
8175 ebuf = escapize_string(nim->aux_file) ;
8176 sprintf( buf+strlen(buf) , " aux_file = %s\n",ebuf) ;
8177 free(ebuf) ;
8178 }
8179
8180 if( nim->qform_code > 0 ){
8181 int i,j,k ;
8182
8183 sprintf( buf+strlen(buf) ,
8184 " qform_code = '%d'\n"
8185 " qform_code_name = '%s'\n"
8186 " qto_xyz_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
8187 nim->qform_code , nifti_xform_string(nim->qform_code) ,
8188 nim->qto_xyz.m[0][0] , nim->qto_xyz.m[0][1] ,
8189 nim->qto_xyz.m[0][2] , nim->qto_xyz.m[0][3] ,
8190 nim->qto_xyz.m[1][0] , nim->qto_xyz.m[1][1] ,
8191 nim->qto_xyz.m[1][2] , nim->qto_xyz.m[1][3] ,
8192 nim->qto_xyz.m[2][0] , nim->qto_xyz.m[2][1] ,
8193 nim->qto_xyz.m[2][2] , nim->qto_xyz.m[2][3] ,
8194 nim->qto_xyz.m[3][0] , nim->qto_xyz.m[3][1] ,
8195 nim->qto_xyz.m[3][2] , nim->qto_xyz.m[3][3] ) ;
8196
8197 sprintf( buf+strlen(buf) ,
8198 " qto_ijk_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
8199 nim->qto_ijk.m[0][0] , nim->qto_ijk.m[0][1] ,
8200 nim->qto_ijk.m[0][2] , nim->qto_ijk.m[0][3] ,
8201 nim->qto_ijk.m[1][0] , nim->qto_ijk.m[1][1] ,
8202 nim->qto_ijk.m[1][2] , nim->qto_ijk.m[1][3] ,
8203 nim->qto_ijk.m[2][0] , nim->qto_ijk.m[2][1] ,
8204 nim->qto_ijk.m[2][2] , nim->qto_ijk.m[2][3] ,
8205 nim->qto_ijk.m[3][0] , nim->qto_ijk.m[3][1] ,
8206 nim->qto_ijk.m[3][2] , nim->qto_ijk.m[3][3] ) ;
8207
8208 sprintf( buf+strlen(buf) ,
8209 " quatern_b = '%g'\n"
8210 " quatern_c = '%g'\n"
8211 " quatern_d = '%g'\n"
8212 " qoffset_x = '%g'\n"
8213 " qoffset_y = '%g'\n"
8214 " qoffset_z = '%g'\n"
8215 " qfac = '%g'\n" ,
8216 nim->quatern_b , nim->quatern_c , nim->quatern_d ,
8217 nim->qoffset_x , nim->qoffset_y , nim->qoffset_z , nim->qfac ) ;
8218
8219 nifti_dmat44_to_orientation( nim->qto_xyz , &i,&j,&k ) ;
8220 if( i > 0 && j > 0 && k > 0 )
8221 sprintf( buf+strlen(buf) ,
8222 " qform_i_orientation = '%s'\n"
8223 " qform_j_orientation = '%s'\n"
8224 " qform_k_orientation = '%s'\n" ,
8225 nifti_orientation_string(i) ,
8226 nifti_orientation_string(j) ,
8227 nifti_orientation_string(k) ) ;
8228 }
8229
8230 if( nim->sform_code > 0 ){
8231 int i,j,k ;
8232
8233 sprintf( buf+strlen(buf) ,
8234 " sform_code = '%d'\n"
8235 " sform_code_name = '%s'\n"
8236 " sto_xyz_matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
8237 nim->sform_code , nifti_xform_string(nim->sform_code) ,
8238 nim->sto_xyz.m[0][0] , nim->sto_xyz.m[0][1] ,
8239 nim->sto_xyz.m[0][2] , nim->sto_xyz.m[0][3] ,
8240 nim->sto_xyz.m[1][0] , nim->sto_xyz.m[1][1] ,
8241 nim->sto_xyz.m[1][2] , nim->sto_xyz.m[1][3] ,
8242 nim->sto_xyz.m[2][0] , nim->sto_xyz.m[2][1] ,
8243 nim->sto_xyz.m[2][2] , nim->sto_xyz.m[2][3] ,
8244 nim->sto_xyz.m[3][0] , nim->sto_xyz.m[3][1] ,
8245 nim->sto_xyz.m[3][2] , nim->sto_xyz.m[3][3] ) ;
8246
8247 sprintf( buf+strlen(buf) ,
8248 " sto_ijk matrix = '%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g'\n" ,
8249 nim->sto_ijk.m[0][0] , nim->sto_ijk.m[0][1] ,
8250 nim->sto_ijk.m[0][2] , nim->sto_ijk.m[0][3] ,
8251 nim->sto_ijk.m[1][0] , nim->sto_ijk.m[1][1] ,
8252 nim->sto_ijk.m[1][2] , nim->sto_ijk.m[1][3] ,
8253 nim->sto_ijk.m[2][0] , nim->sto_ijk.m[2][1] ,
8254 nim->sto_ijk.m[2][2] , nim->sto_ijk.m[2][3] ,
8255 nim->sto_ijk.m[3][0] , nim->sto_ijk.m[3][1] ,
8256 nim->sto_ijk.m[3][2] , nim->sto_ijk.m[3][3] ) ;
8257
8258 nifti_dmat44_to_orientation( nim->sto_xyz , &i,&j,&k ) ;
8259 if( i > 0 && j > 0 && k > 0 )
8260 sprintf( buf+strlen(buf) ,
8261 " sform_i_orientation = '%s'\n"
8262 " sform_j_orientation = '%s'\n"
8263 " sform_k_orientation = '%s'\n" ,
8264 nifti_orientation_string(i) ,
8265 nifti_orientation_string(j) ,
8266 nifti_orientation_string(k) ) ;
8267 }
8268
8269 sprintf( buf+strlen(buf) , " num_ext = '%d'\n", nim->num_ext ) ;
8270
8271 sprintf( buf+strlen(buf) , "/>\n" ) ; /* XML-ish closer */
8272
8273 nbuf = (int)strlen(buf) ;
8274 buf = (char *)realloc((void *)buf, nbuf+1); /* cut back to proper length */
8275 if( !buf ) fprintf(stderr,"** NITA: failed to realloc %d bytes\n",nbuf+1);
8276 return buf ;
8277 }
8278
8279 /*---------------------------------------------------------------------------*/
8280
8281 /*----------------------------------------------------------------------*/
8282 /*! get the byte order for this CPU
8283
8284 - LSB_FIRST means least significant byte, first (little endian)
8285 - MSB_FIRST means most significant byte, first (big endian)
8286 *//*--------------------------------------------------------------------*/
nifti_short_order(void)8287 int nifti_short_order(void) /* determine this CPU's byte order */
8288 {
8289 union { unsigned char bb[2] ;
8290 short ss ; } fred ;
8291
8292 fred.bb[0] = 1 ; fred.bb[1] = 0 ;
8293
8294 return (fred.ss == 1) ? LSB_FIRST : MSB_FIRST ;
8295 }
8296
8297 /*---------------------------------------------------------------------------*/
8298
8299 #undef QQNUM
8300 #undef QNUM
8301 #undef QSTR
8302
8303 /* macro to check lhs string against "n1"; if it matches,
8304 interpret rhs string as a number, and put it into nim->"n2" */
8305
8306 #define QQNUM(n1,n2,tt) if( strcmp(lhs,#n1)==0 ) nim->n2=(tt)strtod(rhs,NULL)
8307
8308 /* same, but where "n1" == "n2" */
8309
8310 #define QNUM(nam,tt) QQNUM(nam,nam,tt)
8311
8312 /* macro to check lhs string against "nam"; if it matches,
8313 put rhs string into nim->"nam" string, with max length = "ml" */
8314
8315 #define QSTR(nam,ml) if( strcmp(lhs,#nam) == 0 ) \
8316 strncpy(nim->nam,rhs,ml), nim->nam[ml]='\0'
8317
8318 /*---------------------------------------------------------------------------*/
8319 /*! Take an XML-ish ASCII string and create a NIFTI image header to match.
8320
8321 NULL is returned if enough information isn't present in the input string.
8322 - The image data can later be loaded with nifti_image_load().
8323 - The struct returned here can be liberated with nifti_image_free().
8324 - Not a lot of error checking is done here to make sure that the
8325 input values are reasonable!
8326 *//*-------------------------------------------------------------------------*/
nifti_image_from_ascii(const char * str,int * bytes_read)8327 nifti_image *nifti_image_from_ascii( const char *str, int * bytes_read )
8328 {
8329 char lhs[1024] , rhs[1024] ;
8330 int ii , spos, nn ;
8331 nifti_image *nim ; /* will be output */
8332
8333 if( str == NULL || *str == '\0' ) return NULL ; /* bad input!? */
8334
8335 /* scan for opening string */
8336
8337 spos = 0 ;
8338 ii = sscanf( str+spos , "%1023s%n" , lhs , &nn ) ; spos += nn ;
8339 if( ii == 0 || strcmp(lhs,"<nifti_image") != 0 ) return NULL ;
8340
8341 /* create empty image struct */
8342
8343 nim = (nifti_image *)calloc( 1 , sizeof(nifti_image) ) ;
8344 if( !nim ){
8345 fprintf(stderr,"** NIFA: failed to alloc nifti_image\n");
8346 return NULL;
8347 }
8348
8349 nim->nx = nim->ny = nim->nz = nim->nt
8350 = nim->nu = nim->nv = nim->nw = 1 ;
8351 nim->dx = nim->dy = nim->dz = nim->dt
8352 = nim->du = nim->dv = nim->dw = 0 ;
8353 nim->qfac = 1.0f ;
8354
8355 nim->byteorder = nifti_short_order() ;
8356
8357 /* starting at str[spos], scan for "equations" of the form
8358 lhs = 'rhs'
8359 and assign rhs values into the struct component named by lhs */
8360
8361 while(1){
8362
8363 while( isspace((int) str[spos]) ) spos++ ; /* skip whitespace */
8364 if( str[spos] == '\0' ) break ; /* end of string? */
8365
8366 /* get lhs string */
8367
8368 ii = sscanf( str+spos , "%1023s%n" , lhs , &nn ) ; spos += nn ;
8369 if( ii == 0 || strcmp(lhs,"/>") == 0 ) break ; /* end of input? */
8370
8371 /* skip whitespace and the '=' marker */
8372
8373 while( isspace((int) str[spos]) || str[spos] == '=' ) spos++ ;
8374 if( str[spos] == '\0' ) break ; /* end of string? */
8375
8376 /* if next character is a quote ', copy everything up to next '
8377 otherwise, copy everything up to next nonblank */
8378
8379 if( str[spos] == '\'' ){
8380 ii = spos+1 ;
8381 while( str[ii] != '\0' && str[ii] != '\'' ) ii++ ;
8382 nn = ii-spos-1 ; if( nn > 1023 ) nn = 1023 ;
8383 memcpy(rhs,str+spos+1,nn) ; rhs[nn] = '\0' ;
8384 spos = (str[ii] == '\'') ? ii+1 : ii ;
8385 } else {
8386 ii = sscanf( str+spos , "%1023s%n" , rhs , &nn ) ; spos += nn ;
8387 if( ii == 0 ) break ; /* nothing found? */
8388 }
8389 unescape_string(rhs) ; /* remove any XML escape sequences */
8390
8391 /* Now can do the assignment, based on lhs string.
8392 Start with special cases that don't fit the QNUM/QSTR macros. */
8393
8394 if( strcmp(lhs,"nifti_type") == 0 ){
8395 if( strcmp(rhs,"ANALYZE-7.5") == 0 )
8396 nim->nifti_type = NIFTI_FTYPE_ANALYZE ;
8397 else if( strcmp(rhs,"NIFTI-1+") == 0 )
8398 nim->nifti_type = NIFTI_FTYPE_NIFTI1_1 ;
8399 else if( strcmp(rhs,"NIFTI-1") == 0 )
8400 nim->nifti_type = NIFTI_FTYPE_NIFTI1_2 ;
8401 else if( strcmp(rhs,"NIFTI-1A") == 0 )
8402 nim->nifti_type = NIFTI_FTYPE_ASCII ;
8403 }
8404 else if( strcmp(lhs,"header_filename") == 0 ){
8405 nim->fname = nifti_strdup(rhs) ;
8406 }
8407 else if( strcmp(lhs,"image_filename") == 0 ){
8408 nim->iname = nifti_strdup(rhs) ;
8409 }
8410 else if( strcmp(lhs,"sto_xyz_matrix") == 0 ){
8411 sscanf( rhs , "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf" ,
8412 &(nim->sto_xyz.m[0][0]) , &(nim->sto_xyz.m[0][1]) ,
8413 &(nim->sto_xyz.m[0][2]) , &(nim->sto_xyz.m[0][3]) ,
8414 &(nim->sto_xyz.m[1][0]) , &(nim->sto_xyz.m[1][1]) ,
8415 &(nim->sto_xyz.m[1][2]) , &(nim->sto_xyz.m[1][3]) ,
8416 &(nim->sto_xyz.m[2][0]) , &(nim->sto_xyz.m[2][1]) ,
8417 &(nim->sto_xyz.m[2][2]) , &(nim->sto_xyz.m[2][3]) ,
8418 &(nim->sto_xyz.m[3][0]) , &(nim->sto_xyz.m[3][1]) ,
8419 &(nim->sto_xyz.m[3][2]) , &(nim->sto_xyz.m[3][3]) ) ;
8420 }
8421 else if( strcmp(lhs,"byteorder") == 0 ){
8422 if( strcmp(rhs,"MSB_FIRST") == 0 ) nim->byteorder = MSB_FIRST ;
8423 if( strcmp(rhs,"LSB_FIRST") == 0 ) nim->byteorder = LSB_FIRST ;
8424 }
8425 else QQNUM(image_offset,iname_offset,int) ;
8426 else QNUM(datatype,short int) ;
8427 else QNUM(ndim,int) ;
8428 else QNUM(nx,int) ;
8429 else QNUM(ny,int) ;
8430 else QNUM(nz,int) ;
8431 else QNUM(nt,int) ;
8432 else QNUM(nu,int) ;
8433 else QNUM(nv,int) ;
8434 else QNUM(nw,int) ;
8435 else QNUM(dx,float) ;
8436 else QNUM(dy,float) ;
8437 else QNUM(dz,float) ;
8438 else QNUM(dt,float) ;
8439 else QNUM(du,float) ;
8440 else QNUM(dv,float) ;
8441 else QNUM(dw,float) ;
8442 else QNUM(cal_min,float) ;
8443 else QNUM(cal_max,float) ;
8444 else QNUM(scl_slope,float) ;
8445 else QNUM(scl_inter,float) ;
8446 else QNUM(intent_code,short) ;
8447 else QNUM(intent_p1,float) ;
8448 else QNUM(intent_p2,float) ;
8449 else QNUM(intent_p3,float) ;
8450 else QSTR(intent_name,15) ;
8451 else QNUM(toffset,float) ;
8452 else QNUM(xyz_units,int) ;
8453 else QNUM(time_units,int) ;
8454 else QSTR(descrip,79) ;
8455 else QSTR(aux_file,23) ;
8456 else QNUM(qform_code,int) ;
8457 else QNUM(quatern_b,float) ;
8458 else QNUM(quatern_c,float) ;
8459 else QNUM(quatern_d,float) ;
8460 else QNUM(qoffset_x,float) ;
8461 else QNUM(qoffset_y,float) ;
8462 else QNUM(qoffset_z,float) ;
8463 else QNUM(qfac,float) ;
8464 else QNUM(sform_code,int) ;
8465 else QNUM(freq_dim,int) ;
8466 else QNUM(phase_dim,int) ;
8467 else QNUM(slice_dim,int) ;
8468 else QNUM(slice_code,int) ;
8469 else QNUM(slice_start,int) ;
8470 else QNUM(slice_end,int) ;
8471 else QNUM(slice_duration,float) ;
8472 else QNUM(num_ext,int) ;
8473
8474 } /* end of while loop */
8475
8476 if( bytes_read ) *bytes_read = spos+1; /* "process" last '\n' */
8477
8478 /* do miscellaneous checking and cleanup */
8479
8480 if( nim->ndim <= 0 ){ nifti_image_free(nim); return NULL; } /* bad! */
8481
8482 nifti_datatype_sizes( nim->datatype, &(nim->nbyper), &(nim->swapsize) );
8483 if( nim->nbyper == 0 ){ nifti_image_free(nim); return NULL; } /* bad! */
8484
8485 nim->dim[0] = nim->ndim ;
8486 nim->dim[1] = nim->nx ; nim->pixdim[1] = nim->dx ;
8487 nim->dim[2] = nim->ny ; nim->pixdim[2] = nim->dy ;
8488 nim->dim[3] = nim->nz ; nim->pixdim[3] = nim->dz ;
8489 nim->dim[4] = nim->nt ; nim->pixdim[4] = nim->dt ;
8490 nim->dim[5] = nim->nu ; nim->pixdim[5] = nim->du ;
8491 nim->dim[6] = nim->nv ; nim->pixdim[6] = nim->dv ;
8492 nim->dim[7] = nim->nw ; nim->pixdim[7] = nim->dw ;
8493
8494 nim->nvox = (int64_t)nim->nx * nim->ny * nim->nz
8495 * nim->nt * nim->nu * nim->nv * nim->nw ;
8496
8497 if( nim->qform_code > 0 )
8498 nim->qto_xyz = nifti_quatern_to_dmat44(
8499 nim->quatern_b, nim->quatern_c, nim->quatern_d,
8500 nim->qoffset_x, nim->qoffset_y, nim->qoffset_z,
8501 nim->dx , nim->dy , nim->dz ,
8502 nim->qfac ) ;
8503 else
8504 nim->qto_xyz = nifti_quatern_to_dmat44(
8505 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ,
8506 nim->dx , nim->dy , nim->dz , 0.0 ) ;
8507
8508
8509 nim->qto_ijk = nifti_dmat44_inverse( nim->qto_xyz ) ;
8510
8511 if( nim->sform_code > 0 )
8512 nim->sto_ijk = nifti_dmat44_inverse( nim->sto_xyz ) ;
8513
8514 return nim ;
8515 }
8516
8517
8518 /*---------------------------------------------------------------------------*/
8519 /*! validate the nifti_image
8520
8521 \return 1 if the structure seems valid, otherwise 0
8522
8523 \sa nifti_nim_has_valid_dims, nifti_hdr1_looks_good
8524 *//*-------------------------------------------------------------------------*/
nifti_nim_is_valid(nifti_image * nim,int complain)8525 int nifti_nim_is_valid(nifti_image * nim, int complain)
8526 {
8527 int errs = 0;
8528
8529 if( !nim ){
8530 fprintf(stderr,"** is_valid_nim: nim is NULL\n");
8531 return 0;
8532 }
8533
8534 if( g_opts.debug > 2 ) fprintf(stderr,"-d nim_is_valid check...\n");
8535
8536 /**- check that dim[] matches the individual values ndim, nx, ny, ... */
8537 if( ! nifti_nim_has_valid_dims(nim,complain) ){
8538 if( !complain ) return 0;
8539 errs++;
8540 }
8541
8542 /* might check nbyper, pixdim, q/sforms, swapsize, nifti_type, ... */
8543
8544 /**- be explicit in return of 0 or 1 */
8545 if( errs > 0 ) return 0;
8546 else return 1;
8547 }
8548
8549 /*---------------------------------------------------------------------------*/
8550 /*! validate nifti dimensions
8551
8552 \return 1 if valid, 0 if not
8553
8554 \sa nifti_nim_is_valid, nifti_hdr1_looks_good
8555
8556 rely on dim[] as the master
8557 *//*-------------------------------------------------------------------------*/
nifti_nim_has_valid_dims(nifti_image * nim,int complain)8558 int nifti_nim_has_valid_dims(nifti_image * nim, int complain)
8559 {
8560 int64_t prod, c;
8561 int errs = 0;
8562
8563 /**- start with dim[0]: failure here is considered terminal */
8564 if( nim->dim[0] <= 0 || nim->dim[0] > 7 ){
8565 errs++;
8566 if( complain )
8567 fprintf(stderr,"** NVd: dim[0] (%" PRId64 ") out of range [1,7]\n",nim->dim[0]);
8568 return 0;
8569 }
8570
8571 /**- check whether ndim equals dim[0] */
8572 if( nim->ndim != nim->dim[0] ){
8573 errs++;
8574 if( ! complain ) return 0;
8575 fprintf(stderr,"** NVd: ndim != dim[0] (%" PRId64 ",%" PRId64 ")\n",
8576 nim->ndim,nim->dim[0]);
8577 }
8578
8579 /**- compare each dim[i] to the proper nx, ny, ... */
8580 if( ( (nim->dim[0] >= 1) && (nim->dim[1] != nim->nx) ) ||
8581 ( (nim->dim[0] >= 2) && (nim->dim[2] != nim->ny) ) ||
8582 ( (nim->dim[0] >= 3) && (nim->dim[3] != nim->nz) ) ||
8583 ( (nim->dim[0] >= 4) && (nim->dim[4] != nim->nt) ) ||
8584 ( (nim->dim[0] >= 5) && (nim->dim[5] != nim->nu) ) ||
8585 ( (nim->dim[0] >= 6) && (nim->dim[6] != nim->nv) ) ||
8586 ( (nim->dim[0] >= 7) && (nim->dim[7] != nim->nw) ) ){
8587 errs++;
8588 if( !complain ) return 0;
8589 fprintf(stderr,"** NVd mismatch: dims = %" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 "\n"
8590 " nxyz... = %" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 ",%" PRId64 "\n",
8591 nim->dim[1], nim->dim[2], nim->dim[3],
8592 nim->dim[4], nim->dim[5], nim->dim[6], nim->dim[7],
8593 nim->nx, nim->ny, nim->nz,
8594 nim->nt, nim->nu, nim->nv, nim->nw );
8595 }
8596
8597 if( g_opts.debug > 2 ){
8598 fprintf(stderr,"-d check dim[%" PRId64 "] =", nim->dim[0]);
8599 for( c = 0; c < 7; c++ ) fprintf(stderr," %" PRId64 "", nim->dim[c]);
8600 fputc('\n', stderr);
8601 }
8602
8603 /**- check the dimensions, and that their product matches nvox */
8604 prod = 1;
8605 for( c = 1; c <= nim->dim[0]; c++ ){
8606 if( nim->dim[c] > 0)
8607 prod *= nim->dim[c];
8608 else if( nim->dim[c] <= 0 ){
8609 if( !complain ) return 0;
8610 fprintf(stderr,"** NVd: dim[%" PRId64 "] (=%" PRId64 ") <= 0\n",c, nim->dim[c]);
8611 errs++;
8612 }
8613 }
8614 if( prod != nim->nvox ){
8615 if( ! complain ) return 0;
8616 fprintf(stderr,"** NVd: nvox does not match %" PRId64 "-dim product (%" PRId64 ", %" PRId64 ")\n",
8617 nim->dim[0], nim->nvox, prod);
8618 errs++;
8619 }
8620
8621 /**- if debug, warn about any remaining dim that is neither 0, nor 1 */
8622 /* (values in dims above dim[0] are undefined, as reminded by Cinly
8623 Ooi and Alle Meije Wink) 16 Nov 2005 [rickr] */
8624 if( g_opts.debug > 1 )
8625 for( c = nim->dim[0]+1; c <= 7; c++ )
8626 if( nim->dim[c] != 0 && nim->dim[c] != 1 )
8627 fprintf(stderr,"** NVd warning: dim[%" PRId64 "] = %" PRId64 ", but ndim = %" PRId64 "\n",
8628 c, nim->dim[c], nim->dim[0]);
8629
8630 if( g_opts.debug > 2 )
8631 fprintf(stderr,"-d nim_has_valid_dims check, errs = %d\n", errs);
8632
8633 /**- return invalid or valid */
8634 if( errs > 0 ) return 0;
8635 else return 1;
8636 }
8637
8638
8639 /*---------------------------------------------------------------------------*/
8640 /*! read a nifti image, collapsed across dimensions according to dims[8] <pre>
8641
8642 This function may be used to read parts of a nifti dataset, such as
8643 the time series for a single voxel, or perhaps a slice. It is similar
8644 to nifti_image_load(), though the passed 'data' parameter is used for
8645 returning the image, not nim->data.
8646
8647 \param nim given nifti_image struct, corresponding to the data file
8648 \param dims given list of dimensions (see below)
8649 \param data pointer to data pointer (if *data is NULL, data will be
8650 allocated, otherwise not)
8651
8652 Here, dims is an array of 8 ints, similar to nim->dim[8]. While dims[0]
8653 is unused at this point, the other indices specify which dimensions to
8654 collapse (and at which index), and which not to collapse. If dims[i] is
8655 set to -1, then that entire dimension will be read in, from index 0 to
8656 index (nim->dim[i] - 1). If dims[i] >= 0, then only that index will be
8657 read in (so dims[i] must also be < nim->dim[i]).
8658
8659 Example: given nim->dim[8] = { 4, 64, 64, 21, 80, 1, 1, 1 } (4-D dataset)
8660
8661 if dims[8] = { 0, 5, 4, 17, -1, -1, -1, -1 }
8662 -> read time series for voxel i,j,k = 5,4,17
8663
8664 if dims[8] = { 0, -1, -1, -1, 17, -1, -1, -1 }
8665 -> read single volume at time point 17
8666
8667 Example: given nim->dim[8] = { 6, 64, 64, 21, 80, 4, 3, 1 } (6-D dataset)
8668
8669 if dims[8] = { 0, 5, 4, 17, -1, 2, 1, 0 }
8670 -> read time series for the voxel i,j,k = 5,4,17, and dim 5,6 = 2,1
8671
8672 if dims[8] = { 0, 5, 4, -1, -1, 0, 0, 0 }
8673 -> read time series for slice at i,j = 5,4, and dim 5,6,7 = 0,0,0
8674 (note that dims[7] is not relevant, but must be 0 or -1)
8675
8676 If *data is NULL, then *data will be set as a pointer to new memory,
8677 allocated here for the resulting collapsed image data.
8678
8679 e.g. { int dims[8] = { 0, 5, 4, 17, -1, -1, -1, -1 };
8680 void * data = NULL;
8681 ret_val = nifti_read_collapsed_image(nim, dims, &data);
8682 if( ret_val > 0 ){
8683 process_time_series(data);
8684 if( data != NULL ) free(data);
8685 }
8686 }
8687
8688 NOTE: If *data is not NULL, then it will be assumed that it points to
8689 valid memory, sufficient to hold the results. This is done for
8690 speed and possibly repeated calls to this function.
8691
8692 e.g. { int64_t dims[8] = { 0, -1, -1, -1, -1, -1, -1, -1 };
8693 void * data = NULL;
8694 for( zslice = 0; zslice < nzslices; zslice++ ){
8695 dims[3] = zslice;
8696 ret_val = nifti_read_collapsed_image(nim, dims, &data);
8697 if( ret_val > 0 ) process_slice(zslice, data);
8698 }
8699 if( data != NULL ) free(data);
8700 }
8701
8702 \return
8703 - the total number of bytes read, or < 0 on failure
8704 - the read and byte-swapped data, in 'data' </pre>
8705
8706 \sa nifti_image_read, nifti_image_free, nifti_image_read_bricks
8707 nifti_image_load
8708 *//*-------------------------------------------------------------------------*/
nifti_read_collapsed_image(nifti_image * nim,const int64_t dims[8],void ** data)8709 int64_t nifti_read_collapsed_image( nifti_image * nim, const int64_t dims [8],
8710 void ** data )
8711 {
8712 znzFile fp;
8713 int64_t prods[8]; /* sizes are bounded by dims[], so 8 */
8714 int pivots[8], nprods; /* sizes are bounded by dims[], so 8 */
8715 int64_t c, bytes;
8716
8717 /** - check pointers for sanity */
8718 if( !nim || !dims || !data ){
8719 fprintf(stderr,"** nifti_RCI: bad params %p, %p, %p\n",
8720 (void *)nim, (const void *)dims, (void *)data);
8721 return -1;
8722 }
8723
8724 if( g_opts.debug > 2 ){
8725 fprintf(stderr,"-d read_collapsed_image:\n dims =");
8726 for(c = 0; c < 8; c++) fprintf(stderr," %3" PRId64, dims[c]);
8727 fprintf(stderr,"\n nim->dims =");
8728 for(c = 0; c < 8; c++) fprintf(stderr," %3" PRId64, nim->dim[c]);
8729 fputc('\n', stderr);
8730 }
8731
8732 /** - verify that dim[] makes sense */
8733 if( ! nifti_nim_is_valid(nim, g_opts.debug > 0) ){
8734 fprintf(stderr,"** invalid nim (file is '%s')\n", nim->fname );
8735 return -1;
8736 }
8737
8738 /** - verify that dims[] makes sense for this dataset */
8739 for( c = 1; c <= nim->dim[0]; c++ ){
8740 if( dims[c] >= nim->dim[c] ){
8741 fprintf(stderr,"** nifti_RCI: dims[%" PRId64 "] >= nim->dim[%" PRId64 "] (%" PRId64 ",%" PRId64 ")\n",
8742 c, c, dims[c], nim->dim[c]);
8743 return -1;
8744 }
8745 }
8746
8747 /** - prepare pivot list - pivots are fixed indices */
8748 if( make_pivot_list(nim, dims, pivots, prods, &nprods) < 0 ) return -1;
8749
8750 bytes = rci_alloc_mem(data, prods, nprods, nim->nbyper);
8751 if( bytes < 0 ) return -1;
8752
8753 /** - open the image file for reading at the appropriate offset */
8754 fp = nifti_image_load_prep( nim );
8755 if( ! fp ){ free(*data); *data = NULL; return -1; } /* failure */
8756
8757 /** - call the recursive reading function, passing nim, the pivot info,
8758 location to store memory, and file pointer and position */
8759 c = rci_read_data(nim, pivots, prods, nprods, dims, (char *)*data, fp,
8760 znztell(fp));
8761 znzclose(fp); /* in any case, close the file */
8762 if( c < 0 ){ free(*data); *data = NULL; return -1; } /* failure */
8763
8764 if( g_opts.debug > 1 )
8765 fprintf(stderr,"+d read %" PRId64 " bytes of collapsed image from %s\n",
8766 bytes, nim->fname);
8767
8768 return bytes;
8769 }
8770
8771
8772 /* local function to find strides per dimension. assumes 7D size and
8773 ** stride array.
8774 */
8775 static void
compute_strides(int64_t * strides,const int64_t * size,int nbyper)8776 compute_strides(int64_t *strides,const int64_t *size,int nbyper)
8777 {
8778 int i;
8779 strides[0] = nbyper;
8780 for(i = 1; i < 7; i++)
8781 {
8782 strides[i] = size[i-1] * strides[i-1];
8783 }
8784 }
8785
8786 /*---------------------------------------------------------------------------*/
8787 /*! read an arbitrary subregion from a nifti image
8788
8789 This function may be used to read a single arbitary subregion of any
8790 rectangular size from a nifti dataset, such as a small 5x5x5 subregion
8791 around the center of a 3D image.
8792
8793 \param nim given nifti_image struct, corresponding to the data file
8794 \param start_index the index location of first voxel that will be returned
8795 \param region_size the size of the subregion to be returned
8796 \param data pointer to data pointer (if *data is NULL, data will be
8797 allocated, otherwise not)
8798
8799 Example: given nim->dim[8] = {3, 64, 64, 64, 1, 1, 1, 1 } (3-D dataset)
8800
8801 if start_index[7] = { 29, 29, 29, 0, 0, 0, 0 } and
8802 region_size[7] = { 5, 5, 5, 1, 1, 1, 1 }
8803 -> read 5x5x5 region starting with the first voxel at (29,29,29)
8804
8805 NOTE: If *data is not NULL, then it will be assumed that it points to
8806 valid memory, sufficient to hold the results. This is done for
8807 speed and possibly repeated calls to this function.
8808 \return
8809 - the total number of bytes read, or < 0 on failure
8810 - the read and byte-swapped data, in 'data' </pre>
8811
8812 \sa nifti_image_read, nifti_image_free, nifti_image_read_bricks
8813 nifti_image_load, nifti_read_collapsed_image
8814 *//*-------------------------------------------------------------------------*/
nifti_read_subregion_image(nifti_image * nim,int64_t * start_index,int64_t * region_size,void ** data)8815 int64_t nifti_read_subregion_image( nifti_image * nim,
8816 int64_t *start_index,
8817 int64_t *region_size,
8818 void ** data )
8819 {
8820 znzFile fp; /* file to read */
8821 int64_t i,j,k,l,m,n; /* indices for dims */
8822 int64_t bytes = 0; /* total # bytes read */
8823 int64_t total_alloc_size; /* size of buffer allocation */
8824 char *readptr; /* where in *data to read next */
8825 int64_t strides[7]; /* strides between dimensions */
8826 int64_t collapsed_dims[8]; /* for read_collapsed_image */
8827 int64_t *image_size; /* pointer to dimensions in header */
8828 int64_t initial_offset;
8829 int64_t offset; /* seek offset for reading current row */
8830
8831 /* probably ignored, but set to ndim for consistency*/
8832 collapsed_dims[0] = nim->ndim;
8833
8834 /* build a dims array for collapsed image read */
8835 for(i = 0; i < nim->ndim; i++) {
8836 /* if you take the whole extent in this dimension */
8837 if(start_index[i] == 0 && region_size[i] == nim->dim[i+1])
8838 collapsed_dims[i+1] = -1;
8839 /* if you specify a single element in this dimension */
8840 else if(region_size[i] == 1)
8841 collapsed_dims[i+1] = start_index[i];
8842 else
8843 collapsed_dims[i+1] = -2; /* sentinel value */
8844 }
8845 /* fill out end of collapsed_dims */
8846 for(i = nim->ndim ; i < 7; i++)
8847 collapsed_dims[i+1] = -1;
8848
8849 /* check to see whether collapsed read is possible */
8850 for(i = 1; i <= nim->ndim; i++)
8851 if(collapsed_dims[i] == -2) break;
8852
8853 /* if you get through all the dimensions without hitting
8854 ** a subrange of size > 1, a collapsed read is possible
8855 */
8856 if(i > nim->ndim)
8857 return nifti_read_collapsed_image(nim, collapsed_dims, data);
8858
8859 /* point past first element of dim, which holds nim->ndim */
8860 image_size = &(nim->dim[1]);
8861
8862 /* check region sizes for sanity */
8863 for(i = 0; i < nim->ndim; i++)
8864 if(start_index[i] + region_size[i] > image_size[i]) {
8865 if(g_opts.debug > 1)
8866 fprintf(stderr,"region doesn't fit within image size\n");
8867 return -1;
8868 }
8869
8870 /* get the file open */
8871 fp = nifti_image_load_prep( nim );
8872 /* the current offset is just past the nifti header, save
8873 * location so that SEEK_SET can be used below
8874 */
8875 initial_offset = znztell(fp);
8876 /* get strides*/
8877 compute_strides(strides,image_size,nim->nbyper);
8878
8879 total_alloc_size = nim->nbyper; /* size of pixel */
8880
8881 /* find alloc size */
8882 for(i = 0; i < nim->ndim; i++) total_alloc_size *= region_size[i];
8883
8884 /* allocate buffer, if necessary */
8885 if(! *data) *data = (void *)malloc(total_alloc_size);
8886
8887 if(! *data) {
8888 if(g_opts.debug > 1)
8889 fprintf(stderr,"allocation of %" PRId64 " bytes failed\n",total_alloc_size);
8890 return -1;
8891 }
8892
8893 /* point to start of data buffer as char * */
8894 readptr = *((char **)data);
8895 {
8896 /* can't assume that start_index and region_size have any more than
8897 ** nim->ndim elements so make local copies, filled out to seven elements
8898 */
8899 int64_t si[7], rs[7];
8900 for(i = 0; i < nim->ndim; i++) {
8901 si[i] = start_index[i];
8902 rs[i] = region_size[i];
8903 }
8904 for(i = nim->ndim; i < 7; i++) {
8905 si[i] = 0;
8906 rs[i] = 1;
8907 }
8908
8909 /* loop through subregion and read a row at a time */
8910 for(i = si[6]; i < (si[6] + rs[6]); i++) {
8911 for(j = si[5]; j < (si[5] + rs[5]); j++) {
8912 for(k = si[4]; k < (si[4] + rs[4]); k++) {
8913 for(l = si[3]; l < (si[3] + rs[3]); l++) {
8914 for(m = si[2]; m < (si[2] + rs[2]); m++) {
8915 for(n = si[1]; n < (si[1] + rs[1]); n++) {
8916 int64_t nread,read_amount;
8917 offset = initial_offset +
8918 (i * strides[6]) +
8919 (j * strides[5]) +
8920 (k * strides[4]) +
8921 (l * strides[3]) +
8922 (m * strides[2]) +
8923 (n * strides[1]) +
8924 (si[0] * strides[0]);
8925 znzseek(fp, offset, SEEK_SET); /* seek to current row */
8926 read_amount = rs[0] * nim->nbyper; /* read a row of subregion */
8927 nread = nifti_read_buffer(fp, readptr, read_amount, nim);
8928 if(nread != read_amount) {
8929 if(g_opts.debug > 1) {
8930 fprintf(stderr,"read of %" PRId64 " bytes failed\n",read_amount);
8931 return -1;
8932 }
8933 }
8934 bytes += nread;
8935 readptr += read_amount;
8936 }
8937 }
8938 }
8939 }
8940 }
8941 }
8942 }
8943 return bytes;
8944 }
8945
8946
8947 /* read the data from the file pointed to by fp
8948
8949 - this a recursive function, so start with the base case
8950 - data is now (char *) for easy incrementing
8951
8952 return 0 on success, < 0 on failure
8953 */
rci_read_data(nifti_image * nim,int * pivots,int64_t * prods,int nprods,const int64_t dims[],char * data,znzFile fp,int64_t base_offset)8954 static int rci_read_data(nifti_image * nim, int * pivots, int64_t * prods,
8955 int nprods, const int64_t dims[], char * data,
8956 znzFile fp, int64_t base_offset)
8957 {
8958 int64_t sublen, offset, read_size;
8959 int c;
8960
8961 /* bad check first - base_offset may not have been checked */
8962 if( nprods <= 0 ){
8963 fprintf(stderr,"** rci_read_data, bad prods, %d\n", nprods);
8964 return -1;
8965 }
8966
8967 /* base case: actually read the data */
8968 if( nprods == 1 ){
8969 int64_t nread, bytes;
8970
8971 /* make sure things look good here */
8972 if( *pivots != 0 ){
8973 fprintf(stderr,"** rciRD: final pivot == %d!\n", *pivots);
8974 return -1;
8975 }
8976
8977 /* so just seek and read (prods[0] * nbyper) bytes from the file */
8978 znzseek(fp, base_offset, SEEK_SET);
8979 bytes = prods[0] * nim->nbyper;
8980 nread = nifti_read_buffer(fp, data, bytes, nim);
8981 if( nread != bytes ){
8982 fprintf(stderr,"** rciRD: read only %" PRId64 " of %" PRId64 " bytes from '%s'\n",
8983 nread, bytes, nim->fname);
8984 return -1;
8985 } else if( g_opts.debug > 3 )
8986 fprintf(stderr,"+d successful read of %" PRId64 " bytes at offset %" PRId64 "\n",
8987 bytes, base_offset);
8988
8989 return 0; /* done with base case - return success */
8990 }
8991
8992 /* not the base case, so do a set of reduced reads */
8993
8994 /* compute size of sub-brick: all dimensions below pivot */
8995 for( c = 1, sublen = 1; c < *pivots; c++ ) sublen *= nim->dim[c];
8996
8997 /* compute number of values to read, i.e. remaining prods */
8998 for( c = 1, read_size = 1; c < nprods; c++ ) read_size *= prods[c];
8999 read_size *= nim->nbyper; /* and multiply by bytes per voxel */
9000
9001 /* now repeatedly compute offsets, and recursively read */
9002 for( c = 0; c < prods[0]; c++ ){
9003 /* offset is (c * sub-block size (including pivot dim)) */
9004 /* + (dims[] index into pivot sub-block) */
9005 /* the unneeded multiplication is to make this more clear */
9006 offset = (int64_t)c * sublen * nim->dim[*pivots] +
9007 (int64_t)sublen * dims[*pivots];
9008 offset *= nim->nbyper;
9009
9010 if( g_opts.debug > 3 )
9011 fprintf(stderr,"-d reading %" PRId64 " bytes, foff %" PRId64 " + %" PRId64 ", doff %" PRId64 "\n",
9012 read_size, base_offset, offset, c*read_size);
9013
9014 /* now read the next level down, adding this offset */
9015 if( rci_read_data(nim, pivots+1, prods+1, nprods-1, dims,
9016 data + c * read_size, fp, base_offset + offset) < 0 )
9017 return -1;
9018 }
9019
9020 return 0;
9021 }
9022
9023
9024 /* allocate memory for all collapsed image data
9025
9026 If *data is already set, do not allocate, but still calculate
9027 size for debug report.
9028
9029 return total size on success, and < 0 on failure
9030 */
rci_alloc_mem(void ** data,int64_t prods[8],int nprods,int nbyper)9031 static int rci_alloc_mem(void **data, int64_t prods[8], int nprods, int nbyper )
9032 {
9033 int64_t size;
9034 int memindex;
9035
9036 if( nbyper < 0 || nprods < 1 || nprods > 8 ){
9037 fprintf(stderr,"** rci_am: bad params, %d, %d\n", nbyper, nprods);
9038 return -1;
9039 }
9040
9041 for( memindex = 0, size = 1; memindex < nprods; memindex++ )
9042 size *= prods[memindex];
9043
9044 size *= nbyper;
9045
9046 if( ! *data ){ /* then allocate what is needed */
9047 if( g_opts.debug > 1 )
9048 fprintf(stderr,"+d alloc %" PRId64 " (%" PRId64 " x %d) bytes for collapsed image\n",
9049 size, size/nbyper, nbyper);
9050
9051 *data = malloc(size); /* actually allocate the memory */
9052 if( ! *data ){
9053 fprintf(stderr,"** rci_am: failed to alloc %" PRId64 " bytes for data\n", size);
9054 return -1;
9055 }
9056 } else if( g_opts.debug > 1 )
9057 fprintf(stderr,"-d rci_am: *data already set, need %" PRId64 " x %d bytes\n",
9058 size/nbyper, nbyper);
9059
9060 return size;
9061 }
9062
9063
9064 /* prepare a pivot list for reading
9065
9066 The pivot points are the indices into dims where the calling function
9067 wants to collapse a dimension. The last pivot should always be zero
9068 (note that we have space for that in the lists).
9069 */
make_pivot_list(nifti_image * nim,const int64_t dims[],int pivots[],int64_t prods[],int * nprods)9070 static int make_pivot_list(nifti_image *nim, const int64_t dims[], int pivots[],
9071 int64_t prods[], int * nprods )
9072 {
9073 int len, dind;
9074
9075 len = 0;
9076 dind = nim->dim[0];
9077 while( dind > 0 ){
9078 prods[len] = 1;
9079 while( dind > 0 && (nim->dim[dind] == 1 || dims[dind] == -1) ){
9080 prods[len] *= nim->dim[dind];
9081 dind--;
9082 }
9083 pivots[len] = dind;
9084 len++;
9085 dind--; /* fine, let it drop out at -1 */
9086 }
9087
9088 /* make sure to include 0 as a pivot (instead of just 1, if it is) */
9089 if( pivots[len-1] != 0 ){
9090 pivots[len] = 0;
9091 prods[len] = 1;
9092 len++;
9093 }
9094
9095 *nprods = len;
9096
9097 if( g_opts.debug > 2 ){
9098 fprintf(stderr,"+d pivot list created, pivots :");
9099 for(dind = 0; dind < len; dind++) fprintf(stderr," %d", pivots[dind]);
9100 fprintf(stderr,", prods :");
9101 for(dind = 0; dind < len; dind++) fprintf(stderr," %" PRId64 "", prods[dind]);
9102 fputc('\n',stderr);
9103 }
9104
9105 return 0;
9106 }
9107
9108
9109 #undef ISEND
9110 #define ISEND(c) ( (c)==']' || (c)=='}' || (c)=='\0' )
9111
9112 /*---------------------------------------------------------------------*/
9113 /*! Get an integer list in the range 0..(nvals-1), from the
9114 character string str. If we call the output pointer fred,
9115 then fred[0] = number of integers in the list (> 0), and
9116 fred[i] = i-th integer in the list for i=1..fred[0].
9117 If on return, fred == NULL or fred[0] == 0, then something is
9118 wrong, and the caller must deal with that.
9119
9120 Syntax of input string:
9121 - initial '{' or '[' is skipped, if present
9122 - ends when '}' or ']' or end of string is found
9123 - contains entries separated by commas
9124 - entries have one of these forms:
9125 - a single number
9126 - a dollar sign '$', which means nvals-1
9127 - a sequence of consecutive numbers in the form "a..b" or
9128 "a-b", where "a" and "b" are single numbers (or '$')
9129 - a sequence of evenly spaced numbers in the form
9130 "a..b(c)" or "a-b(c)", where "c" encodes the step
9131 - Example: "[2,7..4,3..9(2)]" decodes to the list
9132 2 7 6 5 4 3 5 7 9
9133 - entries should be in the range 0..nvals-1
9134
9135 (borrowed, with permission, from thd_intlist.c)
9136 *//*-------------------------------------------------------------------*/
nifti_get_int64list(int64_t nvals,const char * str)9137 int64_t * nifti_get_int64list( int64_t nvals , const char * str )
9138 {
9139 int64_t *subv = NULL ;
9140 int64_t ii , nout ;
9141 int64_t ibot,itop,istep , nused ;
9142 int ipos , slen ;
9143 char *cpt ;
9144
9145 /* Meaningless input? */
9146 if( nvals < 1 ) return NULL ;
9147
9148 /* No selection list? */
9149 if( str == NULL || str[0] == '\0' ) return NULL ;
9150
9151 /* skip initial '[' or '{' */
9152 subv = (int64_t *)malloc( sizeof(int64_t) * 2 ) ;
9153 if( !subv ) {
9154 fprintf(stderr,"** nifti_get_intlist: failed alloc of 2 ints\n");
9155 return NULL;
9156 }
9157 subv[0] = nout = 0 ;
9158
9159 ipos = 0 ;
9160 if( str[ipos] == '[' || str[ipos] == '{' ) ipos++ ;
9161
9162 if( g_opts.debug > 1 )
9163 fprintf(stderr,"-d making int_list (vals = %" PRId64 ") from '%s'\n", nvals, str);
9164
9165 /**- for each sub-selector until end of input... */
9166
9167 slen = (int)strlen(str) ;
9168 while( ipos < slen && !ISEND(str[ipos]) ){
9169
9170 while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */
9171 if( ISEND(str[ipos]) ) break ; /* done */
9172
9173 /**- get starting value */
9174
9175 if( str[ipos] == '$' ){ /* special case */
9176 ibot = nvals-1 ; ipos++ ;
9177 } else { /* decode an integer */
9178 ibot = strtoll( str+ipos , &cpt , 10 ) ;
9179 if( ibot < 0 ){
9180 fprintf(stderr,"** ERROR: list index %" PRId64 " is out of range 0..%" PRId64 "\n",
9181 ibot,nvals-1) ;
9182 free(subv) ; return NULL ;
9183 }
9184 if( ibot >= nvals ){
9185 fprintf(stderr,"** ERROR: list index %" PRId64 " is out of range 0..%" PRId64 "\n",
9186 ibot,nvals-1) ;
9187 free(subv) ; return NULL ;
9188 }
9189 nused = (cpt-(str+ipos)) ;
9190 if( ibot == 0 && nused == 0 ){
9191 fprintf(stderr,"** ERROR: list syntax error '%s'\n",str+ipos) ;
9192 free(subv) ; return NULL ;
9193 }
9194 ipos += nused ;
9195 }
9196
9197 while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */
9198
9199 /**- if that's it for this sub-selector, add one value to list */
9200
9201 if( str[ipos] == ',' || ISEND(str[ipos]) ){
9202 nout++ ;
9203 subv = (int64_t *)realloc( (char *)subv , sizeof(int64_t)*(nout+1) ) ;
9204 if( !subv ) {
9205 fprintf(stderr,"** nifti_get_intlist: failed realloc of %" PRId64 " ints\n",
9206 nout+1);
9207 return NULL;
9208 }
9209 subv[0] = nout ;
9210 subv[nout] = ibot ;
9211 if( ISEND(str[ipos]) ) break ; /* done */
9212 ipos++ ; continue ; /* re-start loop at next sub-selector */
9213 }
9214
9215 /**- otherwise, must have '..' or '-' as next inputs */
9216
9217 if( str[ipos] == '-' ){
9218 ipos++ ;
9219 } else if( str[ipos] == '.' && str[ipos+1] == '.' ){
9220 ipos++ ; ipos++ ;
9221 } else {
9222 fprintf(stderr,"** ERROR: index list syntax is bad: '%s'\n",
9223 str+ipos) ;
9224 free(subv) ; return NULL ;
9225 }
9226
9227 /**- get ending value for loop now */
9228
9229 if( str[ipos] == '$' ){ /* special case */
9230 itop = nvals-1 ; ipos++ ;
9231 } else { /* decode an integer */
9232 itop = strtoll( str+ipos , &cpt , 10 ) ;
9233 if( itop < 0 ){
9234 fprintf(stderr,"** ERROR: index %" PRId64 " is out of range 0..%" PRId64 "\n",
9235 itop,nvals-1) ;
9236 free(subv) ; return NULL ;
9237 }
9238 if( itop >= nvals ){
9239 fprintf(stderr,"** ERROR: index %" PRId64 " is out of range 0..%" PRId64 "\n",
9240 itop,nvals-1) ;
9241 free(subv) ; return NULL ;
9242 }
9243 nused = (cpt-(str+ipos)) ;
9244 if( itop == 0 && nused == 0 ){
9245 fprintf(stderr,"** ERROR: index list syntax error '%s'\n",str+ipos) ;
9246 free(subv) ; return NULL ;
9247 }
9248 ipos += nused ;
9249 }
9250
9251 /**- set default loop step */
9252
9253 istep = (ibot <= itop) ? 1 : -1 ;
9254
9255 while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */
9256
9257 /**- check if we have a non-default loop step */
9258
9259 if( str[ipos] == '(' ){ /* decode an integer */
9260 ipos++ ;
9261 istep = strtoll( str+ipos , &cpt , 10 ) ;
9262 if( istep == 0 ){
9263 fprintf(stderr,"** ERROR: index loop step is 0!\n") ;
9264 free(subv) ; return NULL ;
9265 }
9266 nused = (cpt-(str+ipos)) ;
9267 ipos += nused ;
9268 if( str[ipos] == ')' ) ipos++ ;
9269 if( (ibot-itop)*istep > 0 ){
9270 fprintf(stderr,"** WARNING: index list '%" PRId64 "..%" PRId64 "(%" PRId64 ")' means nothing\n",
9271 ibot,itop,istep ) ;
9272 }
9273 }
9274
9275 /**- add values to output */
9276
9277 for( ii=ibot ; (ii-itop)*istep <= 0 ; ii += istep ){
9278 nout++ ;
9279 subv = (int64_t *)realloc( (char *)subv , sizeof(int64_t)*(nout+1) ) ;
9280 if( !subv ) {
9281 fprintf(stderr,"** nifti_get_intlist: failed realloc of %" PRId64 " ints\n",
9282 nout+1);
9283 return NULL;
9284 }
9285 subv[0] = nout ;
9286 subv[nout] = ii ;
9287 }
9288
9289 /**- check if we have a comma to skip over */
9290
9291 while( isspace((int) str[ipos]) ) ipos++ ; /* skip blanks */
9292 if( str[ipos] == ',' ) ipos++ ; /* skip commas */
9293
9294 } /* end of loop through selector string */
9295
9296 if( g_opts.debug > 1 ) {
9297 fprintf(stderr,"+d int_list (vals = %" PRId64 "): ", subv[0]);
9298 for( ii = 1; ii <= subv[0]; ii++ ) fprintf(stderr,"%" PRId64 " ", subv[ii]);
9299 fputc('\n',stderr);
9300 }
9301
9302 if( subv[0] == 0 ){ free(subv); subv = NULL; }
9303 return subv ;
9304 }
9305
9306 /*! a 32-bit version of nifti_get_int64list */
nifti_get_intlist(int nvals,const char * str)9307 int * nifti_get_intlist( int nvals , const char * str )
9308 {
9309 int *ilist=NULL;
9310 int64_t *i64list=NULL, nints, index;
9311
9312 i64list = nifti_get_int64list((int64_t)nvals, str);
9313 if( !i64list ) return NULL;
9314
9315 /* check that the length is between 1 and INT_MAX */
9316 nints = i64list[0];
9317 if( nints <= 0 ) { free(i64list); return NULL; }
9318
9319 if( nints > INT_MAX ) {
9320 fprintf(stderr,"** N_get_intlist: %" PRId64 " ints is too long for 32-bits\n",
9321 nints);
9322 free(i64list);
9323 return NULL;
9324 }
9325
9326 /* have a valid result, copy as ints */
9327 ilist = (int *)malloc((nints+1) * sizeof(int));
9328 if( !ilist ) {
9329 fprintf(stderr,"** N_get_intlist: failed to alloc %" PRId64 " ints\n", nints);
9330 free(i64list);
9331 return NULL;
9332 }
9333
9334 /* copy list, including length at index 0 */
9335 for( index=0; index <= nints; index++ ) {
9336 if( i64list[index] > INT_MAX ) {
9337 fprintf(stderr,"** N_get_intlist: value %" PRId64 " too big for 32-bits\n",
9338 i64list[index]);
9339 free(ilist);
9340 free(i64list);
9341 return NULL;
9342 }
9343 ilist[index] = (int)i64list[index];
9344 }
9345
9346 free(i64list);
9347
9348 return ilist;
9349 }
9350
9351 /*---------------------------------------------------------------------*/
9352 /*! Given a NIFTI_TYPE string, such as "NIFTI_TYPE_INT16", return the
9353 * corresponding integral type code. The type code is the macro
9354 * value defined in nifti1.h.
9355 *//*-------------------------------------------------------------------*/
nifti_datatype_from_string(const char * name)9356 int nifti_datatype_from_string( const char * name )
9357 {
9358 int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele);
9359 int c;
9360
9361 if( !name ) return DT_UNKNOWN;
9362
9363 for( c = tablen-1; c > 0; c-- )
9364 if( !strcmp(name, nifti_type_list[c].name) )
9365 break;
9366
9367 return nifti_type_list[c].type;
9368 }
9369
9370
9371 /*---------------------------------------------------------------------*/
9372 /*! Given a NIFTI_TYPE value, such as NIFTI_TYPE_INT16, return the
9373 * corresponding macro label as a string. The dtype code is the
9374 * macro value defined in nifti1.h.
9375 *//*-------------------------------------------------------------------*/
nifti_datatype_to_string(int dtype)9376 const char * nifti_datatype_to_string( int dtype )
9377 {
9378 int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele);
9379 int c;
9380
9381 for( c = tablen-1; c > 0; c-- )
9382 if( nifti_type_list[c].type == dtype )
9383 break;
9384
9385 return nifti_type_list[c].name;
9386 }
9387
9388
9389 /*---------------------------------------------------------------------*/
9390 /*! Determine whether dtype is a valid NIFTI_TYPE.
9391 *
9392 * DT_UNKNOWN is considered invalid
9393 *
9394 * The only difference 'for_nifti' makes is that DT_BINARY
9395 * should be invalid for a NIfTI dataset.
9396 *//*-------------------------------------------------------------------*/
nifti_datatype_is_valid(int dtype,int for_nifti)9397 int nifti_datatype_is_valid( int dtype, int for_nifti )
9398 {
9399 int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele);
9400 int c;
9401
9402 /* special case */
9403 if( for_nifti && dtype == DT_BINARY ) return 0;
9404
9405 for( c = tablen-1; c > 0; c-- )
9406 if( nifti_type_list[c].type == dtype )
9407 return 1;
9408
9409 return 0;
9410 }
9411
9412
9413 /*---------------------------------------------------------------------*/
9414 /*! Only as a test, verify that the new nifti_type_list table matches
9415 * the the usage of nifti_datatype_sizes (which could be changed to
9416 * use the table, if there were interest).
9417 *
9418 * return the number of errors (so 0 is success, as usual)
9419 *//*-------------------------------------------------------------------*/
nifti_test_datatype_sizes(int verb)9420 int nifti_test_datatype_sizes(int verb)
9421 {
9422 int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele);
9423 int nbyper, ssize;
9424 int c, errs = 0;
9425
9426 for( c = 0; c < tablen; c++ )
9427 {
9428 nbyper = ssize = -1;
9429 nifti_datatype_sizes(nifti_type_list[c].type, &nbyper, &ssize);
9430 if( nbyper < 0 || ssize < 0 ||
9431 nbyper != nifti_type_list[c].nbyper ||
9432 ssize != nifti_type_list[c].swapsize )
9433 {
9434 if( verb || g_opts.debug > 2 )
9435 fprintf(stderr, "** type mismatch: %s, %d, %d, %d : %d, %d\n",
9436 nifti_type_list[c].name, nifti_type_list[c].type,
9437 nifti_type_list[c].nbyper, nifti_type_list[c].swapsize,
9438 nbyper, ssize);
9439 errs++;
9440 }
9441 }
9442
9443 if( errs )
9444 fprintf(stderr,"** nifti_test_datatype_sizes: found %d errors\n",errs);
9445 else if( verb || g_opts.debug > 1 )
9446 fprintf(stderr,"-- nifti_test_datatype_sizes: all OK\n");
9447
9448 return errs;
9449 }
9450
9451
9452 /*---------------------------------------------------------------------*/
9453 /*! Display the nifti_type_list table.
9454 *
9455 * if which == 1 : display DT_*
9456 * if which == 2 : display NIFTI_TYPE*
9457 * else : display all
9458 *//*-------------------------------------------------------------------*/
nifti_disp_type_list(int which)9459 int nifti_disp_type_list( int which )
9460 {
9461 const char * style;
9462 int tablen = sizeof(nifti_type_list)/sizeof(nifti_type_ele);
9463 int lwhich, c;
9464
9465 if ( which == 1 ){ lwhich = 1; style = "DT_"; }
9466 else if( which == 2 ){ lwhich = 2; style = "NIFTI_TYPE_"; }
9467 else { lwhich = 3; style = "ALL"; }
9468
9469 printf("nifti_type_list entries (%s) :\n"
9470 " name type nbyper swapsize\n"
9471 " --------------------- ---- ------ --------\n", style);
9472
9473 for( c = 0; c < tablen; c++ )
9474 if( (lwhich & 1 && nifti_type_list[c].name[0] == 'D') ||
9475 (lwhich & 2 && nifti_type_list[c].name[0] == 'N') )
9476 printf(" %-22s %5d %3d %5d\n",
9477 nifti_type_list[c].name,
9478 nifti_type_list[c].type,
9479 nifti_type_list[c].nbyper,
9480 nifti_type_list[c].swapsize);
9481
9482 return 0;
9483 }
9484
9485
9486 } // namespace mirtk
9487