TPCCLIB
Loading...
Searching...
No Matches
nifti.c
Go to the documentation of this file.
1
15/******************************************************************************/
16#include "libtpcimgio.h"
17/******************************************************************************/
18
19/*****************************************************************************/
25 char *fname
26) {
27 char *cptr;
28 cptr=strrchr(fname, '.'); if(cptr==NULL) return;
29 if(strcasecmp(cptr, ".")==0 || strcasecmp(cptr, ".img")==0 ||
30 strcasecmp(cptr, ".hdr")==0 || strcasecmp(cptr, ".sif")==0 ||
31 strcasecmp(cptr, ".nii")==0)
32 *cptr=(char)0;
33 /* Remove also double extensions, e.g. from data.img.hdr */
34 cptr=strrchr(fname, '.'); if(cptr==NULL) return;
35 if(strcasecmp(cptr, ".img")==0 || strcasecmp(cptr, ".nii")==0) *cptr=(char)0;
36}
37/*****************************************************************************/
38
39/*****************************************************************************/
47 const char *filename,
52 char *hdrfile,
57 char *imgfile,
60 char *siffile,
62 int fileformat
63) {
64 int n;
65 char basename[FILENAME_MAX];
66
67 if(hdrfile!=NULL) strcpy(hdrfile, "");
68 if(imgfile!=NULL) strcpy(imgfile, "");
69 if(siffile!=NULL) strcpy(siffile, "");
70 n=strlen(filename); if(n<1 || n>=FILENAME_MAX) {return(1);}
71 strlcpy(basename, filename, FILENAME_MAX);
73
74 /* Create database filenames */
75 if(fileformat==IMG_NIFTI_1D) {
76 if(hdrfile!=NULL) snprintf(hdrfile, FILENAME_MAX, "%s.hdr", basename);
77 if(imgfile!=NULL) snprintf(imgfile, FILENAME_MAX, "%s.img", basename);
78 } else if(fileformat==IMG_NIFTI_1S) {
79 if(hdrfile!=NULL) snprintf(hdrfile, FILENAME_MAX, "%s.nii", basename);
80 if(imgfile!=NULL) snprintf(imgfile, FILENAME_MAX, "%s.nii", basename);
81 } else
82 return(2);
83 if(siffile!=NULL) snprintf(siffile, FILENAME_MAX, "%s.sif", basename);
84 return(0);
85}
86/*****************************************************************************/
87
88/*****************************************************************************/
102 const char *dbname,
105 int fileformat,
107 int verbose
108) {
109 if(verbose>0) {
110 printf("niftiRemove(%s, %d, ...)\n", dbname, fileformat);
111 fflush(stdout);
112 }
113
114 char imgfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
115 int errNr=0;
116 int ret=niftiCreateFNames(dbname, hdrfile, imgfile, siffile, fileformat);
117 if(ret==0 && fileformat==IMG_NIFTI_1D) { // dual format
118 if(access(hdrfile, 0)!=-1) {
119 if(verbose>1) {printf(" removing %s\n", hdrfile); fflush(stdout);}
120 if(remove(hdrfile)!=0) errNr++;
121 }
122 if(access(imgfile, 0)!=-1) {
123 if(verbose>1) {printf(" removing %s\n", imgfile); fflush(stdout);}
124 if(remove(imgfile)!=0) errNr++;
125 }
126 } else if(ret==0 && fileformat==IMG_NIFTI_1S) { // single format
127 if(access(imgfile, 0)!=-1) {
128 if(verbose>1) {printf(" removing %s\n", imgfile); fflush(stdout);}
129 if(remove(imgfile)!=0) errNr++;
130 }
131 } else { // dual and single formats
132 ret=niftiCreateFNames(dbname, hdrfile, imgfile, siffile, IMG_NIFTI_1D);
133 if(ret!=0) return 1;
134 if(access(hdrfile, 0)!=-1) {
135 if(verbose>1) {printf(" removing %s\n", hdrfile); fflush(stdout);}
136 if(remove(hdrfile)!=0) errNr++;
137 }
138 if(access(imgfile, 0)!=-1) {
139 if(verbose>1) {printf(" removing %s\n", imgfile); fflush(stdout);}
140 if(remove(imgfile)!=0) errNr++;
141 }
142
143 ret=niftiCreateFNames(dbname, hdrfile, imgfile, siffile, IMG_NIFTI_1S);
144 if(ret!=0) return 1;
145 if(access(imgfile, 0)!=-1) {
146 if(verbose>1) {printf(" removing %s\n", imgfile); fflush(stdout);}
147 if(remove(imgfile)!=0) errNr++;
148 }
149 }
150 return errNr;
151}
152/*****************************************************************************/
153
154/*****************************************************************************/
163 const char *filename,
168 char *hdrfile,
173 char *imgfile,
177 char *siffile,
179 NIFTI_DSR *header,
181 int verbose,
184 char *status
185) {
186 char basefile[FILENAME_MAX], temp[FILENAME_MAX], localhdrfile[FILENAME_MAX];
187 NIFTI_DSR *dsr, local_dsr;
188 int ret, combined=0;
189
190 if(filename==NULL || strlen(filename)==0) return(0);
191 if(verbose>0) {printf("\nniftiExists(%s, ...)\n", filename); fflush(stdout);}
192 if(status!=NULL) strcpy(status, "OK");
193 if(header==NULL) dsr=&local_dsr; else dsr=header;
194
195 localhdrfile[0]=(char)0;
196
197 /* Construct the base file name wo extensions */
198 strlcpy(basefile, filename, FILENAME_MAX);
200 if(verbose>1) printf("\n basefile := %s\n", basefile);
201
202 /* Combined header and image file exists? */
203 strcpy(temp, basefile); strcat(temp, ".nii");
204 if(access(temp, 0) == -1) {
205 if(verbose>0) printf(" %s not found or accessible.\n", temp);
206 } else {
207 /* Preserve header and image filenames */
208 strcpy(localhdrfile, temp);
209 if(hdrfile!=NULL) strcpy(hdrfile, temp);
210 if(imgfile!=NULL) strcpy(imgfile, temp);
211 combined=1;
212 if(verbose>1) printf(" %s is accessible.\n", temp);
213 }
214
215 /* If not, then check if header file exists */
216 if(combined==0) {
217 strcpy(temp, basefile); strcat(temp, ".hdr");
218 if(access(temp, 0) == -1) {
219 strcpy(temp, basefile); strcat(temp, ".img.hdr");
220 if(access(temp, 0) == -1) {
221 if(verbose>0) printf(" hdr file not found or accessible.\n");
222 if(status!=NULL) strcpy(status, "file not accessible");
223 return(0);
224 }
225 }
226 /* Preserve header filename */
227 strcpy(localhdrfile, temp);
228 if(hdrfile!=NULL) strcpy(hdrfile, temp);
229 if(verbose>1) printf(" %s is accessible.\n", temp);
230 }
231
232 /* If not combined, then does image file exists? */
233 if(combined==0) {
234 strcpy(temp, basefile); strcat(temp, ".img");
235 if(access(temp, 0) == -1) {
236 if(verbose>0) printf(" %s not found or accessible.\n", temp);
237 if(status!=NULL) strcpy(status, "file not accessible");
238 return(0);
239 }
240 /* Preserve image filename */
241 if(imgfile!=NULL) strcpy(imgfile, temp);
242 if(verbose>1) printf(" %s is accessible.\n", temp);
243 }
244
245 /* Is this Nifti file? */
246 if((ret=niftiReadHeader(localhdrfile, dsr, verbose, temp))!=0) {
247 if(status!=NULL) strcpy(status, "file is not Nifti");
248 if(verbose>0) {
249 printf(" %s was not identified as Nifti header file (%d).\n", localhdrfile, ret);
250 printf(" %s\n", temp);
251 }
252 return(0);
253 }
254 if(verbose>1) printf(" %s is identified as Nifti.\n", localhdrfile);
255 if(verbose>10) niftiPrintHeader(dsr, stdout);
256
257 /* SIF exists? */
258 strcpy(temp, basefile); strcat(temp, ".sif");
259 if(verbose>3) printf(" checking if %s exists\n", temp);
260 if(access(temp, 0) == -1) {
261 strcpy(temp, basefile); strcat(temp, ".img.sif");
262 if(verbose>3) printf(" checking if %s exists\n", temp);
263 if(access(temp, 0) == -1) {
264 strcpy(temp, basefile); strcat(temp, ".nii.sif");
265 if(verbose>3) printf(" checking if %s exists\n", temp);
266 if(access(temp, 0) == -1) {
267 if(verbose>0) printf("\n SIF not found or accessible.\n");
268 if(siffile!=NULL) strcpy(siffile, "");
269 if(status!=NULL) {
270 if(combined) strcpy(status, "combined Nifti file is accessible");
271 else strcpy(status, "Nifti files are accessible");
272 }
273 return(1); // but otherwise ok
274 }
275 }
276 }
277 /* Preserve SIF filename */
278 if(siffile!=NULL) strcpy(siffile, temp);
279 if(verbose>1) printf(" %s is accessible.\n", temp);
280 if(status!=NULL) {
281 if(combined) strcpy(status, "combined Nifti file and SIF are accessible");
282 else strcpy(status, "Nifti files and SIF are accessible");
283 }
284 return(2);
285}
286/*****************************************************************************/
287
288/*****************************************************************************/
295 char *filename,
297 NIFTI_DSR *dsr,
299 int verbose,
302 char *status
303) {
304 FILE *fp;
305 int little; // 1 if current platform is little endian (x86), else 0
306 int same_order, extender=0;
307 unsigned char buf[NIFTI_HEADER_SIZE];
308 short int s;
309
310 /* Check arguments */
311 if(filename==NULL || strlen(filename)==0 || dsr==NULL) return(1);
312 if(verbose>0) {
313 printf("\nniftiReadHeader(%s, ...)\n", filename); fflush(stdout);}
314 if(status!=NULL) strcpy(status, "OK");
315 little=little_endian(); if(verbose>3) printf(" little := %d\n", little);
316
317 /* Open file */
318 fp=fopen(filename, "rb"); if(fp==NULL) {
319 if(status!=NULL) strcpy(status, "cannot open file");
320 if(verbose>0) fprintf(stderr, "Error: cannot open file %s\n", filename);
321 return(2);
322 }
323
324 /* Read Nifti header */
325 if(fread(buf, NIFTI_HEADER_SIZE, 1, fp)<1) {
326 if(status!=NULL) strcpy(status, "complete Nifti header not found");
327 if(verbose>0)
328 fprintf(stderr, "Error: invalid Nifti header file %s\n", filename);
329 return(3);
330 }
331 /* Read nifti1 extender */
332 for(int n=0; n<4; n++) dsr->e.extension[n]=(char)0;
333 if(fread(dsr->e.extension, 4, 1, fp)<1) {
334 if(status!=NULL) strcpy(status, "complete Nifti header not found");
335 if(verbose>1)
336 fprintf(stdout, "Nifti header extender not found in %s\n", filename);
337 extender=0;
338 } else {
339 extender=1;
340 }
341 /* Close file */
342 fclose(fp);
343
344 /* Read Nifti Magic number */
345 memcpy(dsr->h.magic, buf+344, 4);
346 if(strcasecmp(dsr->h.magic, "ni1")==0) {
347 if(verbose>1) {printf(" separate hdr and img files.\n"); fflush(stdout);}
348 } else if(strcasecmp(dsr->h.magic, "n+1")==0) {
349 if(verbose>1) printf(" combined hdr and img data.\n");
350 } else {
351 if(status!=NULL) strcpy(status, "Nifti magic number not found");
352 if(verbose>0) {
353 fprintf(stderr, "Error: not a Nifti header file %s\n", filename);
354 fflush(stderr);
355 }
356 if(verbose>2) {
357 printf("magic := {%d, %d, %d, %d}\n", dsr->h.magic[0], dsr->h.magic[1],
358 dsr->h.magic[2], dsr->h.magic[3]);
359 }
360 return(4);
361 }
362 if(verbose>1) printf(" Nifti Magic number := %s\n", dsr->h.magic);
363 /* Check that 4-byte header extender was found, if magic number is n+1 */
364 if(strcasecmp(dsr->h.magic, "n+1")==0 && extender==0) {
365 if(status!=NULL) strcpy(status, "Nifti header extender not found");
366 if(verbose>0) {
367 fprintf(stderr, "Error: not valid Nifti n+1 header file %s\n", filename);
368 fflush(stderr);
369 }
370 return(5);
371 }
372
373 /* Determine from dim[0] if file is big or little endian */
374 memcpy(&s, buf+40, 2); if(verbose>10) printf(" s := %d\n", s);
375 if(s>0 && s<8) { // same order in file and current machine
376 dsr->byte_order=little;
377 same_order=1;
378 } else {
379 swabip(&s, 2); if(verbose>10) printf(" s := %d\n", s);
380 if(s>0 && s<8) { // opposite order in file and in current machine
381 if(little==1) dsr->byte_order=0; else dsr->byte_order=1;
382 same_order=0;
383 } else {
384 if(status!=NULL) strcpy(status, "invalid Nifti byte order");
385 if(verbose>0)
386 fprintf(stderr, "Error: not a valid Nifti header file %s\n", filename);
387 return(6);
388 }
389 }
390 if(verbose>1) printf(" Nifti byte order := %d\n", dsr->byte_order);
391
392 /* Size of header */
393 {
394 int n=0;
395 memcpy(&n, buf+0, 4); if(!same_order) swawbip(&n, 4);
396 if(n!=348) {
397 if(status!=NULL) strcpy(status, "invalid Nifti sizeof_hdr");
398 if(verbose>0)
399 fprintf(stderr, "Error: not a valid Nifti header file %s\n", filename);
400 return(7);
401 }
402 dsr->h.sizeof_hdr=n;
403 }
404
405 /* */
406 memcpy(&dsr->h.data_type, buf+4, 10);
407 memcpy(&dsr->h.db_name, buf+14, 18);
408 if(!same_order) swawbip(buf+32, 4);
409 memcpy(&dsr->h.extents, buf+32, 4);
410 if(!same_order) swabip(buf+36, 2);
411 memcpy(&dsr->h.session_error, buf+36, 2);
412 memcpy(&dsr->h.regular, buf+38, 1);
413 memcpy(&dsr->h.dim_info, buf+39, 1);
414
415 /* dim */
416 if(!same_order) swabip(buf+40, 16);
417 memcpy(dsr->h.dim, buf+40, 16);
418 /* intent parameters */
419 if(!same_order) swawbip(buf+56, 4);
420 memcpy(&dsr->h.intent_p1, buf+56, 4);
421 if(!same_order) swawbip(buf+60, 4);
422 memcpy(&dsr->h.intent_p2, buf+60, 4);
423 if(!same_order) swawbip(buf+64, 4);
424 memcpy(&dsr->h.intent_p3, buf+64, 4);
425 if(!same_order) swabip(buf+68, 2);
426 memcpy(&dsr->h.intent_code, buf+68, 2);
427
428 /* */
429 if(!same_order) swabip(buf+70, 2);
430 memcpy(&dsr->h.datatype, buf+70, 2);
431 if(!same_order) swabip(buf+72, 2);
432 memcpy(&dsr->h.bitpix, buf+72, 2);
433 if(!same_order) swabip(buf+74, 2);
434 memcpy(&dsr->h.slice_start, buf+74, 2);
435 if(!same_order) swawbip(buf+76, 32);
436 memcpy(dsr->h.pixdim, buf+76, 32);
437 if(!same_order) swawbip(buf+108, 4);
438 memcpy(&dsr->h.vox_offset, buf+108, 4);
439 if(!same_order) swawbip(buf+112, 4);
440 memcpy(&dsr->h.scl_slope, buf+112, 4);
441 if(!same_order) swawbip(buf+116, 4);
442 memcpy(&dsr->h.scl_inter, buf+116, 4);
443 if(!same_order) swabip(buf+120, 2);
444 memcpy(&dsr->h.slice_end, buf+120, 2);
445 memcpy(&dsr->h.slice_code, buf+122, 1);
446 memcpy(&dsr->h.xyzt_units, buf+123, 1);
447 if(!same_order) swawbip(buf+124, 4);
448 memcpy(&dsr->h.cal_max, buf+124, 4);
449 if(!same_order) swawbip(buf+128, 4);
450 memcpy(&dsr->h.cal_min, buf+128, 4);
451 if(!same_order) swawbip(buf+132, 4);
452 memcpy(&dsr->h.slice_duration,buf+132,4);
453 if(!same_order) swawbip(buf+136, 4);
454 memcpy(&dsr->h.toffset, buf+136, 4);
455 if(!same_order) swawbip(buf+140, 4);
456 memcpy(&dsr->h.glmax, buf+140, 4);
457 if(!same_order) swawbip(buf+144, 4);
458 memcpy(&dsr->h.glmin, buf+144, 4);
459
460 /* study description */
461 memcpy(&dsr->h.descrip, buf+148, 80);
462 /* Auxiliary filename */
463 memcpy(&dsr->h.aux_file, buf+228, 24);
464
465 /* Transformation parameters */
466 if(!same_order) swabip(buf+252, 2);
467 memcpy(&dsr->h.qform_code, buf+252, 2);
468 if(!same_order) swabip(buf+254, 2);
469 memcpy(&dsr->h.sform_code, buf+254, 2);
470 if(!same_order) swawbip(buf+256, 4);
471 memcpy(&dsr->h.quatern_b, buf+256, 4);
472 if(!same_order) swawbip(buf+260, 4);
473 memcpy(&dsr->h.quatern_c, buf+260, 4);
474 if(!same_order) swawbip(buf+264, 4);
475 memcpy(&dsr->h.quatern_d, buf+264, 4);
476 if(!same_order) swawbip(buf+268, 4);
477 memcpy(&dsr->h.qoffset_x, buf+268, 4);
478 if(!same_order) swawbip(buf+272, 4);
479 memcpy(&dsr->h.qoffset_y, buf+272, 4);
480 if(!same_order) swawbip(buf+276, 4);
481 memcpy(&dsr->h.qoffset_z, buf+276, 4);
482 if(!same_order) swawbip(buf+280, 16);
483 memcpy(dsr->h.srow_x, buf+280, 16);
484 if(!same_order) swawbip(buf+296, 16);
485 memcpy(dsr->h.srow_y, buf+296, 16);
486 if(!same_order) swawbip(buf+312, 16);
487 memcpy(dsr->h.srow_z, buf+312, 16);
488
489 memcpy(&dsr->h.intent_name, buf+328, 16);
490
491 if(status!=NULL) strcpy(status, "complete Nifti header was read");
492 if(verbose>0) fflush(stdout);
493 return(0);
494}
495/*****************************************************************************/
496
497/*****************************************************************************/
503 NIFTI_DSR *dsr,
505 FILE *fp
506) {
507 int i;
508 char *cptr, tmp[256];
509
510 /* Check input */
511 if(fp==NULL || dsr==NULL) return(1);
512
513 fprintf(fp, "Nifti header:\n");
514
515 /* Byte order */
516 if(dsr->byte_order==0) strcpy(tmp, "big"); else strcpy(tmp, "little");
517 fprintf(fp, "byte_order := %s endian\n", tmp);
518 /* sizeof_hdr */
519 fprintf(fp, "sizeof_hdr := %d\n", dsr->h.sizeof_hdr);
520 /* data_type */
521 strncpy(tmp, dsr->h.data_type, 10); tmp[10]=(char)0;
522 cptr=tmp; while(*cptr) {if(!isprint(cptr[0])) cptr[0]=' '; cptr++;}
523 fprintf(fp, "data_type := %s\n", tmp);
524 /* db_name */
525 strncpy(tmp, dsr->h.db_name, 18); tmp[18]=(char)0;
526 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
527 fprintf(fp, "db_name := %s\n", tmp);
528 /* extents */
529 fprintf(fp, "extents := %d\n", dsr->h.extents);
530 /* session_error */
531 fprintf(fp, "session_error := %d\n", dsr->h.session_error);
532 /* regular */
533 fprintf(fp, "regular := %d\n", dsr->h.regular);
534 /* dim_info */
535 fprintf(fp, "dim_info := %d\n", dsr->h.dim_info);
536
537 /* Data array dimensions */
538 i=0; fprintf(fp, "dim := {%d", dsr->h.dim[i]);
539 for(i=1; i<8; i++) fprintf(fp, ", %d", dsr->h.dim[i]);
540 fprintf(fp, "}\n");
541
542 /* Intent parameters */
543 fprintf(fp, "intent_p1 := %g\n", dsr->h.intent_p1);
544 fprintf(fp, "intent_p2 := %g\n", dsr->h.intent_p2);
545 fprintf(fp, "intent_p3 := %g\n", dsr->h.intent_p3);
546 fprintf(fp, "intent_code := %d\n", dsr->h.intent_code);
547
548 /* */
549 fprintf(fp, "datatype := %d\n", dsr->h.datatype);
550 fprintf(fp, "bitpix := %d\n", dsr->h.bitpix);
551 fprintf(fp, "slice_start := %d\n", dsr->h.slice_start);
552 i=0; fprintf(fp, "pixdim := {%g", dsr->h.pixdim[i]);
553 for(i=1; i<8; i++) fprintf(fp, ", %g", dsr->h.pixdim[i]);
554 fprintf(fp, "}\n");
555 fprintf(fp, "vox_offset := %g\n", dsr->h.vox_offset);
556 fprintf(fp, "scl_slope := %g\n", dsr->h.scl_slope);
557 fprintf(fp, "scl_inter := %g\n", dsr->h.scl_inter);
558 fprintf(fp, "slice_end := %d\n", dsr->h.slice_end);
559 fprintf(fp, "slice_code := %d\n", dsr->h.slice_code);
560 fprintf(fp, "xyzt_units := %d\n", dsr->h.xyzt_units);
561 fprintf(fp, "cal_max := %g\n", dsr->h.cal_max);
562 fprintf(fp, "cal_min := %g\n", dsr->h.cal_min);
563 fprintf(fp, "slice_duration := %g\n", dsr->h.slice_duration);
564 fprintf(fp, "toffset := %g\n", dsr->h.toffset);
565 fprintf(fp, "glmax := %d\n", dsr->h.glmax);
566 fprintf(fp, "glmin := %d\n", dsr->h.glmin);
567
568 /* Study description */
569 strncpy(tmp, dsr->h.descrip, 80); tmp[80]=(char)0;
570 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
571 fprintf(fp, "descrip := %s\n", tmp);
572 strncpy(tmp, dsr->h.aux_file, 24); tmp[24]=(char)0;
573 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
574 fprintf(fp, "aux_file := %s\n", tmp);
575
576 /* Transformation parameters */
577 fprintf(fp, "qform_code := %d\n", dsr->h.qform_code);
578 fprintf(fp, "sform_code := %d\n", dsr->h.sform_code);
579 fprintf(fp, "quatern_b := %g\n", dsr->h.quatern_b);
580 fprintf(fp, "quatern_c := %g\n", dsr->h.quatern_c);
581 fprintf(fp, "quatern_d := %g\n", dsr->h.quatern_d);
582 fprintf(fp, "qoffset_x := %g\n", dsr->h.qoffset_x);
583 fprintf(fp, "qoffset_y := %g\n", dsr->h.qoffset_y);
584 fprintf(fp, "qoffset_z := %g\n", dsr->h.qoffset_z);
585 i=0; fprintf(fp, "srow_x := {%g", dsr->h.srow_x[i]);
586 for(i=1; i<4; i++) fprintf(fp, ", %g", dsr->h.srow_x[i]);
587 fprintf(fp, "}\n");
588 i=0; fprintf(fp, "srow_y := {%g", dsr->h.srow_y[i]);
589 for(i=1; i<4; i++) fprintf(fp, ", %g", dsr->h.srow_y[i]);
590 fprintf(fp, "}\n");
591 i=0; fprintf(fp, "srow_z := {%g", dsr->h.srow_z[i]);
592 for(i=1; i<4; i++) fprintf(fp, ", %g", dsr->h.srow_z[i]);
593 fprintf(fp, "}\n");
594
595 strncpy(tmp, dsr->h.intent_name, 16); tmp[16]=(char)0;
596 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
597 fprintf(fp, "intent_name := %s\n", tmp);
598
599 /* Nifti magic number */
600 fprintf(fp, "magic := %s\n", dsr->h.magic);
601
602 /* Nifti header extender */
603 i=0; fprintf(fp, "extension := {%d", dsr->e.extension[i]);
604 for(i=1; i<4; i++) fprintf(fp, ", %d", dsr->e.extension[i]);
605 fprintf(fp, "}\n");
606
607 fflush(fp);
608 return(0);
609}
610/*****************************************************************************/
611
612/*****************************************************************************/
621 FILE *fp,
623 NIFTI_DSR *dsr,
625 int frame,
627 float *data,
629 int verbose,
632 char *status
633) {
634 int dimNr, dimx, dimy, dimz=1, dimt=1;
635 int little;
636 char *mdata, *mptr;
637 float *fptr, ss, si;
638 short int *sptr;
639 int *iptr;
640 double d;
641
642
643 if(verbose>0) {
644 printf("niftiReadImagedata(fp, h, %d, data, %d)\n", frame, verbose);
645 fflush(stdout);
646 }
647 /* Check the arguments */
648 if(status!=NULL) sprintf(status, "invalid function input");
649 if(frame<=0 || fp==NULL || dsr==NULL || data==NULL) return(1);
650
651 /* Get the image data start location from header, in case of single file
652 format */
653 long long start_pos;
654 {
655 long long int s=0;
656 if(strcasecmp(dsr->h.magic, "n+1")==0) s=(int)dsr->h.vox_offset;
657 if(s<0) start_pos=-s; else start_pos=s;
658 }
659 if(verbose>2) printf(" image_start_pos := %llu\n", start_pos);
660 /* edit it later to move to the correct frame */
661
662 /* Get the image dimensions from header */
663 if(status!=NULL) sprintf(status, "invalid image dimensions");
664 dimNr=dsr->h.dim[0]; if(dimNr<2 || dimNr>4) return(2);
665 dimx=dsr->h.dim[1];
666 dimy=dsr->h.dim[2];
667 if(dimNr>2) dimz=dsr->h.dim[3];
668 if(dimNr>3) dimt=dsr->h.dim[4];
669 if(frame>dimt) return(-1);
670 long long pxlNr=dimx*dimy*dimz; if(pxlNr<1) return(4);
671
672 // data_type is unused in Nifti
673 /* Check that datatype is supported */
674 if(verbose>1) printf(" verifying datatype %d\n", dsr->h.datatype);
675 {
676 int n=0;
677 if(dsr->h.datatype & NIFTI_DT_RGB) n+=NIFTI_DT_RGB;
680 if(dsr->h.datatype==NIFTI_DT_UNKNOWN) n+=512;
681 if(n!=0) {
682 if(verbose>0) printf("datatype error %d\n", n);
683 if(status!=NULL) sprintf(status, "unsupported pixel datatype %d", dsr->h.datatype);
684 return(6);
685 }
686 }
687
688 /* Allocate memory for the binary data */
689 if(verbose>1) printf(" allocating memory for binary data\n");
690 if(status!=NULL) sprintf(status, "invalid pixel data format");
691 if(dsr->h.bitpix==0) { // Carimas Nifti Writer does not set bitpix
692 if(dsr->h.datatype==NIFTI_DT_UNSIGNED_SHORT) dsr->h.bitpix=16;
693 }
694 if(dsr->h.bitpix<8) return(5); // We don't support bit data
695 long long rawSize=pxlNr*(dsr->h.bitpix/8); if(rawSize<1) return(6);
696 if(verbose>1) printf(" pxlNr=%lld rawSize=%lld\n", pxlNr, rawSize);
697 if(status!=NULL) sprintf(status, "out of memory");
698 mdata=(char*)malloc(rawSize); if(mdata==NULL) return(11);
699
700 /* Seek the start of current frame data */
701 if(verbose>1) printf(" seeking file position\n");
702 start_pos+=(frame-1)*rawSize;
703 if(verbose>2) printf("start_pos=%lld\n", start_pos);
704 fseeko(fp, start_pos, SEEK_SET);
705 if(ftello(fp)!=start_pos) {
706 if(status!=NULL) sprintf(status, "could not move to start_pos %lld", start_pos);
707 free(mdata); return(7);
708 }
709
710 /* Read the data */
711 if(verbose>1) printf(" reading binary data\n");
712 mptr=mdata;
713 {
714 size_t n=fread(mptr, rawSize, 1, fp);
715 if(n<1) {
716 if(status!=NULL)
717 sprintf(status, "could read only %zu bytes when request was %lld", n, rawSize);
718 free(mdata); return(8);
719 }
720 }
721
722 /* Convert byte order if necessary */
723 little=little_endian(); mptr=mdata;
724 if(little!=dsr->byte_order) {
725 if(verbose>0) printf("byte conversion\n");
726 switch(dsr->h.bitpix) {
727 case 8: /* no conversion needed */ break;
728 case 16: swabip(mptr, rawSize); break;
729 case 32: swawbip(mptr, rawSize); break;
730 case 64: swawbip(mptr, rawSize); break;
731 default:
732 if(verbose>5) printf("unsupported nifti bitpix := %d\n", dsr->h.bitpix);
733 sprintf(status, "unsupported nifti bitpix := %d", dsr->h.bitpix);
734 free(mdata); return(5);
735 }
736 }
737
738 /* Get scaling factors */
739 ss=dsr->h.scl_slope; if(ss==0) ss=1.0;
740 si=dsr->h.scl_inter;
741
742 /* Copy data to float pixel values */
743 if(verbose>1) printf(" conversion to floating point voxel values\n");
744 mptr=mdata;
745 switch(dsr->h.datatype) {
747 if(dsr->h.bitpix!=8) {
748 if(status!=NULL)
749 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
750 dsr->h.datatype, dsr->h.bitpix);
751 free(mdata); return(5);
752 }
753 fptr=data;
754 for(long long i=0; i<pxlNr; i++, mptr++, fptr++)
755 *fptr=si+ss*(float)(*mptr);
756 break;
758 if(dsr->h.bitpix!=16) {
759 if(status!=NULL)
760 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
761 dsr->h.datatype, dsr->h.bitpix);
762 free(mdata); return(5);
763 }
764 fptr=data;
765 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
766 unsigned short int *uptr=(unsigned short int*)mptr; *fptr=si+ss*(float)(*uptr);
767 }
768 break;
770 if(dsr->h.bitpix!=16) {
771 if(status!=NULL)
772 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
773 dsr->h.datatype, dsr->h.bitpix);
774 free(mdata); return(5);
775 }
776 fptr=data;
777 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
778 sptr=(short int*)mptr; *fptr=si+ss*(float)(*sptr);
779 }
780 break;
782 if(dsr->h.bitpix!=16 && dsr->h.bitpix!=32) {
783 if(status!=NULL)
784 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
785 dsr->h.datatype, dsr->h.bitpix);
786 free(mdata); return(5);
787 }
788 fptr=data;
789 if(dsr->h.bitpix==16) {
790 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
791 iptr=(int*)mptr; *fptr=si+ss*(float)(*iptr);
792 }
793 } else if(dsr->h.bitpix==32) {
794 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
795 iptr=(int*)mptr; *fptr=si+ss*(float)(*iptr);
796 }
797 }
798 break;
799 case NIFTI_DT_FLOAT: // 16
800 if(dsr->h.bitpix==32) {
801 fptr=data; memcpy(fptr, mptr, pxlNr*4);
802 fptr=data; for(long long i=0; i<pxlNr; i++, fptr++) *fptr*=ss;
803 fptr=data; for(long long i=0; i<pxlNr; i++, fptr++) *fptr+=si;
804 } else {
805 if(status!=NULL)
806 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
807 dsr->h.datatype, dsr->h.bitpix);
808 free(mdata); return(5);
809 }
810 break;
811 case NIFTI_DT_DOUBLE:
812 if(dsr->h.bitpix!=64) {
813 if(status!=NULL)
814 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
815 dsr->h.datatype, dsr->h.bitpix);
816 free(mdata); return(5);
817 }
818 fptr=data;
819 for(long long i=0; i<pxlNr; i++, mptr+=8, fptr++) {
820 memcpy(&d, mptr, 8); *fptr=si+ss*d;
821 }
822 break;
823 default:
824 if(status!=NULL)
825 sprintf(status, "unsupported pixel datatype %d", dsr->h.datatype);
826 free(mdata); return(5);
827 }
828
829 if(verbose>1) {printf(" data read successfully.\n"); fflush(stdout);}
830 free(mdata);
831 if(status!=NULL) sprintf(status, "ok");
832 return 0;
833}
834/*****************************************************************************/
835
836/*****************************************************************************/
846 char *filename,
848 NIFTI_DSR *dsr,
850 int verbose,
853 char *status
854) {
855 FILE *fp;
856 int little; // 1 if current platform is little endian (x86), else 0
857 int same_order;
858 unsigned char buf1[NIFTI_HEADER_SIZE];
859 unsigned char buf2[NIFTI_HEADER_EXTENDER_SIZE];
860 unsigned char *bptr;
861
862
863 if(verbose>0) {
864 printf("\nniftiWriteHeader(%s, ...)\n", filename); fflush(stdout);
865 }
866
867 /* Check arguments */
868 if(status!=NULL) strcpy(status, "invalid function input");
869 if(filename==NULL || strlen(filename)==0 || dsr==NULL) return(1);
870 /* Check magic number */
871 if(strcmp(dsr->h.magic, "ni1")!=0 && strcmp(dsr->h.magic, "n+1")!=0)
872 return(1);
873
874 /* Check if byte swapping is needed */
875 little=little_endian(); if(verbose>3) printf(" little := %d\n", little);
876 if(little==dsr->byte_order) same_order=1; else same_order=0;
877
878 /* Make sure that buffers are all zeroes to begin with */
879 memset(buf1, 0, sizeof(NIFTI_HEADER_SIZE));
880 memset(buf2, 0, sizeof(NIFTI_HEADER_EXTENDER_SIZE));
881
882 /* Copy header contents into buffer */
883 if(verbose>2) printf(" setting write buffer\n");
884 bptr=buf1+0;
885 memcpy(bptr, &dsr->h.sizeof_hdr, 4); if(!same_order) swawbip(bptr, 4);
886 bptr=buf1+4;
887 memcpy(bptr, &dsr->h.data_type, 10);
888 bptr=buf1+14;
889 memcpy(bptr, &dsr->h.db_name, 18);
890 bptr=buf1+32;
891 memcpy(bptr, &dsr->h.extents, 4); if(!same_order) swawbip(bptr, 4);
892 bptr=buf1+36;
893 memcpy(bptr, &dsr->h.session_error, 2); if(!same_order) swabip(bptr, 2);
894 bptr=buf1+38;
895 memcpy(bptr, &dsr->h.regular, 1);
896 bptr=buf1+39;
897 memcpy(bptr, &dsr->h.dim_info, 1);
898
899 bptr=buf1+40;
900 memcpy(bptr, dsr->h.dim, 16); if(!same_order) swabip(bptr, 16);
901 bptr=buf1+56;
902 memcpy(bptr, &dsr->h.intent_p1, 4); if(!same_order) swawbip(bptr, 4);
903 bptr=buf1+60;
904 memcpy(bptr, &dsr->h.intent_p2, 4); if(!same_order) swawbip(bptr, 4);
905 bptr=buf1+64;
906 memcpy(bptr, &dsr->h.intent_p3, 4); if(!same_order) swawbip(bptr, 4);
907 bptr=buf1+68;
908 memcpy(bptr, &dsr->h.intent_code, 2); if(!same_order) swabip(bptr, 2);
909 bptr=buf1+70;
910 memcpy(bptr, &dsr->h.datatype, 2); if(!same_order) swabip(bptr, 2);
911 bptr=buf1+72;
912 memcpy(bptr, &dsr->h.bitpix, 2); if(!same_order) swabip(bptr, 2);
913 bptr=buf1+74;
914 memcpy(bptr, &dsr->h.slice_start, 2); if(!same_order) swabip(bptr, 2);
915 bptr=buf1+76;
916 memcpy(bptr, dsr->h.pixdim, 32); if(!same_order) swawbip(bptr, 32);
917 bptr=buf1+108;
918 memcpy(bptr, &dsr->h.vox_offset, 4); if(!same_order) swawbip(bptr, 4);
919 bptr=buf1+112;
920 memcpy(bptr, &dsr->h.scl_slope, 4); if(!same_order) swawbip(bptr, 4);
921 bptr=buf1+116;
922 memcpy(bptr, &dsr->h.scl_inter, 4); if(!same_order) swawbip(bptr, 4);
923 bptr=buf1+120;
924 memcpy(bptr, &dsr->h.slice_end, 2); if(!same_order) swabip(bptr, 2);
925 bptr=buf1+122;
926 memcpy(bptr, &dsr->h.slice_code, 1);
927 bptr=buf1+123;
928 memcpy(bptr, &dsr->h.xyzt_units, 1);
929 bptr=buf1+124;
930 memcpy(bptr, &dsr->h.cal_max, 4); if(!same_order) swawbip(bptr, 4);
931 bptr=buf1+128;
932 memcpy(bptr, &dsr->h.cal_min, 4); if(!same_order) swawbip(bptr, 4);
933 bptr=buf1+132;
934 memcpy(bptr, &dsr->h.slice_duration, 4); if(!same_order) swawbip(bptr, 4);
935 bptr=buf1+136;
936 memcpy(bptr, &dsr->h.toffset, 4); if(!same_order) swawbip(bptr, 4);
937 bptr=buf1+140;
938 memcpy(bptr, &dsr->h.glmax, 4); if(!same_order) swawbip(bptr, 4);
939 bptr=buf1+144;
940 memcpy(bptr, &dsr->h.glmin, 4); if(!same_order) swawbip(bptr, 4);
941
942 bptr=buf1+148;
943 memcpy(bptr, dsr->h.descrip, 80);
944 bptr=buf1+228;
945 memcpy(bptr, dsr->h.aux_file, 24);
946 bptr=buf1+252;
947 memcpy(bptr, &dsr->h.qform_code, 2); if(!same_order) swabip(bptr, 2);
948 bptr=buf1+254;
949 memcpy(bptr, &dsr->h.sform_code, 2); if(!same_order) swabip(bptr, 2);
950 bptr=buf1+256;
951 memcpy(bptr, &dsr->h.quatern_b, 4); if(!same_order) swawbip(bptr, 4);
952 bptr=buf1+260;
953 memcpy(bptr, &dsr->h.quatern_c, 4); if(!same_order) swawbip(bptr, 4);
954 bptr=buf1+264;
955 memcpy(bptr, &dsr->h.quatern_d, 4); if(!same_order) swawbip(bptr, 4);
956 bptr=buf1+268;
957 memcpy(bptr, &dsr->h.qoffset_x, 4); if(!same_order) swawbip(bptr, 4);
958 bptr=buf1+272;
959 memcpy(bptr, &dsr->h.qoffset_y, 4); if(!same_order) swawbip(bptr, 4);
960 bptr=buf1+276;
961 memcpy(bptr, &dsr->h.qoffset_z, 4); if(!same_order) swawbip(bptr, 4);
962 bptr=buf1+280;
963 memcpy(bptr, dsr->h.srow_x, 16); if(!same_order) swawbip(bptr, 16);
964 bptr=buf1+296;
965 memcpy(bptr, dsr->h.srow_y, 16); if(!same_order) swawbip(bptr, 16);
966 bptr=buf1+312;
967 memcpy(bptr, dsr->h.srow_z, 16); if(!same_order) swawbip(bptr, 16);
968 bptr=buf1+328;
969 memcpy(bptr, dsr->h.intent_name, 16);
970 bptr=buf1+344;
971 memcpy(bptr, dsr->h.magic, 4);
972
973 /* Open header file for write; do not delete old contents, since this
974 function may be called to update single format NIfTI */
975 if(strcmp(dsr->h.magic, "ni1")==0) { // dual file format
976 if(verbose>2) printf(" creating NIfTI header %s\n", filename);
977 fp=fopen(filename, "wb");
978 } else if(access(filename, 0)==-1) { // single file format, not exists
979 if(verbose>2) printf(" creating NIfTI header %s\n", filename);
980 fp=fopen(filename, "wb");
981 } else { // single file format, exists already
982 if(verbose>2) printf(" opening NIfTI header %s\n", filename);
983 fp=fopen(filename, "r+b");
984 }
985 if(fp==NULL) {
986 if(status!=NULL) strcpy(status, "cannot open Nifti header for write");
987 return(2);
988 }
989
990 /* Write header */
991 if(verbose>2) printf(" writing NIfTI header\n");
992 if(fwrite(buf1, 1, NIFTI_HEADER_SIZE, fp) != NIFTI_HEADER_SIZE) {
993 if(status!=NULL) strcpy(status, "cannot write Nifti header");
994 fclose(fp); return(3);
995 }
996
997 /* Write extender, if necessary (leave the contents 0 0 0 0 for now) */
998 if(verbose>2) printf(" writing NIfTI extender\n");
999 if(fwrite(buf2, 1, NIFTI_HEADER_EXTENDER_SIZE, fp)!= NIFTI_HEADER_EXTENDER_SIZE) {
1000 if(status!=NULL) strcpy(status, "cannot write Nifti header extender");
1001 fclose(fp); return(3);
1002 }
1003
1004 fclose(fp);
1005
1006 if(verbose>2) {printf(" complete Nifti header was written\n"); fflush(stdout);}
1007 if(status!=NULL) strcpy(status, "complete Nifti header was written");
1008 return(0);
1009}
1010/*****************************************************************************/
1011
1012/*****************************************************************************/
Header file for libtpcimgio.
#define NIFTI_DT_RGB
#define IMG_NIFTI_1S
#define NIFTI_DT_BINARY
#define NIFTI_DT_FLOAT
#define NIFTI_DT_UNSIGNED_SHORT
#define NIFTI_DT_SIGNED_SHORT
#define NIFTI_HEADER_EXTENDER_SIZE
#define NIFTI_DT_SIGNED_INT
#define NIFTI_DT_UNSIGNED_CHAR
#define NIFTI_DT_COMPLEX
#define NIFTI_HEADER_SIZE
#define IMG_NIFTI_1D
#define NIFTI_DT_UNKNOWN
#define NIFTI_DT_DOUBLE
void swabip(void *buf, long long int size)
Definition swap.c:72
void swawbip(void *buf, long long int size)
Definition swap.c:93
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
int little_endian()
Definition swap.c:14
int niftiReadImagedata(FILE *fp, NIFTI_DSR *dsr, int frame, float *data, int verbose, char *status)
Definition nifti.c:619
int niftiReadHeader(char *filename, NIFTI_DSR *dsr, int verbose, char *status)
Definition nifti.c:293
int niftiWriteHeader(char *filename, NIFTI_DSR *dsr, int verbose, char *status)
Definition nifti.c:844
int niftiCreateFNames(const char *filename, char *hdrfile, char *imgfile, char *siffile, int fileformat)
Definition nifti.c:44
void niftiRemoveFNameExtension(char *fname)
Definition nifti.c:23
int niftiExists(const char *filename, char *hdrfile, char *imgfile, char *siffile, NIFTI_DSR *header, int verbose, char *status)
Definition nifti.c:160
int niftiPrintHeader(NIFTI_DSR *dsr, FILE *fp)
Definition nifti.c:501
int niftiRemove(const char *dbname, int fileformat, int verbose)
Definition nifti.c:100
short int qform_code
short int slice_start
short int slice_end
short int datatype
char aux_file[24]
char intent_name[16]
short int bitpix
char data_type[10]
short int sform_code
short int dim[8]
short int intent_code
short int session_error
NIFTI_1_HEADER h
NIFTI_EXTENDER e