TPCCLIB
Loading...
Searching...
No Matches
niftiio.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include "tpcnifti.h"
8/*****************************************************************************/
9
10/*****************************************************************************/
19 const char *filename,
24 char *hdrfile,
29 char *imgfile,
33 char *siffile,
35 NIFTI_DSR *header,
37 TPCSTATUS *status
38) {
39 int verbose=0; if(status!=NULL) verbose=status->verbose;
40 if(verbose>0) {printf("%s(%s, ...)\n", __func__, filename); fflush(stdout);}
41 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
42
43 /* Initiate output */
44 if(hdrfile!=NULL) hdrfile[0]=(char)0;
45 if(imgfile!=NULL) imgfile[0]=(char)0;
46 if(siffile!=NULL) siffile[0]=(char)0;
47
48 /* Empty file name means not a NIfTI */
49 if(strnlen(filename, 2)<1) {
50 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FILENAME);
51 return(0);
52 }
53
54 /* Construct the base file name wo extensions */
55 char basefile[FILENAME_MAX]; strlcpy(basefile, filename, FILENAME_MAX);
56 // If file exists it has extensions
57 if(fileExist(basefile)) niftiBasename(basefile);
58 if(verbose>1) printf(" basefile := %s\n", basefile);
59
60 /* Combined header and image file exists? */
61 int combined=0;
62 char temp[FILENAME_MAX+10], localhdrfile[FILENAME_MAX];
63 localhdrfile[0]=(char)0;
64 strcpy(temp, basefile); strcat(temp, ".nii");
65 if(fileExist(temp)) {
66 if(verbose>1) printf(" %s exists.\n", temp);
67 /* Preserve header and image file names */
68 strcpy(localhdrfile, temp);
69 if(hdrfile!=NULL) strlcpy(hdrfile, temp, FILENAME_MAX);
70 if(imgfile!=NULL) strlcpy(imgfile, temp, FILENAME_MAX);
71 combined=1;
72 } else {
73 if(verbose>1) printf(" %s does not exist.\n", temp);
74 /* Not combined file, therefore check that header file exists */
75 strcpy(temp, basefile); strcat(temp, ".hdr");
76 if(!fileExist(temp)) {
77 strcpy(temp, basefile); strcat(temp, ".img.hdr");
78 if(!fileExist(temp)) {
79 if(verbose>1) printf(" hdr file not found.\n");
80 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_MISSING_HEADER);
81 return(0);
82 }
83 }
84 /* Preserve file name of the header */
85 strlcpy(localhdrfile, temp, FILENAME_MAX);
86 if(hdrfile!=NULL) strlcpy(hdrfile, temp, FILENAME_MAX);
87 if(verbose>1) printf(" %s is found.\n", localhdrfile);
88 /* Not combined file, therefore check that image file exists */
89 strcpy(temp, basefile); strcat(temp, ".img");
90 if(!fileExist(temp)) {
91 if(verbose>1) printf(" %s not found.\n", temp);
92 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_FILE);
93 return(0);
94 }
95 /* Preserve image filename */
96 if(imgfile!=NULL) strlcpy(imgfile, temp, FILENAME_MAX);
97 if(verbose>1) printf(" %s is found.\n", temp);
98 }
99 if(verbose>1) {printf(" combined := %d\n", combined); fflush(stdout);}
100
101 /* Read header to check that this indeed is NIfTI, and which version of it */
102 {
103 NIFTI_DSR *dsr, local_dsr; if(header==NULL) dsr=&local_dsr; else dsr=header;
104 int ret=niftiReadHeader(localhdrfile, dsr, verbose-2);
105 if(ret!=TPCERROR_OK) {
106 if(verbose>1) {
107 printf(" %s was not identified as NIfTI header file.\n", localhdrfile); fflush(stdout);}
108 statusSet(status, __func__, __FILE__, __LINE__, ret);
109 return(0);
110 }
111 if(verbose>1) {printf(" %s is identified as NIfTI.\n", localhdrfile); fflush(stdout);}
112 }
113
114 /* SIF exists? */
115 strcpy(temp, basefile); strcat(temp, ".sif");
116 if(verbose>3) printf(" checking if %s exists\n", temp);
117 if(!fileExist(temp)) {
118 strcpy(temp, basefile); strcat(temp, ".img.sif");
119 if(verbose>3) printf(" checking if %s exists\n", temp);
120 if(!fileExist(temp)) {
121 strcpy(temp, basefile); strcat(temp, ".nii.sif");
122 if(verbose>3) printf(" checking if %s exists\n", temp);
123 if(!fileExist(temp)) {
124 if(verbose>0) printf(" SIF not found or accessible.\n");
125 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
126 return(1); // but otherwise ok NIfTI
127 }
128 }
129 }
130 /* Preserve SIF filename */
131 if(siffile!=NULL) strcpy(siffile, temp);
132 if(verbose>1) {printf(" %s is found.\n", temp); fflush(stdout);}
133
134 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
135 return(1);
136}
137/*****************************************************************************/
138
139/*****************************************************************************/
148 const char *filename,
150 NIFTI_DSR *dsr,
152 int verbose
153) {
154 if(verbose>0) {printf("%s(%s, ...)\n", __func__, filename); fflush(stdout);}
155
156 /* Check arguments */
157 if(strnlen(filename, 2)<1) return(TPCERROR_INVALID_FILENAME);
158 if(dsr==NULL) return(TPCERROR_FAIL);
159
160 /* Is current platform little endian (1) or not (0) ? */
161 int little=endianLittle();
162 if(verbose>2) {
163 if(little) printf("little endian platform\n"); else printf("big endian platform\n");
164 }
165
166 /* Open file */
167 FILE *fp=fopen(filename, "rb"); if(fp==NULL) return(TPCERROR_CANNOT_OPEN);
168
169 /* Try to read the size of header, which should be stored in the beginning as
170 4-byte integer in both NIfTI and Analyze header files.
171 Determine from the size if byte swapping is needed. */
172 int hdrSize=0;
173 int same_order=1;
174 {
175 char buf[4];
176 if(fread(buf, 4, 1, fp)<1) {fclose(fp); return(TPCERROR_CANNOT_READ);}
177 memcpy(&hdrSize, buf, 4);
178 if(hdrSize!=NIFTI1_HEADER_SIZE && hdrSize!=NIFTI2_HEADER_SIZE) {
179 swawbip(&hdrSize, 4);
180 same_order=0;
181 }
182 if(verbose>1) {printf(" sizeof_hdr := %d\n", hdrSize); fflush(stdout);}
183 if(hdrSize==NIFTI2_HEADER_SIZE) {
184 if(verbose>1) {printf(" NIfTI-2 header size.\n"); fflush(stdout);}
185 } else if(hdrSize==NIFTI1_HEADER_SIZE) {
186 if(verbose>1) {printf(" NIfTI-1 or Analyze header size.\n"); fflush(stdout);}
187 } else {
188 if(verbose>1) {printf(" invalid Nifti sizeof_hdr\n"); fflush(stdout);}
189 fclose(fp); return(TPCERROR_INVALID_FORMAT);
190 }
191 }
192 if(same_order==1) {
193 dsr->byte_order=little;
194 } else {
195 // opposite order in file and in current machine
196 if(little==1) dsr->byte_order=0; else dsr->byte_order=1;
197 }
198 if(verbose>1) {
199 printf(" Nifti byte order := ");
200 if(dsr->byte_order==0) printf("big\n"); else printf("little\n");
201 if(same_order==1) printf(" No need for byte swapping\n");
202 else printf(" Byte swapping needed.\n");
203 fflush(stdout);
204 }
205
206
207 /* Read file into NIfTI header structure */
208 if(verbose>1) {printf(" reading header as binary data\n"); fflush(stdout);}
209 unsigned char buf[hdrSize];
210 rewind(fp);
211 if(fread(buf, hdrSize, 1, fp)<1) {fclose(fp); return(TPCERROR_CANNOT_READ);}
212
213 /* Read NIfTI-1 extender */
214 int extender=0;
215 for(int n=0; n<4; n++) dsr->e.extension[n]=(char)0;
216 if(fread(dsr->e.extension, 4, 1, fp)<1) {
217 if(verbose>1) printf(" Nifti header extender not found in %s\n", filename);
218 extender=0;
219 } else {
220 if(verbose>2) printf(" Nifti header extender was found in %s\n", filename);
221 extender=1;
222 }
223 /* Close file */
224 fclose(fp);
225
226 /* Get the Nifti Magic number */
227 if(hdrSize==NIFTI1_HEADER_SIZE) {
228 if(buf[344]==(char)0 || buf[344]=='0') {
229 if(verbose>0) {printf(" probably Analyze header.\n"); fflush(stdout);}
230 return(TPCERROR_UNSUPPORTED);
231 }
232 memcpy(dsr->h1.magic, buf+344, 4);
233 dsr->h1.magic[3]=(char)0; // make sure that string ends as intended
234 if(strcasecmp(dsr->h1.magic, "ni1")==0) {
235 if(verbose>1) {printf(" separate hdr and img files.\n"); fflush(stdout);}
236 } else if(strcasecmp(dsr->h1.magic, "n+1")==0) {
237 if(verbose>1) {printf(" combined hdr and img data.\n"); fflush(stdout);}
238 } else {
239 if(verbose>1) {printf(" Nifti magic number not found"); fflush(stdout);}
240 if(verbose>2) {
241 printf("magic := {%d, %d, %d, %d}\n", dsr->h1.magic[0], dsr->h1.magic[1],
242 dsr->h1.magic[2], dsr->h1.magic[3]);
243 }
245 }
246 dsr->n=1;
247 if(verbose>1) printf(" Nifti Magic number := %s\n", dsr->h1.magic);
248 /* Check that 4-byte header extender was found, if magic number is n+1 */
249 if(strcasecmp(dsr->h1.magic, "n+1")==0 && extender==0) {
250 if(verbose>1) printf(" Nifti n+1 header extender not found\n");
252 }
253 } else {
254 memcpy(dsr->h2.magic, buf+4, 8);
255 if(strcasecmp(dsr->h2.magic, "ni2")==0) {
256 if(verbose>1) {printf(" separate hdr and img files.\n"); fflush(stdout);}
257 } else if(strcasecmp(dsr->h2.magic, "n+2")==0) {
258 if(verbose>1) {printf(" combined hdr and img data.\n"); fflush(stdout);}
259 } else {
260 if(verbose>1) {printf(" Nifti magic number not found"); fflush(stdout);}
262 }
263 /* Check also the next four characters of NIfTI-2 signature */
264 if(dsr->h2.magic[4]!='\r' || dsr->h2.magic[5]!='\n' || dsr->h2.magic[6]!=32 || dsr->h2.magic[7]!='\n') {
265 if(verbose>1) {printf(" Nifti magic signature not found"); fflush(stdout);}
267 }
268 dsr->n=2;
269 if(verbose>1) printf(" Nifti Magic number := %s\n", dsr->h2.magic);
270 /* Check that 4-byte header extender was found, if magic number is n+1 */
271 if(strcasecmp(dsr->h2.magic, "n+3")==0 && extender==0) {
272 if(verbose>1) printf(" Nifti n+3 header extender not found\n");
274 }
275 }
276
277
278 /*
279 * Fill the header structure fields
280 */
281 if(dsr->n==1) { // NIfTI-1
282 dsr->h1.sizeof_hdr=hdrSize; // Bytes already swapped when necessary
283 memcpy(&dsr->h1.data_type, buf+4, 10);
284 memcpy(&dsr->h1.db_name, buf+14, 18);
285 if(!same_order) swawbip(buf+32, 4);
286 memcpy(&dsr->h1.extents, buf+32, 4);
287 if(!same_order) swabip(buf+36, 2);
288 memcpy(&dsr->h1.session_error, buf+36, 2);
289 memcpy(&dsr->h1.regular, buf+38, 1);
290 memcpy(&dsr->h1.dim_info, buf+39, 1);
291
292 /* dim */
293 if(!same_order) swabip(buf+40, 16);
294 memcpy(dsr->h1.dim, buf+40, 16);
295 /* intent parameters */
296 if(!same_order) swawbip(buf+56, 4);
297 memcpy(&dsr->h1.intent_p1, buf+56, 4);
298 if(!same_order) swawbip(buf+60, 4);
299 memcpy(&dsr->h1.intent_p2, buf+60, 4);
300 if(!same_order) swawbip(buf+64, 4);
301 memcpy(&dsr->h1.intent_p3, buf+64, 4);
302 if(!same_order) swabip(buf+68, 2);
303 memcpy(&dsr->h1.intent_code, buf+68, 2);
304
305 /* */
306 if(!same_order) swabip(buf+70, 2);
307 memcpy(&dsr->h1.datatype, buf+70, 2);
308 if(!same_order) swabip(buf+72, 2);
309 memcpy(&dsr->h1.bitpix, buf+72, 2);
310 if(!same_order) swabip(buf+74, 2);
311 memcpy(&dsr->h1.slice_start, buf+74, 2);
312 if(!same_order) swawbip(buf+76, 32);
313 memcpy(dsr->h1.pixdim, buf+76, 32);
314 if(!same_order) swawbip(buf+108, 4);
315 memcpy(&dsr->h1.vox_offset, buf+108, 4); //printf("dsr->h1.vox_offset := %g\n", dsr->h1.vox_offset);
316 if(!same_order) swawbip(buf+112, 4);
317 memcpy(&dsr->h1.scl_slope, buf+112, 4);
318 if(!same_order) swawbip(buf+116, 4);
319 memcpy(&dsr->h1.scl_inter, buf+116, 4);
320 if(!same_order) swabip(buf+120, 2);
321 memcpy(&dsr->h1.slice_end, buf+120, 2);
322 memcpy(&dsr->h1.slice_code, buf+122, 1);
323 memcpy(&dsr->h1.xyzt_units, buf+123, 1);
324 if(!same_order) swawbip(buf+124, 4);
325 memcpy(&dsr->h1.cal_max, buf+124, 4);
326 if(!same_order) swawbip(buf+128, 4);
327 memcpy(&dsr->h1.cal_min, buf+128, 4);
328 if(!same_order) swawbip(buf+132, 4);
329 memcpy(&dsr->h1.slice_duration,buf+132,4);
330 if(!same_order) swawbip(buf+136, 4);
331 memcpy(&dsr->h1.toffset, buf+136, 4);
332 if(!same_order) swawbip(buf+140, 4);
333 memcpy(&dsr->h1.glmax, buf+140, 4);
334 if(!same_order) swawbip(buf+144, 4);
335 memcpy(&dsr->h1.glmin, buf+144, 4);
336
337 /* study description */
338 memcpy(&dsr->h1.descrip, buf+148, 80);
339 /* Auxiliary filename */
340 memcpy(&dsr->h1.aux_file, buf+228, 24);
341
342 /* Transformation parameters */
343 if(!same_order) swabip(buf+252, 2);
344 memcpy(&dsr->h1.qform_code, buf+252, 2);
345 if(!same_order) swabip(buf+254, 2);
346 memcpy(&dsr->h1.sform_code, buf+254, 2);
347 if(!same_order) swawbip(buf+256, 4);
348 memcpy(&dsr->h1.quatern_b, buf+256, 4);
349 if(!same_order) swawbip(buf+260, 4);
350 memcpy(&dsr->h1.quatern_c, buf+260, 4);
351 if(!same_order) swawbip(buf+264, 4);
352 memcpy(&dsr->h1.quatern_d, buf+264, 4);
353 if(!same_order) swawbip(buf+268, 4);
354 memcpy(&dsr->h1.qoffset_x, buf+268, 4);
355 if(!same_order) swawbip(buf+272, 4);
356 memcpy(&dsr->h1.qoffset_y, buf+272, 4);
357 if(!same_order) swawbip(buf+276, 4);
358 memcpy(&dsr->h1.qoffset_z, buf+276, 4);
359 if(!same_order) swawbip(buf+280, 16);
360 memcpy(dsr->h1.srow_x, buf+280, 16);
361 if(!same_order) swawbip(buf+296, 16);
362 memcpy(dsr->h1.srow_y, buf+296, 16);
363 if(!same_order) swawbip(buf+312, 16);
364 memcpy(dsr->h1.srow_z, buf+312, 16);
365
366 memcpy(&dsr->h1.intent_name, buf+328, 16);
367
368 } else { // NIfTI-2
369
370 dsr->h2.sizeof_hdr=hdrSize; // Bytes already swapped when necessary
371 // magic signature already set
372 if(!same_order) swap16ip(buf+12, 1);
373 memcpy(&dsr->h2.datatype, buf+12, 2);
374 if(!same_order) swap16ip(buf+14, 1);
375 memcpy(&dsr->h2.bitpix, buf+14, 2);
376 if(!same_order) swap64ip(buf+16, 8);
377 memcpy(dsr->h2.dim, buf+16, 64);
378 if(!same_order) swap64ip(buf+80, 3); /* intent parameters */
379 memcpy(&dsr->h2.intent_p1, buf+80, 8);
380 memcpy(&dsr->h2.intent_p2, buf+88, 8);
381 memcpy(&dsr->h2.intent_p3, buf+96, 8);
382 if(!same_order) swap64ip(buf+104, 8); /* pixdim array */
383 memcpy(dsr->h2.pixdim, buf+104, 64);
384 if(!same_order) swap64ip(buf+168, 1);
385 memcpy(&dsr->h2.vox_offset, buf+168, 8);
386 if(!same_order) swap64ip(buf+176, 6);
387 memcpy(&dsr->h2.scl_slope, buf+176, 8);
388 memcpy(&dsr->h2.scl_inter, buf+184, 8);
389 memcpy(&dsr->h2.cal_max, buf+192, 8);
390 memcpy(&dsr->h2.cal_min, buf+200, 8);
391 memcpy(&dsr->h2.slice_duration, buf+208, 8);
392 memcpy(&dsr->h2.toffset, buf+216, 8);
393 if(!same_order) swap64ip(buf+224, 2);
394 memcpy(&dsr->h2.slice_start, buf+224, 8);
395 memcpy(&dsr->h2.slice_end, buf+232, 8);
396 memcpy(&dsr->h2.descrip, buf+240, 80); /* study description */
397 memcpy(&dsr->h2.aux_file, buf+320, 24);
398 if(!same_order) swap32ip(buf+344, 2); /* quaternion fields */
399 memcpy(&dsr->h2.qform_code, buf+344, 4);
400 memcpy(&dsr->h2.sform_code, buf+348, 4);
401 if(!same_order) swap64ip(buf+352, 18);
402 memcpy(&dsr->h2.quatern_b, buf+252, 8);
403 memcpy(&dsr->h2.quatern_c, buf+260, 8);
404 memcpy(&dsr->h2.quatern_d, buf+268, 8);
405 memcpy(&dsr->h2.qoffset_x, buf+276, 8);
406 memcpy(&dsr->h2.qoffset_y, buf+284, 8);
407 memcpy(&dsr->h2.qoffset_z, buf+292, 8);
408 memcpy(dsr->h2.srow_x, buf+400, 8);
409 memcpy(dsr->h2.srow_x+1, buf+408, 8);
410 memcpy(dsr->h2.srow_x+2, buf+416, 8);
411 memcpy(dsr->h2.srow_x+3, buf+424, 8);
412 memcpy(dsr->h2.srow_y, buf+432, 8);
413 memcpy(dsr->h2.srow_y+1, buf+440, 8);
414 memcpy(dsr->h2.srow_y+2, buf+448, 8);
415 memcpy(dsr->h2.srow_y+3, buf+456, 8);
416 memcpy(dsr->h2.srow_z, buf+464, 8);
417 memcpy(dsr->h2.srow_z+1, buf+472, 8);
418 memcpy(dsr->h2.srow_z+2, buf+480, 8);
419 memcpy(dsr->h2.srow_z+3, buf+488, 8);
420 if(!same_order) swap32ip(buf+496, 1);
421 memcpy(&dsr->h2.slice_code, buf+496, 4);
422 if(!same_order) swap32ip(buf+500, 1);
423 memcpy(&dsr->h2.xyzt_units, buf+500, 4);
424 if(!same_order) swap32ip(buf+504, 1); /* intent */
425 memcpy(&dsr->h2.intent_code, buf+508, 4);
426 memcpy(&dsr->h2.intent_name, buf+508, 16);
427 memcpy(&dsr->h2.dim_info, buf+524, 1);
428 memcpy(&dsr->h2.unused_str, buf+525, 15);
429 }
430
431 if(verbose>1) {printf(" complete Nifti header was read.\n"); fflush(stdout);}
432
433
434 return(TPCERROR_OK);
435}
436/*****************************************************************************/
437
438/*****************************************************************************/
447 const char *filename,
449 NIFTI_DSR *dsr,
451 int verbose
452) {
453 if(verbose>0) {printf("%s(%s, dsr, %d)\n", __func__, filename, verbose); fflush(stdout);}
454
455 /* Check arguments */
456 if(strnlen(filename, 2)<1) return(TPCERROR_INVALID_FILENAME);
457 if(dsr==NULL) return(TPCERROR_FAIL);
458
459 /* Check magic number */
460 if(dsr->n==1) {
461 if(strncmp(dsr->h1.magic, "ni1", 3)!=0 && strncmp(dsr->h1.magic, "n+1", 3)!=0)
463 } else if(dsr->n==2) {
464 if(strncmp(dsr->h2.magic, "ni2", 3)!=0 && strncmp(dsr->h2.magic, "n+2", 3)!=0)
466 } else
467 return(TPCERROR_FAIL);
468
469 /* Is current platform little endian (1) or not (0) ? */
470 int little=endianLittle();
471 if(verbose>2) {
472 if(little) printf("little endian platform\n"); else printf("big endian platform\n");
473 }
474 int same_order=0;
475 if(little==dsr->byte_order) same_order=1;
476
477
478 /* Set up buffer with contents of all zeroes */
479 unsigned int hdrSize=NIFTI1_HEADER_SIZE; if(dsr->n==2) hdrSize=NIFTI2_HEADER_SIZE;
480 unsigned char buf[hdrSize];
481 memset(buf, 0, sizeof(hdrSize));
482
483 /* Copy header contents into the buffer */
484 if(verbose>2) printf(" setting write buffer\n");
485 if(dsr->n==1) {
486 unsigned char *bptr=buf+0; memcpy(bptr, &dsr->h1.sizeof_hdr, 4); if(!same_order) swawbip(bptr, 4);
487 bptr=buf+4; memcpy(bptr, &dsr->h1.data_type, 10);
488 bptr=buf+14; memcpy(bptr, &dsr->h1.db_name, 18);
489 bptr=buf+32; memcpy(bptr, &dsr->h1.extents, 4); if(!same_order) swawbip(bptr, 4);
490 bptr=buf+36; memcpy(bptr, &dsr->h1.session_error, 2); if(!same_order) swabip(bptr, 2);
491 bptr=buf+38; memcpy(bptr, &dsr->h1.regular, 1);
492 bptr=buf+39; memcpy(bptr, &dsr->h1.dim_info, 1);
493
494 bptr=buf+40; memcpy(bptr, dsr->h1.dim, 16); if(!same_order) swabip(bptr, 16);
495 bptr=buf+56; memcpy(bptr, &dsr->h1.intent_p1, 4); if(!same_order) swawbip(bptr, 4);
496 bptr=buf+60; memcpy(bptr, &dsr->h1.intent_p2, 4); if(!same_order) swawbip(bptr, 4);
497 bptr=buf+64; memcpy(bptr, &dsr->h1.intent_p3, 4); if(!same_order) swawbip(bptr, 4);
498 bptr=buf+68; memcpy(bptr, &dsr->h1.intent_code, 2); if(!same_order) swabip(bptr, 2);
499 bptr=buf+70; memcpy(bptr, &dsr->h1.datatype, 2); if(!same_order) swabip(bptr, 2);
500 bptr=buf+72; memcpy(bptr, &dsr->h1.bitpix, 2); if(!same_order) swabip(bptr, 2);
501 bptr=buf+74; memcpy(bptr, &dsr->h1.slice_start, 2); if(!same_order) swabip(bptr, 2);
502 bptr=buf+76; memcpy(bptr, dsr->h1.pixdim, 32); if(!same_order) swawbip(bptr, 32);
503 bptr=buf+108; memcpy(bptr, &dsr->h1.vox_offset, 4); if(!same_order) swawbip(bptr, 4);
504 bptr=buf+112; memcpy(bptr, &dsr->h1.scl_slope, 4); if(!same_order) swawbip(bptr, 4);
505 bptr=buf+116; memcpy(bptr, &dsr->h1.scl_inter, 4); if(!same_order) swawbip(bptr, 4);
506 bptr=buf+120; memcpy(bptr, &dsr->h1.slice_end, 2); if(!same_order) swabip(bptr, 2);
507 bptr=buf+122; memcpy(bptr, &dsr->h1.slice_code, 1);
508 bptr=buf+123; memcpy(bptr, &dsr->h1.xyzt_units, 1);
509 bptr=buf+124; memcpy(bptr, &dsr->h1.cal_max, 4); if(!same_order) swawbip(bptr, 4);
510 bptr=buf+128; memcpy(bptr, &dsr->h1.cal_min, 4); if(!same_order) swawbip(bptr, 4);
511 bptr=buf+132; memcpy(bptr, &dsr->h1.slice_duration, 4); if(!same_order) swawbip(bptr, 4);
512 bptr=buf+136; memcpy(bptr, &dsr->h1.toffset, 4); if(!same_order) swawbip(bptr, 4);
513 bptr=buf+140; memcpy(bptr, &dsr->h1.glmax, 4); if(!same_order) swawbip(bptr, 4);
514 bptr=buf+144; memcpy(bptr, &dsr->h1.glmin, 4); if(!same_order) swawbip(bptr, 4);
515
516 bptr=buf+148; memcpy(bptr, dsr->h1.descrip, 80);
517 bptr=buf+228; memcpy(bptr, dsr->h1.aux_file, 24);
518 bptr=buf+252; memcpy(bptr, &dsr->h1.qform_code, 2); if(!same_order) swabip(bptr, 2);
519 bptr=buf+254; memcpy(bptr, &dsr->h1.sform_code, 2); if(!same_order) swabip(bptr, 2);
520 bptr=buf+256; memcpy(bptr, &dsr->h1.quatern_b, 4); if(!same_order) swawbip(bptr, 4);
521 bptr=buf+260; memcpy(bptr, &dsr->h1.quatern_c, 4); if(!same_order) swawbip(bptr, 4);
522 bptr=buf+264; memcpy(bptr, &dsr->h1.quatern_d, 4); if(!same_order) swawbip(bptr, 4);
523 bptr=buf+268; memcpy(bptr, &dsr->h1.qoffset_x, 4); if(!same_order) swawbip(bptr, 4);
524 bptr=buf+272; memcpy(bptr, &dsr->h1.qoffset_y, 4); if(!same_order) swawbip(bptr, 4);
525 bptr=buf+276; memcpy(bptr, &dsr->h1.qoffset_z, 4); if(!same_order) swawbip(bptr, 4);
526 bptr=buf+280; memcpy(bptr, dsr->h1.srow_x, 16); if(!same_order) swawbip(bptr, 16);
527 bptr=buf+296; memcpy(bptr, dsr->h1.srow_y, 16); if(!same_order) swawbip(bptr, 16);
528 bptr=buf+312; memcpy(bptr, dsr->h1.srow_z, 16); if(!same_order) swawbip(bptr, 16);
529 bptr=buf+328; memcpy(bptr, dsr->h1.intent_name, 16);
530 bptr=buf+344; memcpy(bptr, dsr->h1.magic, 4);
531
532 } else {
533
534 unsigned char *bptr=buf+0; memcpy(bptr, &dsr->h2.sizeof_hdr, 4); if(!same_order) swap32ip(bptr, 1);
535 bptr=buf+4; memcpy(bptr, &dsr->h2.magic, 8);
536 bptr=buf+12; memcpy(bptr, &dsr->h2.datatype, 2); if(!same_order) swap16ip(bptr, 1);
537 bptr=buf+14; memcpy(bptr, &dsr->h2.bitpix, 2); if(!same_order) swap16ip(bptr, 1);
538 bptr=buf+16; memcpy(bptr, &dsr->h2.dim, 64); if(!same_order) swap64ip(bptr, 8);
539 bptr=buf+80; memcpy(bptr, &dsr->h2.intent_p1, 8); if(!same_order) swap64ip(bptr, 1);
540 bptr=buf+88; memcpy(bptr, &dsr->h2.intent_p2, 8); if(!same_order) swap64ip(bptr, 1);
541 bptr=buf+96; memcpy(bptr, &dsr->h2.intent_p3, 8); if(!same_order) swap64ip(bptr, 1);
542 bptr=buf+104; memcpy(bptr, &dsr->h2.pixdim, 64); if(!same_order) swap64ip(bptr, 8);
543 bptr=buf+168; memcpy(bptr, &dsr->h2.vox_offset, 8); if(!same_order) swap64ip(bptr, 1);
544 bptr=buf+176; memcpy(bptr, &dsr->h2.scl_slope, 8); if(!same_order) swap64ip(bptr, 1);
545 bptr=buf+184; memcpy(bptr, &dsr->h2.scl_inter, 8); if(!same_order) swap64ip(bptr, 1);
546 bptr=buf+192; memcpy(bptr, &dsr->h2.cal_max, 8); if(!same_order) swap64ip(bptr, 1);
547 bptr=buf+200; memcpy(bptr, &dsr->h2.cal_min, 8); if(!same_order) swap64ip(bptr, 1);
548 bptr=buf+208; memcpy(bptr, &dsr->h2.slice_duration, 8); if(!same_order) swap64ip(bptr, 1);
549 bptr=buf+216; memcpy(bptr, &dsr->h2.toffset, 8); if(!same_order) swap64ip(bptr, 1);
550 bptr=buf+224; memcpy(bptr, &dsr->h2.slice_start, 8); if(!same_order) swap64ip(bptr, 1);
551 bptr=buf+232; memcpy(bptr, &dsr->h2.slice_end, 8); if(!same_order) swap64ip(bptr, 1);
552 bptr=buf+240; memcpy(bptr, dsr->h2.descrip, 80);
553 bptr=buf+320; memcpy(bptr, dsr->h2.aux_file, 24);
554 bptr=buf+344; memcpy(bptr, &dsr->h2.qform_code, 4); if(!same_order) swap32ip(bptr, 1);
555 bptr=buf+348; memcpy(bptr, &dsr->h2.sform_code, 4); if(!same_order) swap32ip(bptr, 1);
556 bptr=buf+352; memcpy(bptr, &dsr->h2.quatern_b, 8); if(!same_order) swap64ip(bptr, 1);
557 bptr=buf+360; memcpy(bptr, &dsr->h2.quatern_c, 8); if(!same_order) swap64ip(bptr, 1);
558 bptr=buf+368; memcpy(bptr, &dsr->h2.quatern_d, 8); if(!same_order) swap64ip(bptr, 1);
559 bptr=buf+376; memcpy(bptr, &dsr->h2.qoffset_x, 8); if(!same_order) swap64ip(bptr, 1);
560 bptr=buf+384; memcpy(bptr, &dsr->h2.qoffset_y, 8); if(!same_order) swap64ip(bptr, 1);
561 bptr=buf+392; memcpy(bptr, &dsr->h2.qoffset_z, 8); if(!same_order) swap64ip(bptr, 1);
562 bptr=buf+400; memcpy(bptr, dsr->h2.srow_x, 8); if(!same_order) swap64ip(bptr, 1);
563 bptr+=8; memcpy(bptr, dsr->h2.srow_x+1, 8); if(!same_order) swap64ip(bptr, 1);
564 bptr+=8; memcpy(bptr, dsr->h2.srow_x+2, 8); if(!same_order) swap64ip(bptr, 1);
565 bptr+=8; memcpy(bptr, dsr->h2.srow_x+3, 8); if(!same_order) swap64ip(bptr, 1);
566 bptr=buf+432; memcpy(bptr, dsr->h2.srow_y, 8); if(!same_order) swap64ip(bptr, 1);
567 bptr+=8; memcpy(bptr, dsr->h2.srow_y+1, 8); if(!same_order) swap64ip(bptr, 1);
568 bptr+=8; memcpy(bptr, dsr->h2.srow_y+2, 8); if(!same_order) swap64ip(bptr, 1);
569 bptr+=8; memcpy(bptr, dsr->h2.srow_y+3, 8); if(!same_order) swap64ip(bptr, 1);
570 bptr=buf+464; memcpy(bptr, dsr->h2.srow_z, 8); if(!same_order) swap64ip(bptr, 1);
571 bptr+=8; memcpy(bptr, dsr->h2.srow_z+1, 8); if(!same_order) swap64ip(bptr, 1);
572 bptr+=8; memcpy(bptr, dsr->h2.srow_z+2, 8); if(!same_order) swap64ip(bptr, 1);
573 bptr+=8; memcpy(bptr, dsr->h2.srow_z+3, 8); if(!same_order) swap64ip(bptr, 1);
574 bptr=buf+496; memcpy(bptr, &dsr->h2.slice_code, 4); if(!same_order) swap32ip(bptr, 1);
575 bptr=buf+500; memcpy(bptr, &dsr->h2.xyzt_units, 4); if(!same_order) swap32ip(bptr, 1);
576 bptr=buf+504; memcpy(bptr, &dsr->h2.intent_code, 4); if(!same_order) swap32ip(bptr, 1);
577 bptr=buf+508; memcpy(bptr, dsr->h2.intent_name, 16);
578 bptr=buf+524; memcpy(bptr, &dsr->h2.dim_info, 1);
579 bptr=buf+525; memcpy(bptr, dsr->h2.unused_str, 15);
580
581 }
582
583 /* Open file for write */
584 FILE *fp;
585 if(verbose>2) printf(" opening file for write in binary mode\n");
586 if(fileExist(filename) &&
587 (strncmp(dsr->h1.magic, "n+1", 3)==0 || strncmp(dsr->h1.magic, "n+2", 3)==0) ) {
588 /* Existing single file format NIfTI; just edit the header, do not touch the pixel data */
589 fp=fopen(filename, "r+b");
590 } else {
591 /* Otherwise just open for write, deleting any previous content */
592 fp=fopen(filename, "wb");
593 }
594 if(fp==NULL) return(TPCERROR_CANNOT_OPEN);
595
596 /* Write buffer into the file */
597 if(verbose>2) printf(" writing NIfTI header\n");
598 if(fwrite(buf, 1, hdrSize, fp) != hdrSize) {
599 fclose(fp); return(TPCERROR_CANNOT_WRITE);
600 }
601
602 /* Write extender */
603 if(verbose>2) printf(" writing NIfTI extender\n");
605 fclose(fp); return(TPCERROR_CANNOT_WRITE);
606 }
607
608 /* Close the file */
609 fclose(fp);
610
611 if(verbose>1) printf(" NIfTI header written.\n");
612 return(TPCERROR_OK);
613}
614/*****************************************************************************/
615
616/*****************************************************************************/
void swap32ip(void *buf, unsigned long long size)
Definition endian.c:210
void swap64ip(void *buf, unsigned long long size)
Definition endian.c:184
void swabip(void *buf, int size)
Definition endian.c:115
int endianLittle()
Definition endian.c:53
void swap16ip(void *buf, unsigned long long size)
Definition endian.c:234
void swawbip(void *buf, int size)
Definition endian.c:138
int fileExist(const char *filename)
Definition filexist.c:17
int niftiExists(const char *filename, char *hdrfile, char *imgfile, char *siffile, NIFTI_DSR *header, TPCSTATUS *status)
Definition niftiio.c:17
int niftiWriteHeader(const char *filename, NIFTI_DSR *dsr, int verbose)
Definition niftiio.c:445
int niftiReadHeader(const char *filename, NIFTI_DSR *dsr, int verbose)
Definition niftiio.c:146
void niftiBasename(char *filename)
Definition niftiname.c:14
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
size_t strnlen(const char *s, size_t n)
Definition stringext.c:566
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
float quatern_d
Definition tpcnifti.h:289
float quatern_c
Definition tpcnifti.h:287
short int qform_code
Definition tpcnifti.h:281
char db_name[18]
Definition tpcnifti.h:220
float qoffset_x
Definition tpcnifti.h:291
short int slice_start
Definition tpcnifti.h:247
short int slice_end
Definition tpcnifti.h:257
float slice_duration
Definition tpcnifti.h:267
short int datatype
Definition tpcnifti.h:243
float intent_p2
Definition tpcnifti.h:237
char aux_file[24]
Definition tpcnifti.h:278
float intent_p1
Definition tpcnifti.h:235
float srow_z[4]
Definition tpcnifti.h:301
float srow_x[4]
Definition tpcnifti.h:297
char intent_name[16]
Definition tpcnifti.h:303
float intent_p3
Definition tpcnifti.h:239
short int bitpix
Definition tpcnifti.h:245
float pixdim[8]
Definition tpcnifti.h:249
char data_type[10]
Definition tpcnifti.h:218
short int sform_code
Definition tpcnifti.h:283
float vox_offset
Definition tpcnifti.h:251
float srow_y[4]
Definition tpcnifti.h:299
float qoffset_y
Definition tpcnifti.h:293
char descrip[80]
Definition tpcnifti.h:276
char magic[4]
Definition tpcnifti.h:306
float scl_inter
Definition tpcnifti.h:255
float qoffset_z
Definition tpcnifti.h:295
short int dim[8]
Definition tpcnifti.h:233
short int intent_code
Definition tpcnifti.h:241
float quatern_b
Definition tpcnifti.h:285
float scl_slope
Definition tpcnifti.h:253
short int session_error
Definition tpcnifti.h:224
double srow_x[4]
Definition tpcnifti.h:372
int64_t vox_offset
Definition tpcnifti.h:333
char aux_file[24]
Definition tpcnifti.h:353
int16_t datatype
Definition tpcnifti.h:317
char magic[8]
Definition tpcnifti.h:315
double slice_duration
Definition tpcnifti.h:343
int64_t dim[8]
Definition tpcnifti.h:323
double cal_min
Definition tpcnifti.h:341
double pixdim[8]
Definition tpcnifti.h:331
double intent_p2
Definition tpcnifti.h:327
int64_t slice_start
Definition tpcnifti.h:347
double qoffset_y
Definition tpcnifti.h:368
double intent_p3
Definition tpcnifti.h:329
int64_t slice_end
Definition tpcnifti.h:349
double srow_y[4]
Definition tpcnifti.h:374
double scl_inter
Definition tpcnifti.h:337
char unused_str[15]
Definition tpcnifti.h:388
double scl_slope
Definition tpcnifti.h:335
double intent_p1
Definition tpcnifti.h:325
double quatern_d
Definition tpcnifti.h:364
double qoffset_z
Definition tpcnifti.h:370
double qoffset_x
Definition tpcnifti.h:366
double toffset
Definition tpcnifti.h:345
char descrip[80]
Definition tpcnifti.h:351
double quatern_c
Definition tpcnifti.h:362
int16_t bitpix
Definition tpcnifti.h:319
double cal_max
Definition tpcnifti.h:339
double srow_z[4]
Definition tpcnifti.h:376
double quatern_b
Definition tpcnifti.h:360
char intent_name[16]
Definition tpcnifti.h:384
NIFTI_2_HEADER h2
Definition tpcnifti.h:406
NIFTI_EXTENDER e
Definition tpcnifti.h:408
NIFTI_1_HEADER h1
Definition tpcnifti.h:404
int byte_order
Definition tpcnifti.h:412
char extension[4]
Definition tpcnifti.h:398
int verbose
Verbose level, used by statusPrint() etc.
@ TPCERROR_NO_FILE
File does not exist.
@ TPCERROR_FAIL
General error.
@ TPCERROR_INVALID_FORMAT
Invalid file format.
@ TPCERROR_CANNOT_OPEN
Cannot open file.
@ TPCERROR_UNSUPPORTED
Unsupported file type.
@ TPCERROR_OK
No error.
@ TPCERROR_INVALID_FILENAME
Invalid file name.
@ TPCERROR_MISSING_HEADER
Missing header.
@ TPCERROR_CANNOT_READ
Cannot read file.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
Header file for libtpcnifti.
#define NIFTI1_HEADER_EXTENDER_SIZE
Definition tpcnifti.h:35
#define NIFTI1_HEADER_SIZE
Definition tpcnifti.h:33
#define NIFTI2_HEADER_SIZE
Definition tpcnifti.h:37