TPCCLIB
Loading...
Searching...
No Matches
nifti.c File Reference

Procedures for reading and writing NIfTI-1 PET images. More...

#include "libtpcimgio.h"

Go to the source code of this file.

Functions

void niftiRemoveFNameExtension (char *fname)
int niftiCreateFNames (const char *filename, char *hdrfile, char *imgfile, char *siffile, int fileformat)
int niftiRemove (const char *dbname, int fileformat, int verbose)
int niftiExists (const char *filename, char *hdrfile, char *imgfile, char *siffile, NIFTI_DSR *header, int verbose, char *status)
int niftiReadHeader (char *filename, NIFTI_DSR *dsr, int verbose, char *status)
int niftiPrintHeader (NIFTI_DSR *dsr, FILE *fp)
int niftiReadImagedata (FILE *fp, NIFTI_DSR *dsr, int frame, float *data, int verbose, char *status)
int niftiWriteHeader (char *filename, NIFTI_DSR *dsr, int verbose, char *status)

Detailed Description

Procedures for reading and writing NIfTI-1 PET images.

Author
Vesa Oikonen

Function are not intended to support all NIfTI files or file properties, but only those that have been found necessary in Turku PET Centre. For full NIfTI support, use other libraries e.g. niftilib https://niftilib.sourceforge.net/

NIfTI-1 and NIfTI-2 documentation and source codes in https://nifti.nimh.nih.gov/

Procedures in this file are not dependent on IMG struct.

Definition in file nifti.c.

Function Documentation

◆ niftiCreateFNames()

int niftiCreateFNames ( const char * filename,
char * hdrfile,
char * imgfile,
char * siffile,
int fileformat )

Construct the file names for NIfTI image.

Returns
Returns 0 if successful, otherwise <>0.
See also
niftiExists
Parameters
filenameFilename, either header file, image file, or base name without extensions, but possibly with path name. This string is never modified.
hdrfileHeader filename will be written in this char pointer (space needs to allocated by caller); If header and image are combined, then this will be the name of combined file; enter NULL if not needed.
imgfileImage filename will be written in this char pointer (space needs to allocated by caller); If header and image are combined, then this will be the name of combined file; enter NULL if not needed.
siffileSIF filename will be written in this char pointer (space needs to allocated by caller); enter NULL if not needed.
fileformatNIfTI file format, either IMG_NIFTI_1D (31) or IMG_NIFTI_1S (32).

Definition at line 44 of file nifti.c.

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}
#define IMG_NIFTI_1S
void niftiRemoveFNameExtension(char *fname)
Definition nifti.c:23
#define IMG_NIFTI_1D
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:244

Referenced by imgWriteNifti(), imgWriteNiftiFrame(), niftiCreateFNames(), and niftiRemove().

◆ niftiExists()

int niftiExists ( const char * filename,
char * hdrfile,
char * imgfile,
char * siffile,
NIFTI_DSR * header,
int verbose,
char * status )

Verify if specified filename is a NIfTI file.

Returns
Returns 0 if it is not, 1 if header and image data are found (either as one combined file or as separate files, and 2, if SIF is found too.
See also
niftiRemove
Parameters
filenameFilename, either header file, image file, or base name without extensions. This string is never modified.
hdrfileIf filename refers to a Nifti file, then header filename will be written in this char pointer (space needs to allocated by caller); If header and image are combined, then this will be the name of combined file; enter NULL if not needed.
imgfileIf filename refers to a Nifti file, then image filename will be written in this char pointer (space needs to allocated by caller); If header and image are combined, then this will be the name of combined file; enter NULL if not needed.
siffileIf filename refers to a Nifti file, and if SIF exists, then SIF filename will be written in this char pointer (space needs to allocated by caller); NULL if not needed.
headerPointer to Nifti header, which is filled in this function; enter NULL, if not needed.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed.

Definition at line 160 of file nifti.c.

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 /* Get filename extension, if there is one */
198 char fext[FILENAME_MAX]; fext[0]=(char)0;
199 strcpy(temp, filename);
200 char *cptr=filenameGetExtension(temp);
201 if(cptr!=NULL) strcpy(fext, cptr);
202 /* If extension is .v, we have ECAT7 file */
203 if(strcasecmp(fext, ".v")==0) return(0);
204
205 /* Construct the base file name wo extensions */
206 strlcpy(basefile, filename, FILENAME_MAX);
208 if(verbose>1) printf("\n basefile := %s\n", basefile);
209
210 /* If extension is .nii, we have NIFTI single file format */
211 if(strcasecmp(fext, ".nii")==0) {
212 if(verbose>1) printf(" we have filename with .nii extension %s\n", temp);
213 combined=1;
214 /* If it is not accessible then we are done here */
215 if(access(filename, 0) == -1) {
216 if(verbose>0) printf(" %s not found or accessible.\n", filename);
217 if(status!=NULL) strcpy(status, "file not accessible");
218 return(0);
219 }
220 /* If accessible, then we have the names (except for the SIF) */
221 strcpy(localhdrfile, temp);
222 if(hdrfile!=NULL) strcpy(hdrfile, temp);
223 if(imgfile!=NULL) strcpy(imgfile, temp);
224 combined=1;
225 if(verbose>1) printf(" %s is accessible.\n", temp);
226 }
227
228 /* If we did not have the .nii extension, then maybe we have .img or .hdr file */
229 if(!localhdrfile[0] && (strcasecmp(fext, ".hdr")==0 || strcasecmp(fext, ".img")==0)) {
230 /* If it is not accessible then we are done here */
231 if(access(filename, 0) == -1) {
232 if(verbose>0) printf(" %s not found or accessible.\n", filename);
233 if(status!=NULL) strcpy(status, "file not accessible");
234 return(0);
235 }
236 /* If accessible, then we must have the other one, too */
237 if(strcasecmp(fext, ".hdr")==0) {
238 strcpy(temp, basefile); strcat(temp, ".img");
239 if(access(temp, 0) == -1) {
240 if(verbose>0) printf(" img file not found or accessible.\n");
241 if(status!=NULL) strcpy(status, "file not accessible");
242 return(0);
243 }
244 /* If accessible, then we have the names (except for the SIF) */
245 strcpy(localhdrfile, filename);
246 if(hdrfile!=NULL) strcpy(hdrfile, filename);
247 if(imgfile!=NULL) strcpy(imgfile, temp);
248 if(verbose>1) printf(" %s and %s are accessible.\n", filename, temp);
249 } else {
250 strcpy(temp, basefile); strcat(temp, ".hdr");
251 if(access(temp, 0) == -1) {
252 strcpy(temp, basefile); strcat(temp, ".img.hdr");
253 if(access(temp, 0) == -1) {
254 if(verbose>0) printf(" hdr file not found or accessible.\n");
255 if(status!=NULL) strcpy(status, "file not accessible");
256 return(0);
257 }
258 }
259 /* If accessible, then we have the names (except for the SIF) */
260 strcpy(localhdrfile, temp);
261 if(hdrfile!=NULL) strcpy(hdrfile, temp);
262 if(imgfile!=NULL) strcpy(imgfile, filename);
263 if(verbose>1) printf(" %s and %s are accessible.\n", filename, temp);
264 }
265 }
266
267 /* If we did not have the extensions, then maybe we were given basename */
268 if(!localhdrfile[0]) {
269 if(verbose>1) printf(" we may have got basename %s\n", filename);
270 strcpy(temp, filename); strcat(temp, ".nii");
271 if(access(temp, 0) == 0) {
272 /* If accessible, then we have the names (except for the SIF) */
273 strcpy(localhdrfile, temp);
274 if(hdrfile!=NULL) strcpy(hdrfile, temp);
275 if(imgfile!=NULL) strcpy(imgfile, temp);
276 combined=1;
277 if(verbose>1) printf(" %s is accessible.\n", temp);
278 } else {
279 strcpy(temp, basefile); strcat(temp, ".hdr");
280 if(access(temp, 0) == -1) {
281 strcpy(temp, basefile); strcat(temp, ".img.hdr");
282 if(access(temp, 0) == -1) {
283 if(verbose>0) printf(" hdr file not found or accessible.\n");
284 if(status!=NULL) strcpy(status, "file not accessible");
285 return(0);
286 }
287 }
288 strcpy(localhdrfile, temp);
289 strcpy(temp, basefile); strcat(temp, ".img");
290 if(access(temp, 0) == -1) {
291 if(verbose>0) printf(" img file not found or accessible.\n");
292 if(status!=NULL) strcpy(status, "file not accessible");
293 return(0);
294 }
295 /* We have the names (except for the SIF) */
296 if(hdrfile!=NULL) strcpy(hdrfile, localhdrfile);
297 if(imgfile!=NULL) strcpy(imgfile, temp);
298 if(verbose>1) printf(" %s and %s are accessible.\n", filename, temp);
299 }
300 }
301
302 /* Try to read the header */
303 if((ret=niftiReadHeader(localhdrfile, dsr, verbose, temp))!=0) {
304 if(status!=NULL) strcpy(status, "file is not Nifti");
305 if(verbose>0) {
306 printf(" %s was not identified as Nifti header file (%d).\n", localhdrfile, ret);
307 printf(" %s\n", temp);
308 }
309 return(0);
310 }
311 if(verbose>1) printf(" %s is identified as Nifti.\n", localhdrfile);
312 if(verbose>10) niftiPrintHeader(dsr, stdout);
313
314
315#if(0)
316 /* Combined header and image file, given as basename, exists? */
317 strcpy(temp, basefile); strcat(temp, ".nii");
318 if(access(temp, 0) == -1) {
319 if(verbose>0) printf(" %s not found or accessible.\n", temp);
320 } else {
321 /* Preserve header and image filenames */
322 strcpy(localhdrfile, temp);
323 if(hdrfile!=NULL) strcpy(hdrfile, temp);
324 if(imgfile!=NULL) strcpy(imgfile, temp);
325 combined=1;
326 if(verbose>1) printf(" %s is accessible.\n", temp);
327 }
328
329 /* If not, then check if header file exists */
330 if(combined==0) {
331 strcpy(temp, basefile); strcat(temp, ".hdr");
332 if(access(temp, 0) == -1) {
333 strcpy(temp, basefile); strcat(temp, ".img.hdr");
334 if(access(temp, 0) == -1) {
335 if(verbose>0) printf(" hdr file not found or accessible.\n");
336 if(status!=NULL) strcpy(status, "file not accessible");
337 return(0);
338 }
339 }
340 /* Preserve header filename */
341 strcpy(localhdrfile, temp);
342 if(hdrfile!=NULL) strcpy(hdrfile, temp);
343 if(verbose>1) printf(" %s is accessible.\n", temp);
344 }
345
346 /* If not combined, then does image file exists? */
347 if(combined==0) {
348 strcpy(temp, basefile); strcat(temp, ".img");
349 if(access(temp, 0) == -1) {
350 if(verbose>0) printf(" %s not found or accessible.\n", temp);
351 if(status!=NULL) strcpy(status, "file not accessible");
352 return(0);
353 }
354 /* Preserve image filename */
355 if(imgfile!=NULL) strcpy(imgfile, temp);
356 if(verbose>1) printf(" %s is accessible.\n", temp);
357 }
358
359 /* Is this Nifti file? */
360 if((ret=niftiReadHeader(localhdrfile, dsr, verbose, temp))!=0) {
361 if(status!=NULL) strcpy(status, "file is not Nifti");
362 if(verbose>0) {
363 printf(" %s was not identified as Nifti header file (%d).\n", localhdrfile, ret);
364 printf(" %s\n", temp);
365 }
366 return(0);
367 }
368 if(verbose>1) printf(" %s is identified as Nifti.\n", localhdrfile);
369 if(verbose>10) niftiPrintHeader(dsr, stdout);
370#endif
371
372 /* SIF exists? */
373 strcpy(temp, basefile); strcat(temp, ".sif");
374 if(verbose>3) printf(" checking if %s exists\n", temp);
375 if(access(temp, 0) == -1) {
376 strcpy(temp, basefile); strcat(temp, ".img.sif");
377 if(verbose>3) printf(" checking if %s exists\n", temp);
378 if(access(temp, 0) == -1) {
379 strcpy(temp, basefile); strcat(temp, ".nii.sif");
380 if(verbose>3) printf(" checking if %s exists\n", temp);
381 if(access(temp, 0) == -1) {
382 if(verbose>0) printf("\n SIF not found or accessible.\n");
383 if(siffile!=NULL) strcpy(siffile, "");
384 if(status!=NULL) {
385 if(combined) strcpy(status, "combined Nifti file is accessible");
386 else strcpy(status, "Nifti files are accessible");
387 }
388 return(1); // but otherwise ok
389 }
390 }
391 }
392 /* Preserve SIF filename */
393 if(siffile!=NULL) strcpy(siffile, temp);
394 if(verbose>1) printf(" %s is accessible.\n", temp);
395 if(status!=NULL) {
396 if(combined) strcpy(status, "combined Nifti file and SIF are accessible");
397 else strcpy(status, "Nifti files and SIF are accessible");
398 }
399 return(2);
400}
char * filenameGetExtension(char *s)
Get the last extension of a filename.
Definition filename.c:139
int niftiPrintHeader(NIFTI_DSR *h, FILE *fp)
Definition nifti.c:616
int niftiReadHeader(char *filename, NIFTI_DSR *h, int verbose, char *status)
Definition nifti.c:408

Referenced by imgFormatDetermine(), imgRead(), imgReadNiftiFrame(), imgReadNiftiHeader(), imgWriteNiftiFrame(), and niftiExists().

◆ niftiPrintHeader()

int niftiPrintHeader ( NIFTI_DSR * dsr,
FILE * fp )

Print the contents of Nifti header to specified file pointer.

Returns
Returns 0 if ok, 1 if invalid input.
Parameters
dsrPointer to combined Nifti header.
fpFile pointer where header information is printed.

Definition at line 616 of file nifti.c.

621 {
622 int i;
623 char *cptr, tmp[256];
624
625 /* Check input */
626 if(fp==NULL || dsr==NULL) return(1);
627
628 fprintf(fp, "Nifti header:\n");
629
630 /* Byte order */
631 if(dsr->byte_order==0) strcpy(tmp, "big"); else strcpy(tmp, "little");
632 fprintf(fp, "byte_order := %s endian\n", tmp);
633 /* sizeof_hdr */
634 fprintf(fp, "sizeof_hdr := %d\n", dsr->h.sizeof_hdr);
635 /* data_type */
636 strncpy(tmp, dsr->h.data_type, 10); tmp[10]=(char)0;
637 cptr=tmp; while(*cptr) {if(!isprint(cptr[0])) cptr[0]=' '; cptr++;}
638 fprintf(fp, "data_type := %s\n", tmp);
639 /* db_name */
640 strncpy(tmp, dsr->h.db_name, 18); tmp[18]=(char)0;
641 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
642 fprintf(fp, "db_name := %s\n", tmp);
643 /* extents */
644 fprintf(fp, "extents := %d\n", dsr->h.extents);
645 /* session_error */
646 fprintf(fp, "session_error := %d\n", dsr->h.session_error);
647 /* regular */
648 fprintf(fp, "regular := %d\n", dsr->h.regular);
649 /* dim_info */
650 fprintf(fp, "dim_info := %d\n", dsr->h.dim_info);
651
652 /* Data array dimensions */
653 i=0; fprintf(fp, "dim := {%d", dsr->h.dim[i]);
654 for(i=1; i<8; i++) fprintf(fp, ", %d", dsr->h.dim[i]);
655 fprintf(fp, "}\n");
656
657 /* Intent parameters */
658 fprintf(fp, "intent_p1 := %g\n", dsr->h.intent_p1);
659 fprintf(fp, "intent_p2 := %g\n", dsr->h.intent_p2);
660 fprintf(fp, "intent_p3 := %g\n", dsr->h.intent_p3);
661 fprintf(fp, "intent_code := %d\n", dsr->h.intent_code);
662
663 /* */
664 fprintf(fp, "datatype := %d\n", dsr->h.datatype);
665 fprintf(fp, "bitpix := %d\n", dsr->h.bitpix);
666 fprintf(fp, "slice_start := %d\n", dsr->h.slice_start);
667 i=0; fprintf(fp, "pixdim := {%g", dsr->h.pixdim[i]);
668 for(i=1; i<8; i++) fprintf(fp, ", %g", dsr->h.pixdim[i]);
669 fprintf(fp, "}\n");
670 fprintf(fp, "vox_offset := %g\n", dsr->h.vox_offset);
671 fprintf(fp, "scl_slope := %g\n", dsr->h.scl_slope);
672 fprintf(fp, "scl_inter := %g\n", dsr->h.scl_inter);
673 fprintf(fp, "slice_end := %d\n", dsr->h.slice_end);
674 fprintf(fp, "slice_code := %d\n", dsr->h.slice_code);
675 fprintf(fp, "xyzt_units := %d\n", dsr->h.xyzt_units);
676 fprintf(fp, "cal_max := %g\n", dsr->h.cal_max);
677 fprintf(fp, "cal_min := %g\n", dsr->h.cal_min);
678 fprintf(fp, "slice_duration := %g\n", dsr->h.slice_duration);
679 fprintf(fp, "toffset := %g\n", dsr->h.toffset);
680 fprintf(fp, "glmax := %d\n", dsr->h.glmax);
681 fprintf(fp, "glmin := %d\n", dsr->h.glmin);
682
683 /* Study description */
684 strncpy(tmp, dsr->h.descrip, 80); tmp[80]=(char)0;
685 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
686 fprintf(fp, "descrip := %s\n", tmp);
687 strncpy(tmp, dsr->h.aux_file, 24); tmp[24]=(char)0;
688 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
689 fprintf(fp, "aux_file := %s\n", tmp);
690
691 /* Transformation parameters */
692 fprintf(fp, "qform_code := %d\n", dsr->h.qform_code);
693 fprintf(fp, "sform_code := %d\n", dsr->h.sform_code);
694 fprintf(fp, "quatern_b := %g\n", dsr->h.quatern_b);
695 fprintf(fp, "quatern_c := %g\n", dsr->h.quatern_c);
696 fprintf(fp, "quatern_d := %g\n", dsr->h.quatern_d);
697 fprintf(fp, "qoffset_x := %g\n", dsr->h.qoffset_x);
698 fprintf(fp, "qoffset_y := %g\n", dsr->h.qoffset_y);
699 fprintf(fp, "qoffset_z := %g\n", dsr->h.qoffset_z);
700 i=0; fprintf(fp, "srow_x := {%g", dsr->h.srow_x[i]);
701 for(i=1; i<4; i++) fprintf(fp, ", %g", dsr->h.srow_x[i]);
702 fprintf(fp, "}\n");
703 i=0; fprintf(fp, "srow_y := {%g", dsr->h.srow_y[i]);
704 for(i=1; i<4; i++) fprintf(fp, ", %g", dsr->h.srow_y[i]);
705 fprintf(fp, "}\n");
706 i=0; fprintf(fp, "srow_z := {%g", dsr->h.srow_z[i]);
707 for(i=1; i<4; i++) fprintf(fp, ", %g", dsr->h.srow_z[i]);
708 fprintf(fp, "}\n");
709
710 strncpy(tmp, dsr->h.intent_name, 16); tmp[16]=(char)0;
711 cptr=tmp; while(*cptr) {if(!isprint(*cptr)) *cptr=' '; cptr++;}
712 fprintf(fp, "intent_name := %s\n", tmp);
713
714 /* Nifti magic number */
715 fprintf(fp, "magic := %s\n", dsr->h.magic);
716
717 /* Nifti header extender */
718 i=0; fprintf(fp, "extension := {%d", dsr->e.extension[i]);
719 for(i=1; i<4; i++) fprintf(fp, ", %d", dsr->e.extension[i]);
720 fprintf(fp, "}\n");
721
722 fflush(fp);
723 return(0);
724}
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

Referenced by niftiExists(), and niftiPrintHeader().

◆ niftiReadHeader()

int niftiReadHeader ( char * filename,
NIFTI_DSR * dsr,
int verbose,
char * status )

Read Nifti header contents. Currently, does not read Nifti-1 header extension.

Returns
Returns 0, if successful, otherwise >0.
See also
niftiReadImagedata, niftiWriteHeader, niftiExists
Parameters
filenameName of file to read (including path and extension)
dsrPointer to previously allocated header structure
verboseVerbose level; if zero, then nothing is printed to stderr or stdout
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed

Definition at line 408 of file nifti.c.

418 {
419 FILE *fp;
420 int little; // 1 if current platform is little endian (x86), else 0
421 int same_order, extender=0;
422 unsigned char buf[NIFTI_HEADER_SIZE];
423 short int s;
424
425 /* Check arguments */
426 if(filename==NULL || strlen(filename)==0 || dsr==NULL) return(1);
427 if(verbose>0) {
428 printf("\nniftiReadHeader(%s, ...)\n", filename); fflush(stdout);}
429 if(status!=NULL) strcpy(status, "OK");
430 little=little_endian(); if(verbose>3) printf(" little := %d\n", little);
431
432 /* Open file */
433 fp=fopen(filename, "rb"); if(fp==NULL) {
434 if(status!=NULL) strcpy(status, "cannot open file");
435 if(verbose>0) fprintf(stderr, "Error: cannot open file %s\n", filename);
436 return(2);
437 }
438
439 /* Read Nifti header */
440 if(fread(buf, NIFTI_HEADER_SIZE, 1, fp)<1) {
441 if(status!=NULL) strcpy(status, "complete Nifti header not found");
442 if(verbose>0)
443 fprintf(stderr, "Error: invalid Nifti header file %s\n", filename);
444 return(3);
445 }
446 /* Read nifti1 extender */
447 for(int n=0; n<4; n++) dsr->e.extension[n]=(char)0;
448 if(fread(dsr->e.extension, 4, 1, fp)<1) {
449 if(status!=NULL) strcpy(status, "complete Nifti header not found");
450 if(verbose>1)
451 fprintf(stdout, "Nifti header extender not found in %s\n", filename);
452 extender=0;
453 } else {
454 extender=1;
455 }
456 /* Close file */
457 fclose(fp);
458
459 /* Read Nifti Magic number */
460 memcpy(dsr->h.magic, buf+344, 4);
461 if(strcasecmp(dsr->h.magic, "ni1")==0) {
462 if(verbose>1) {printf(" separate hdr and img files.\n"); fflush(stdout);}
463 } else if(strcasecmp(dsr->h.magic, "n+1")==0) {
464 if(verbose>1) printf(" combined hdr and img data.\n");
465 } else {
466 if(status!=NULL) strcpy(status, "Nifti magic number not found");
467 if(verbose>0) {
468 fprintf(stderr, "Error: not a Nifti header file %s\n", filename);
469 fflush(stderr);
470 }
471 if(verbose>2) {
472 printf("magic := {%d, %d, %d, %d}\n", dsr->h.magic[0], dsr->h.magic[1],
473 dsr->h.magic[2], dsr->h.magic[3]);
474 }
475 return(4);
476 }
477 if(verbose>1) printf(" Nifti Magic number := %s\n", dsr->h.magic);
478 /* Check that 4-byte header extender was found, if magic number is n+1 */
479 if(strcasecmp(dsr->h.magic, "n+1")==0 && extender==0) {
480 if(status!=NULL) strcpy(status, "Nifti header extender not found");
481 if(verbose>0) {
482 fprintf(stderr, "Error: not valid Nifti n+1 header file %s\n", filename);
483 fflush(stderr);
484 }
485 return(5);
486 }
487
488 /* Determine from dim[0] if file is big or little endian */
489 memcpy(&s, buf+40, 2); if(verbose>10) printf(" s := %d\n", s);
490 if(s>0 && s<8) { // same order in file and current machine
491 dsr->byte_order=little;
492 same_order=1;
493 } else {
494 swabip(&s, 2); if(verbose>10) printf(" s := %d\n", s);
495 if(s>0 && s<8) { // opposite order in file and in current machine
496 if(little==1) dsr->byte_order=0; else dsr->byte_order=1;
497 same_order=0;
498 } else {
499 if(status!=NULL) strcpy(status, "invalid Nifti byte order");
500 if(verbose>0)
501 fprintf(stderr, "Error: not a valid Nifti header file %s\n", filename);
502 return(6);
503 }
504 }
505 if(verbose>1) printf(" Nifti byte order := %d\n", dsr->byte_order);
506
507 /* Size of header */
508 {
509 int n=0;
510 memcpy(&n, buf+0, 4); if(!same_order) swawbip(&n, 4);
511 if(n!=348) {
512 if(status!=NULL) strcpy(status, "invalid Nifti sizeof_hdr");
513 if(verbose>0)
514 fprintf(stderr, "Error: not a valid Nifti header file %s\n", filename);
515 return(7);
516 }
517 dsr->h.sizeof_hdr=n;
518 }
519
520 /* */
521 memcpy(&dsr->h.data_type, buf+4, 10);
522 memcpy(&dsr->h.db_name, buf+14, 18);
523 if(!same_order) swawbip(buf+32, 4);
524 memcpy(&dsr->h.extents, buf+32, 4);
525 if(!same_order) swabip(buf+36, 2);
526 memcpy(&dsr->h.session_error, buf+36, 2);
527 memcpy(&dsr->h.regular, buf+38, 1);
528 memcpy(&dsr->h.dim_info, buf+39, 1);
529
530 /* dim */
531 if(!same_order) swabip(buf+40, 16);
532 memcpy(dsr->h.dim, buf+40, 16);
533 /* intent parameters */
534 if(!same_order) swawbip(buf+56, 4);
535 memcpy(&dsr->h.intent_p1, buf+56, 4);
536 if(!same_order) swawbip(buf+60, 4);
537 memcpy(&dsr->h.intent_p2, buf+60, 4);
538 if(!same_order) swawbip(buf+64, 4);
539 memcpy(&dsr->h.intent_p3, buf+64, 4);
540 if(!same_order) swabip(buf+68, 2);
541 memcpy(&dsr->h.intent_code, buf+68, 2);
542
543 /* */
544 if(!same_order) swabip(buf+70, 2);
545 memcpy(&dsr->h.datatype, buf+70, 2);
546 if(!same_order) swabip(buf+72, 2);
547 memcpy(&dsr->h.bitpix, buf+72, 2);
548 if(!same_order) swabip(buf+74, 2);
549 memcpy(&dsr->h.slice_start, buf+74, 2);
550 if(!same_order) swawbip(buf+76, 32);
551 memcpy(dsr->h.pixdim, buf+76, 32);
552 if(!same_order) swawbip(buf+108, 4);
553 memcpy(&dsr->h.vox_offset, buf+108, 4);
554 if(!same_order) swawbip(buf+112, 4);
555 memcpy(&dsr->h.scl_slope, buf+112, 4);
556 if(!same_order) swawbip(buf+116, 4);
557 memcpy(&dsr->h.scl_inter, buf+116, 4);
558 if(!same_order) swabip(buf+120, 2);
559 memcpy(&dsr->h.slice_end, buf+120, 2);
560 memcpy(&dsr->h.slice_code, buf+122, 1);
561 memcpy(&dsr->h.xyzt_units, buf+123, 1);
562 if(!same_order) swawbip(buf+124, 4);
563 memcpy(&dsr->h.cal_max, buf+124, 4);
564 if(!same_order) swawbip(buf+128, 4);
565 memcpy(&dsr->h.cal_min, buf+128, 4);
566 if(!same_order) swawbip(buf+132, 4);
567 memcpy(&dsr->h.slice_duration,buf+132,4);
568 if(!same_order) swawbip(buf+136, 4);
569 memcpy(&dsr->h.toffset, buf+136, 4);
570 if(!same_order) swawbip(buf+140, 4);
571 memcpy(&dsr->h.glmax, buf+140, 4);
572 if(!same_order) swawbip(buf+144, 4);
573 memcpy(&dsr->h.glmin, buf+144, 4);
574
575 /* study description */
576 memcpy(&dsr->h.descrip, buf+148, 80);
577 /* Auxiliary filename */
578 memcpy(&dsr->h.aux_file, buf+228, 24);
579
580 /* Transformation parameters */
581 if(!same_order) swabip(buf+252, 2);
582 memcpy(&dsr->h.qform_code, buf+252, 2);
583 if(!same_order) swabip(buf+254, 2);
584 memcpy(&dsr->h.sform_code, buf+254, 2);
585 if(!same_order) swawbip(buf+256, 4);
586 memcpy(&dsr->h.quatern_b, buf+256, 4);
587 if(!same_order) swawbip(buf+260, 4);
588 memcpy(&dsr->h.quatern_c, buf+260, 4);
589 if(!same_order) swawbip(buf+264, 4);
590 memcpy(&dsr->h.quatern_d, buf+264, 4);
591 if(!same_order) swawbip(buf+268, 4);
592 memcpy(&dsr->h.qoffset_x, buf+268, 4);
593 if(!same_order) swawbip(buf+272, 4);
594 memcpy(&dsr->h.qoffset_y, buf+272, 4);
595 if(!same_order) swawbip(buf+276, 4);
596 memcpy(&dsr->h.qoffset_z, buf+276, 4);
597 if(!same_order) swawbip(buf+280, 16);
598 memcpy(dsr->h.srow_x, buf+280, 16);
599 if(!same_order) swawbip(buf+296, 16);
600 memcpy(dsr->h.srow_y, buf+296, 16);
601 if(!same_order) swawbip(buf+312, 16);
602 memcpy(dsr->h.srow_z, buf+312, 16);
603
604 memcpy(&dsr->h.intent_name, buf+328, 16);
605
606 if(status!=NULL) strcpy(status, "complete Nifti header was read");
607 if(verbose>0) fflush(stdout);
608 return(0);
609}
#define NIFTI_HEADER_SIZE
void swabip(void *buf, long long int size)
Definition swap.c:72
void swawbip(void *buf, long long int size)
Definition swap.c:93
int little_endian()
Definition swap.c:14

Referenced by niftiExists(), and niftiReadHeader().

◆ niftiReadImagedata()

int niftiReadImagedata ( FILE * fp,
NIFTI_DSR * dsr,
int frame,
float * data,
int verbose,
char * status )

Read Nifti image data, convert byte order if necessary, and scale values to floats. Reads only one frame at a time!

Returns
Returns 0 if successful, >1 in case of an error, and specifically -1 in case that contents after the last image frame was requested.
See also
niftiReadHeader
Parameters
fpFile pointer to start of image data file, opened previously in binary mode.
dsrPointer to previously filled Nifti header structure
frameFrame number to read [1..number of frames].
dataPointer to image float data allocated previously for dimz*dimy*dimx floats.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed.

Definition at line 734 of file nifti.c.

748 {
749 int dimNr, dimx, dimy, dimz=1, dimt=1;
750 int little;
751 char *mdata, *mptr;
752 float *fptr, ss, si;
753 short int *sptr;
754 int *iptr;
755 double d;
756
757
758 if(verbose>0) {
759 printf("niftiReadImagedata(fp, h, %d, data, %d)\n", frame, verbose);
760 fflush(stdout);
761 }
762 /* Check the arguments */
763 if(status!=NULL) sprintf(status, "invalid function input");
764 if(frame<=0 || fp==NULL || dsr==NULL || data==NULL) return(1);
765
766 /* Get the image data start location from header, in case of single file
767 format */
768 long long start_pos;
769 {
770 long long int s=0;
771 if(strcasecmp(dsr->h.magic, "n+1")==0) s=(int)dsr->h.vox_offset;
772 if(s<0) start_pos=-s; else start_pos=s;
773 }
774 if(verbose>2) printf(" image_start_pos := %llu\n", start_pos);
775 /* edit it later to move to the correct frame */
776
777 /* Get the image dimensions from header */
778 if(status!=NULL) sprintf(status, "invalid image dimensions");
779 dimNr=dsr->h.dim[0]; if(dimNr<2 || dimNr>4) return(2);
780 dimx=dsr->h.dim[1];
781 dimy=dsr->h.dim[2];
782 if(dimNr>2) dimz=dsr->h.dim[3];
783 if(dimNr>3) dimt=dsr->h.dim[4];
784 if(frame>dimt) return(-1);
785 long long pxlNr=dimx*dimy*dimz; if(pxlNr<1) return(4);
786
787 // data_type is unused in Nifti
788 /* Check that datatype is supported */
789 if(verbose>1) printf(" verifying datatype %d\n", dsr->h.datatype);
790 {
791 int n=0;
792 if(dsr->h.datatype & NIFTI_DT_RGB) n+=NIFTI_DT_RGB;
795 if(dsr->h.datatype==NIFTI_DT_UNKNOWN) n+=512;
796 if(n!=0) {
797 if(verbose>0) printf("datatype error %d\n", n);
798 if(status!=NULL) sprintf(status, "unsupported pixel datatype %d", dsr->h.datatype);
799 return(6);
800 }
801 }
802
803 /* Allocate memory for the binary data */
804 if(verbose>1) printf(" allocating memory for binary data\n");
805 if(status!=NULL) sprintf(status, "invalid pixel data format");
806 if(dsr->h.bitpix==0) { // Carimas Nifti Writer does not set bitpix
807 if(dsr->h.datatype==NIFTI_DT_UNSIGNED_SHORT) dsr->h.bitpix=16;
808 }
809 if(dsr->h.bitpix<8) return(5); // We don't support bit data
810 long long rawSize=pxlNr*(dsr->h.bitpix/8); if(rawSize<1) return(6);
811 if(verbose>1) printf(" pxlNr=%lld rawSize=%lld\n", pxlNr, rawSize);
812 if(status!=NULL) sprintf(status, "out of memory");
813 mdata=(char*)malloc(rawSize); if(mdata==NULL) return(11);
814
815 /* Seek the start of current frame data */
816 if(verbose>1) printf(" seeking file position\n");
817 start_pos+=(frame-1)*rawSize;
818 if(verbose>2) printf("start_pos=%lld\n", start_pos);
819 fseeko(fp, start_pos, SEEK_SET);
820 if(ftello(fp)!=start_pos) {
821 if(status!=NULL) sprintf(status, "could not move to start_pos %lld", start_pos);
822 free(mdata); return(7);
823 }
824
825 /* Read the data */
826 if(verbose>1) printf(" reading binary data\n");
827 mptr=mdata;
828 {
829 size_t n=fread(mptr, rawSize, 1, fp);
830 if(n<1) {
831 if(status!=NULL)
832 sprintf(status, "could read only %zu bytes when request was %lld", n, rawSize);
833 free(mdata); return(8);
834 }
835 }
836
837 /* Convert byte order if necessary */
838 little=little_endian(); mptr=mdata;
839 if(little!=dsr->byte_order) {
840 if(verbose>0) printf("byte conversion\n");
841 switch(dsr->h.bitpix) {
842 case 8: /* no conversion needed */ break;
843 case 16: swabip(mptr, rawSize); break;
844 case 32: swawbip(mptr, rawSize); break;
845 case 64: swawbip(mptr, rawSize); break;
846 default:
847 if(verbose>5) printf("unsupported nifti bitpix := %d\n", dsr->h.bitpix);
848 sprintf(status, "unsupported nifti bitpix := %d", dsr->h.bitpix);
849 free(mdata); return(5);
850 }
851 }
852
853 /* Get scaling factors */
854 ss=dsr->h.scl_slope; if(ss==0) ss=1.0;
855 si=dsr->h.scl_inter;
856
857 /* Copy data to float pixel values */
858 if(verbose>1) printf(" conversion to floating point voxel values\n");
859 mptr=mdata;
860 switch(dsr->h.datatype) {
862 if(dsr->h.bitpix!=8) {
863 if(status!=NULL)
864 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
865 dsr->h.datatype, dsr->h.bitpix);
866 free(mdata); return(5);
867 }
868 fptr=data;
869 for(long long i=0; i<pxlNr; i++, mptr++, fptr++)
870 *fptr=si+ss*(float)(*mptr);
871 break;
873 if(dsr->h.bitpix!=16) {
874 if(status!=NULL)
875 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
876 dsr->h.datatype, dsr->h.bitpix);
877 free(mdata); return(5);
878 }
879 fptr=data;
880 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
881 unsigned short int *uptr=(unsigned short int*)mptr; *fptr=si+ss*(float)(*uptr);
882 }
883 break;
885 if(dsr->h.bitpix!=16) {
886 if(status!=NULL)
887 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
888 dsr->h.datatype, dsr->h.bitpix);
889 free(mdata); return(5);
890 }
891 fptr=data;
892 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
893 sptr=(short int*)mptr; *fptr=si+ss*(float)(*sptr);
894 }
895 break;
897 if(dsr->h.bitpix!=16 && dsr->h.bitpix!=32) {
898 if(status!=NULL)
899 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
900 dsr->h.datatype, dsr->h.bitpix);
901 free(mdata); return(5);
902 }
903 fptr=data;
904 if(dsr->h.bitpix==16) {
905 for(long long i=0; i<pxlNr; i++, mptr+=2, fptr++) {
906 iptr=(int*)mptr; *fptr=si+ss*(float)(*iptr);
907 }
908 } else if(dsr->h.bitpix==32) {
909 for(long long i=0; i<pxlNr; i++, mptr+=4, fptr++) {
910 iptr=(int*)mptr; *fptr=si+ss*(float)(*iptr);
911 }
912 }
913 break;
914 case NIFTI_DT_FLOAT: // 16
915 if(dsr->h.bitpix==32) {
916 fptr=data; memcpy(fptr, mptr, pxlNr*4);
917 fptr=data; for(long long i=0; i<pxlNr; i++, fptr++) *fptr*=ss;
918 fptr=data; for(long long i=0; i<pxlNr; i++, fptr++) *fptr+=si;
919 } else {
920 if(status!=NULL)
921 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
922 dsr->h.datatype, dsr->h.bitpix);
923 free(mdata); return(5);
924 }
925 break;
926 case NIFTI_DT_DOUBLE:
927 if(dsr->h.bitpix!=64) {
928 if(status!=NULL)
929 sprintf(status, "invalid combination of datatype and bitpix (%d, %d)",
930 dsr->h.datatype, dsr->h.bitpix);
931 free(mdata); return(5);
932 }
933 fptr=data;
934 for(long long i=0; i<pxlNr; i++, mptr+=8, fptr++) {
935 memcpy(&d, mptr, 8); *fptr=si+ss*d;
936 }
937 break;
938 default:
939 if(status!=NULL)
940 sprintf(status, "unsupported pixel datatype %d", dsr->h.datatype);
941 free(mdata); return(5);
942 }
943
944 if(verbose>1) {printf(" data read successfully.\n"); fflush(stdout);}
945 free(mdata);
946 if(status!=NULL) sprintf(status, "ok");
947 return 0;
948}
#define NIFTI_DT_RGB
#define NIFTI_DT_BINARY
#define NIFTI_DT_FLOAT
#define NIFTI_DT_UNSIGNED_SHORT
#define NIFTI_DT_SIGNED_SHORT
#define NIFTI_DT_SIGNED_INT
#define NIFTI_DT_UNSIGNED_CHAR
#define NIFTI_DT_COMPLEX
#define NIFTI_DT_UNKNOWN
#define NIFTI_DT_DOUBLE

Referenced by imgReadNiftiFrame(), and niftiReadImagedata().

◆ niftiRemove()

int niftiRemove ( const char * dbname,
int fileformat,
int verbose )

Remove header and voxel data files or the single .nii file belonging to specified NIfTI database.

SIF is not deleted in any case. Validity of NIfTI is not verified, therefore this can be used to delete any files with similar name as NIfTI would have.

Returns
Returns 0 when call was successful, otherwise <>0. Call is considered successful, if files do not exist initially.
See also
niftiExists, niftiRemoveFNameExtension
Parameters
dbnameNIfTI database name with path, possibly with filename extension
fileformatNIfTI file format, either IMG_NIFTI_1D (31) or IMG_NIFTI_1S (32), or IMG_UNKNOWN (0) in case both are to be deleted.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 100 of file nifti.c.

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}
int niftiCreateFNames(const char *filename, char *hdrfile, char *imgfile, char *siffile, int fileformat)
Definition nifti.c:44

Referenced by imgWriteNifti(), and niftiRemove().

◆ niftiRemoveFNameExtension()

void niftiRemoveFNameExtension ( char * fname)

Remove any extensions from Nifti file name, leaving only base file name.

See also
niftiCreateFNames, niftiExists, niftiRemove
Parameters
fnameFull name of file.

Definition at line 23 of file nifti.c.

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}

Referenced by imgReadNiftiFrame(), imgReadNiftiHeader(), niftiCreateFNames(), niftiExists(), and niftiRemoveFNameExtension().

◆ niftiWriteHeader()

int niftiWriteHeader ( char * filename,
NIFTI_DSR * dsr,
int verbose,
char * status )

Write NIfTI-1 header contents.

Currently, does not write header extension. Header field 'byte_order' is used to determine the required byte order.

Returns
Returns 0, if successful, otherwise >0.
See also
niftiReadHeader, imgWriteNifti
Parameters
filenameName of file to write (including path and extension).
dsrPointer to previously allocated header structure.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed.

Definition at line 959 of file nifti.c.

969 {
970 FILE *fp;
971 int little; // 1 if current platform is little endian (x86), else 0
972 int same_order;
973 unsigned char buf1[NIFTI_HEADER_SIZE];
974 unsigned char buf2[NIFTI_HEADER_EXTENDER_SIZE];
975 unsigned char *bptr;
976
977
978 if(verbose>0) {
979 printf("\nniftiWriteHeader(%s, ...)\n", filename); fflush(stdout);
980 }
981
982 /* Check arguments */
983 if(status!=NULL) strcpy(status, "invalid function input");
984 if(filename==NULL || strlen(filename)==0 || dsr==NULL) return(1);
985 /* Check magic number */
986 if(strcmp(dsr->h.magic, "ni1")!=0 && strcmp(dsr->h.magic, "n+1")!=0)
987 return(1);
988
989 /* Check if byte swapping is needed */
990 little=little_endian(); if(verbose>3) printf(" little := %d\n", little);
991 if(little==dsr->byte_order) same_order=1; else same_order=0;
992
993 /* Make sure that buffers are all zeroes to begin with */
994 memset(buf1, 0, sizeof(NIFTI_HEADER_SIZE));
995 memset(buf2, 0, sizeof(NIFTI_HEADER_EXTENDER_SIZE));
996
997 /* Copy header contents into buffer */
998 if(verbose>2) printf(" setting write buffer\n");
999 bptr=buf1+0;
1000 memcpy(bptr, &dsr->h.sizeof_hdr, 4); if(!same_order) swawbip(bptr, 4);
1001 bptr=buf1+4;
1002 memcpy(bptr, &dsr->h.data_type, 10);
1003 bptr=buf1+14;
1004 memcpy(bptr, &dsr->h.db_name, 18);
1005 bptr=buf1+32;
1006 memcpy(bptr, &dsr->h.extents, 4); if(!same_order) swawbip(bptr, 4);
1007 bptr=buf1+36;
1008 memcpy(bptr, &dsr->h.session_error, 2); if(!same_order) swabip(bptr, 2);
1009 bptr=buf1+38;
1010 memcpy(bptr, &dsr->h.regular, 1);
1011 bptr=buf1+39;
1012 memcpy(bptr, &dsr->h.dim_info, 1);
1013
1014 bptr=buf1+40;
1015 memcpy(bptr, dsr->h.dim, 16); if(!same_order) swabip(bptr, 16);
1016 bptr=buf1+56;
1017 memcpy(bptr, &dsr->h.intent_p1, 4); if(!same_order) swawbip(bptr, 4);
1018 bptr=buf1+60;
1019 memcpy(bptr, &dsr->h.intent_p2, 4); if(!same_order) swawbip(bptr, 4);
1020 bptr=buf1+64;
1021 memcpy(bptr, &dsr->h.intent_p3, 4); if(!same_order) swawbip(bptr, 4);
1022 bptr=buf1+68;
1023 memcpy(bptr, &dsr->h.intent_code, 2); if(!same_order) swabip(bptr, 2);
1024 bptr=buf1+70;
1025 memcpy(bptr, &dsr->h.datatype, 2); if(!same_order) swabip(bptr, 2);
1026 bptr=buf1+72;
1027 memcpy(bptr, &dsr->h.bitpix, 2); if(!same_order) swabip(bptr, 2);
1028 bptr=buf1+74;
1029 memcpy(bptr, &dsr->h.slice_start, 2); if(!same_order) swabip(bptr, 2);
1030 bptr=buf1+76;
1031 memcpy(bptr, dsr->h.pixdim, 32); if(!same_order) swawbip(bptr, 32);
1032 bptr=buf1+108;
1033 memcpy(bptr, &dsr->h.vox_offset, 4); if(!same_order) swawbip(bptr, 4);
1034 bptr=buf1+112;
1035 memcpy(bptr, &dsr->h.scl_slope, 4); if(!same_order) swawbip(bptr, 4);
1036 bptr=buf1+116;
1037 memcpy(bptr, &dsr->h.scl_inter, 4); if(!same_order) swawbip(bptr, 4);
1038 bptr=buf1+120;
1039 memcpy(bptr, &dsr->h.slice_end, 2); if(!same_order) swabip(bptr, 2);
1040 bptr=buf1+122;
1041 memcpy(bptr, &dsr->h.slice_code, 1);
1042 bptr=buf1+123;
1043 memcpy(bptr, &dsr->h.xyzt_units, 1);
1044 bptr=buf1+124;
1045 memcpy(bptr, &dsr->h.cal_max, 4); if(!same_order) swawbip(bptr, 4);
1046 bptr=buf1+128;
1047 memcpy(bptr, &dsr->h.cal_min, 4); if(!same_order) swawbip(bptr, 4);
1048 bptr=buf1+132;
1049 memcpy(bptr, &dsr->h.slice_duration, 4); if(!same_order) swawbip(bptr, 4);
1050 bptr=buf1+136;
1051 memcpy(bptr, &dsr->h.toffset, 4); if(!same_order) swawbip(bptr, 4);
1052 bptr=buf1+140;
1053 memcpy(bptr, &dsr->h.glmax, 4); if(!same_order) swawbip(bptr, 4);
1054 bptr=buf1+144;
1055 memcpy(bptr, &dsr->h.glmin, 4); if(!same_order) swawbip(bptr, 4);
1056
1057 bptr=buf1+148;
1058 memcpy(bptr, dsr->h.descrip, 80);
1059 bptr=buf1+228;
1060 memcpy(bptr, dsr->h.aux_file, 24);
1061 bptr=buf1+252;
1062 memcpy(bptr, &dsr->h.qform_code, 2); if(!same_order) swabip(bptr, 2);
1063 bptr=buf1+254;
1064 memcpy(bptr, &dsr->h.sform_code, 2); if(!same_order) swabip(bptr, 2);
1065 bptr=buf1+256;
1066 memcpy(bptr, &dsr->h.quatern_b, 4); if(!same_order) swawbip(bptr, 4);
1067 bptr=buf1+260;
1068 memcpy(bptr, &dsr->h.quatern_c, 4); if(!same_order) swawbip(bptr, 4);
1069 bptr=buf1+264;
1070 memcpy(bptr, &dsr->h.quatern_d, 4); if(!same_order) swawbip(bptr, 4);
1071 bptr=buf1+268;
1072 memcpy(bptr, &dsr->h.qoffset_x, 4); if(!same_order) swawbip(bptr, 4);
1073 bptr=buf1+272;
1074 memcpy(bptr, &dsr->h.qoffset_y, 4); if(!same_order) swawbip(bptr, 4);
1075 bptr=buf1+276;
1076 memcpy(bptr, &dsr->h.qoffset_z, 4); if(!same_order) swawbip(bptr, 4);
1077 bptr=buf1+280;
1078 memcpy(bptr, dsr->h.srow_x, 16); if(!same_order) swawbip(bptr, 16);
1079 bptr=buf1+296;
1080 memcpy(bptr, dsr->h.srow_y, 16); if(!same_order) swawbip(bptr, 16);
1081 bptr=buf1+312;
1082 memcpy(bptr, dsr->h.srow_z, 16); if(!same_order) swawbip(bptr, 16);
1083 bptr=buf1+328;
1084 memcpy(bptr, dsr->h.intent_name, 16);
1085 bptr=buf1+344;
1086 memcpy(bptr, dsr->h.magic, 4);
1087
1088 /* Open header file for write; do not delete old contents, since this
1089 function may be called to update single format NIfTI */
1090 if(strcmp(dsr->h.magic, "ni1")==0) { // dual file format
1091 if(verbose>2) printf(" creating NIfTI header %s\n", filename);
1092 fp=fopen(filename, "wb");
1093 } else if(access(filename, 0)==-1) { // single file format, not exists
1094 if(verbose>2) printf(" creating NIfTI header %s\n", filename);
1095 fp=fopen(filename, "wb");
1096 } else { // single file format, exists already
1097 if(verbose>2) printf(" opening NIfTI header %s\n", filename);
1098 fp=fopen(filename, "r+b");
1099 }
1100 if(fp==NULL) {
1101 if(status!=NULL) strcpy(status, "cannot open Nifti header for write");
1102 return(2);
1103 }
1104
1105 /* Write header */
1106 if(verbose>2) printf(" writing NIfTI header\n");
1107 if(fwrite(buf1, 1, NIFTI_HEADER_SIZE, fp) != NIFTI_HEADER_SIZE) {
1108 if(status!=NULL) strcpy(status, "cannot write Nifti header");
1109 fclose(fp); return(3);
1110 }
1111
1112 /* Write extender, if necessary (leave the contents 0 0 0 0 for now) */
1113 if(verbose>2) printf(" writing NIfTI extender\n");
1114 if(fwrite(buf2, 1, NIFTI_HEADER_EXTENDER_SIZE, fp)!= NIFTI_HEADER_EXTENDER_SIZE) {
1115 if(status!=NULL) strcpy(status, "cannot write Nifti header extender");
1116 fclose(fp); return(3);
1117 }
1118
1119 fclose(fp);
1120
1121 if(verbose>2) {printf(" complete Nifti header was written\n"); fflush(stdout);}
1122 if(status!=NULL) strcpy(status, "complete Nifti header was written");
1123 return(0);
1124}
#define NIFTI_HEADER_EXTENDER_SIZE

Referenced by imgWriteNiftiFrame(), and niftiWriteHeader().