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

Process NIfTI and Analyze images with IMG structure. More...

#include "tpcclibConfig.h"
#include "tpcimage.h"

Go to the source code of this file.

Functions

int niftiCreateFNames (const char *filename, char *hdrfile, char *imgfile, char *siffile, int fileformat)
 
int imgReadNifti (IMG *img, const char *fname, TPCSTATUS *status)
 
int imgWriteNifti (IMG *img, const char *fname, TPCSTATUS *status)
 
int imgSetNiftiHeader (IMG *img, NIFTI_DSR *dsr, int verbose)
 
int imgGetNiftiHeader (IMG *img, NIFTI_DSR *dsr, int verbose)
 

Detailed Description

Process NIfTI and Analyze images with IMG structure.

Author
Vesa Oikonen

Definition in file imagenii.c.

Function Documentation

◆ imgGetNiftiHeader()

int imgGetNiftiHeader ( IMG * img,
NIFTI_DSR * dsr,
int verbose )

Copy header information from NIfTI into IMG.

Todo
Add tests.
See also
imgSetNiftiHeader, niftiExists, imgReadNifti
Returns
enum tpcerror (TPCERROR_OK when successful).
Parameters
imgPointer to IMG structure to be filled.
dsrPointer to NIfTI header structure from which information is read.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 794 of file imagenii.c.

801 {
802 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
803
804 /* Check the input */
805 if(dsr==NULL || img==NULL) return(TPCERROR_FAIL);
806 if(dsr->n!=1 && dsr->n!=2) return(TPCERROR_FAIL);
807
808 /* NIfTI file format */
809 if(dsr->n==1) {
810 if(strcmp(dsr->h1.magic, "ni1")==0) img->format=IMG_FORMAT_NIFTI_1D;
811 else if(strcmp(dsr->h1.magic, "n+1")==0) img->format=IMG_FORMAT_NIFTI_1S;
812 else return(TPCERROR_INVALID_FORMAT);
813 } else if (dsr->n==2) {
814 if(strcmp(dsr->h2.magic, "ni2")==0) img->format=IMG_FORMAT_NIFTI_2D;
815 else if(strcmp(dsr->h2.magic, "n+2")==0) img->format=IMG_FORMAT_NIFTI_2S;
816 else return(TPCERROR_INVALID_FORMAT);
817 } else {
818 return(TPCERROR_FAIL);
819 }
820
821 /* Get the image dimensions */
822 int dimNr;
823 if(dsr->n==1) dimNr=dsr->h1.dim[0]; else dimNr=dsr->h2.dim[0];
824 if(dimNr<2 || dimNr>8) return(TPCERROR_INVALID_HEADER);
825 if(dimNr>4) {
826 if(verbose>0) fprintf(stderr, "Error: NIfTI image dimension %d is not supported\n", dimNr);
827 return(TPCERROR_UNSUPPORTED);
828 }
829
830 long long dimx, dimy, dimz=1, dimt=1;
831 if(dsr->n==1) {
832 dimx=dsr->h1.dim[1];
833 dimy=dsr->h1.dim[2];
834 if(dimNr>2) {dimz=dsr->h1.dim[3]; if(dimNr>3) dimt=dsr->h1.dim[4];}
835 } else {
836 dimx=dsr->h2.dim[1];
837 dimy=dsr->h2.dim[2];
838 if(dimNr>2) {dimz=dsr->h2.dim[3]; if(dimNr>3) dimt=dsr->h2.dim[4];}
839 }
840 long long pxlNr=dimx*dimy*dimz;
841 if(pxlNr<1 || dimt<0) {
842 if(verbose>0) fprintf(stderr, "Error: invalid NIfTI image dimensions.\n");
844 }
845 if(dimt==0) dimt=1;
846 img->dimx=dimx; img->dimy=dimy; img->dimz=dimz; img->dimt=dimt;
847
848 /* Pixel x,y,z sizes, converting units if necessary */
849 int xyzt_units=0;
850 if(dsr->n==1) xyzt_units=dsr->h1.xyzt_units; else xyzt_units=dsr->h2.xyzt_units;
851 float f=1.0;
852 if(xyzt_units & NIFTI_UNITS_METER) f=1000.;
853 else if(xyzt_units & NIFTI_UNITS_MICRON) f=0.001;
854 else if(xyzt_units & NIFTI_UNITS_MM) f=1.0;
855 if(verbose>2) printf("pixel size conversion factor := %g\n", f);
856 if(dsr->n==1) {
857 img->sizex=dsr->h1.pixdim[1]; img->sizey=dsr->h1.pixdim[2]; img->sizez=dsr->h1.pixdim[3];
858 } else {
859 img->sizex=dsr->h2.pixdim[1]; img->sizey=dsr->h2.pixdim[2]; img->sizez=dsr->h2.pixdim[3];
860 }
861 img->sizex*=f; img->sizey*=f; img->sizez*=f;
862
863 /* Orientation, quaternion, and transformation parameters */
864 if(dsr->n==1) {
865 img->xform[0]=dsr->h1.qform_code;
866 img->xform[1]=dsr->h1.sform_code;
867 img->quatern[0]=dsr->h1.quatern_b;
868 img->quatern[1]=dsr->h1.quatern_c;
869 img->quatern[2]=dsr->h1.quatern_d;
870 img->quatern[3]=dsr->h1.qoffset_x;
871 img->quatern[4]=dsr->h1.qoffset_y;
872 img->quatern[5]=dsr->h1.qoffset_z;
873 for(int i=0; i<4; i++) img->srow[i]=dsr->h1.srow_x[i];
874 for(int i=0; i<4; i++) img->srow[4+i]=dsr->h1.srow_y[i];
875 for(int i=0; i<4; i++) img->srow[8+i]=dsr->h1.srow_z[i];
876 } else {
877 img->xform[0]=dsr->h2.qform_code;
878 img->xform[1]=dsr->h2.sform_code;
879 img->quatern[0]=dsr->h2.quatern_b;
880 img->quatern[1]=dsr->h2.quatern_c;
881 img->quatern[2]=dsr->h2.quatern_d;
882 img->quatern[3]=dsr->h2.qoffset_x;
883 img->quatern[4]=dsr->h2.qoffset_y;
884 img->quatern[5]=dsr->h2.qoffset_z;
885 for(int i=0; i<4; i++) img->srow[i]=dsr->h2.srow_x[i];
886 for(int i=0; i<4; i++) img->srow[4+i]=dsr->h2.srow_y[i];
887 for(int i=0; i<4; i++) img->srow[8+i]=dsr->h2.srow_z[i];
888 }
889
890 /* Assumptions etc */
892 strcpy(img->studyNr, "");
894 img->cunit=UNIT_UNKNOWN;
895
896 /* Check if unit can be found in description field */
897 char *cptr;
898 if(dsr->n==1) cptr=dsr->h1.descrip; else cptr=dsr->h2.descrip;
899 img->cunit=unitIdentify(cptr);
900
901 return(TPCERROR_OK);
902}
float sizex
Definition tpcimage.h:119
unsigned short int dimx
Definition tpcimage.h:112
unit cunit
Definition tpcimage.h:203
imgformat format
Definition tpcimage.h:103
short int xform[2]
Definition tpcimage.h:133
float quatern[6]
Definition tpcimage.h:135
float srow[12]
Definition tpcimage.h:137
unsigned short int dimt
Definition tpcimage.h:110
float sizey
Definition tpcimage.h:121
imgcontent content
Definition tpcimage.h:97
unsigned short int dimz
Definition tpcimage.h:116
unsigned short int dimy
Definition tpcimage.h:114
decaycorrection decayCorrection
Definition tpcimage.h:91
char studyNr[MAX_STUDYNR_LEN+1]
Definition tpcimage.h:85
float sizez
Definition tpcimage.h:123
float quatern_d
Definition tpcnifti.h:289
float quatern_c
Definition tpcnifti.h:287
short int qform_code
Definition tpcnifti.h:281
float qoffset_x
Definition tpcnifti.h:291
float srow_z[4]
Definition tpcnifti.h:301
float srow_x[4]
Definition tpcnifti.h:297
float pixdim[8]
Definition tpcnifti.h:249
short int sform_code
Definition tpcnifti.h:283
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 qoffset_z
Definition tpcnifti.h:295
short int dim[8]
Definition tpcnifti.h:233
float quatern_b
Definition tpcnifti.h:285
double srow_x[4]
Definition tpcnifti.h:372
char magic[8]
Definition tpcnifti.h:315
int64_t dim[8]
Definition tpcnifti.h:323
double pixdim[8]
Definition tpcnifti.h:331
double qoffset_y
Definition tpcnifti.h:368
double srow_y[4]
Definition tpcnifti.h:374
double quatern_d
Definition tpcnifti.h:364
double qoffset_z
Definition tpcnifti.h:370
double qoffset_x
Definition tpcnifti.h:366
char descrip[80]
Definition tpcnifti.h:351
double quatern_c
Definition tpcnifti.h:362
double srow_z[4]
Definition tpcnifti.h:376
double quatern_b
Definition tpcnifti.h:360
NIFTI_2_HEADER h2
Definition tpcnifti.h:406
NIFTI_1_HEADER h1
Definition tpcnifti.h:404
@ UNIT_UNKNOWN
Unknown unit.
@ TPCERROR_FAIL
General error.
@ TPCERROR_INVALID_FORMAT
Invalid file format.
@ TPCERROR_INVALID_HEADER
Invalid header contents.
@ TPCERROR_UNSUPPORTED
Unsupported file type.
@ TPCERROR_OK
No error.
int unitIdentify(const char *s)
Definition units.c:162
@ IMG_FORMAT_NIFTI_1D
NIfTI-1 dual-file format.
Definition tpcimage.h:42
@ IMG_FORMAT_NIFTI_2S
NIfTI-2 single-file format.
Definition tpcimage.h:45
@ IMG_FORMAT_NIFTI_1S
NIfTI-1 single-file format.
Definition tpcimage.h:43
@ IMG_FORMAT_NIFTI_2D
NIfTI-2 dual-file format.
Definition tpcimage.h:44
@ IMG_CONTENT_IMAGE
Image data.
Definition tpcimage.h:72
@ DECAY_CORRECTED
Data is corrected for physical decay.
Definition tpcisotope.h:81
#define NIFTI_UNITS_METER
Definition tpcnifti.h:46
#define NIFTI_UNITS_MICRON
Definition tpcnifti.h:50
#define NIFTI_UNITS_MM
Definition tpcnifti.h:48

Referenced by imgReadNifti().

◆ imgReadNifti()

int imgReadNifti ( IMG * img,
const char * fname,
TPCSTATUS * status )

Read NIfTI into IMG data structure.

Note
NIfTI may have missing pixel values (NaNs), remove those with imgNaNs(IMG, 1) when necessary.
Todo
Add tests.
See also
imgInit, imgRead, imgWrite, imgFree, imgNaNs, niftiCreateFNames
Returns
enum tpcerror (TPCERROR_OK when successful).
Parameters
imgPointer to image structure. Any previous contents removed.
fnamePointer to the database name. Path alone not accepted.
statusPointer to status data; enter NULL if not needed.

Definition at line 72 of file imagenii.c.

79 {
80 int verbose=0; if(status!=NULL) verbose=status->verbose;
81 if(verbose>0) {printf("%s(..., %s, ...)\n", __func__, fname); fflush(stdout);}
82
83 if(img==NULL || strnlen(fname, 2)<1) {
84 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
85 return(TPCERROR_FAIL);
86 }
87 /* Delete any old contents in data structure */
88 imgFree(img);
89
90 /* Get NIfTI filenames, check existence, and read header */
91 if(verbose>1) printf("checking that %s exists and is NIfTI\n", fname);
92 char hdrfile[FILENAME_MAX], imgfile[FILENAME_MAX], siffile[FILENAME_MAX];
93 NIFTI_DSR dsr;
94 if(!niftiExists(fname, hdrfile, imgfile, siffile, &dsr, status)) {
95 if(status!=NULL) return(status->error);
96 else return(TPCERROR_FAIL);
97 }
98 if(verbose>1) printf("NIfTI header read from %s\n", hdrfile);
99
100 /* Get data type and check that it is currently supported */
101 if(verbose>2) printf(" verifying datatype\n");
102 int datatype=0;
103 if(dsr.n==1) datatype=dsr.h1.datatype; else datatype=dsr.h2.datatype;
104 switch(datatype) {
108 case NIFTI_DT_FLOAT:
109 case NIFTI_DT_DOUBLE:
115 break;
116 case NIFTI_DT_UNKNOWN:
117 case NIFTI_DT_BINARY:
118 case NIFTI_DT_COMPLEX:
119 case NIFTI_DT_RGB:
120 case NIFTI_DT_ALL:
124 case NIFTI_DT_RGBA:
125 default:
126 if(verbose>0) printf("Error: currently unsupported NIfTI datatype %d\n", datatype);
127 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_UNSUPPORTED);
128 return(TPCERROR_UNSUPPORTED);
129 }
130 int bitpix=0;
131 if(dsr.n==1) bitpix=dsr.h1.bitpix; else bitpix=dsr.h2.bitpix;
132 if(verbose>2) printf(" bits per pixel := %d\n", bitpix);
133 if(bitpix==0) { // Carimas Nifti Writer does not set bitpix
134 if(datatype==NIFTI_DT_UNSIGNED_SHORT) bitpix=16;
135 }
136 if(bitpix<8 || (bitpix%8)!=0) { // We don't support bit data
137 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_UNSUPPORTED);
138 return(TPCERROR_UNSUPPORTED);
139 }
140 if(bitpix>64) { // We don't currently support 128 bit data or larger
141 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_UNSUPPORTED);
142 return(TPCERROR_UNSUPPORTED);
143 }
144 int bytepix=bitpix/8; if(verbose>2) printf(" bytes per pixel := %d\n", bytepix);
145
146
147 /* Allocate memory for 4D image */
148 {
149 int ret=imgGetNiftiHeader(img, &dsr, verbose-1); // Get the image dimensions
150 if(ret!=TPCERROR_OK) {
151 statusSet(status, __func__, __FILE__, __LINE__, ret);
152 return(ret);
153 }
154 if(verbose>1) printf("allocating memory for 4D image\n");
155 ret=imgAllocate(img, img->dimz, img->dimy, img->dimx, img->dimt, status);
156 if(ret) return(ret);
157 }
158
159 /* Copy header contents into IMG structure */
160 {
161 int ret=imgGetNiftiHeader(img, &dsr, verbose-1);
162 if(ret!=TPCERROR_OK) {
163 statusSet(status, __func__, __FILE__, __LINE__, ret);
164 return(ret);
165 }
166 if(verbose>2) printf("format: %s\n", imgFormatDescr(img->format));
167 }
168
169 /* Open file */
170 if(verbose>1) printf("reading pixel data in %s\n", imgfile);
171 FILE *fp=fopen(imgfile, "rb");
172 if(fp==NULL) {
173 imgFree(img);
174 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_OPEN);
175 return(TPCERROR_CANNOT_OPEN);
176 }
177
178
179 /* Set initial read position.
180 Get the image data start location from header, in case of single file format */
181 long long start_pos=0;
182 {
183 long long int s=0;
184 if(dsr.n==1) s=(int)dsr.h1.vox_offset; else s=(int)dsr.h2.vox_offset;
185 if(s<0) start_pos=-s; else start_pos=s;
186 /* Check that start location is not earlier than it can by definition; it can be later, though */
189 start_pos=s;
190 }
191 if(verbose>2) printf(" image_start_pos := %llu\n", start_pos);
192 /* Seek the data position, jumping over possible header */
193 if(start_pos>0) {
194 fseeko(fp, start_pos, SEEK_SET);
195 if(ftello(fp)!=start_pos) {
196 fclose(fp); imgFree(img);
197 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
199 }
200 }
201
202 /* Allocate memory for one frame of the binary data */
203 long long pxlNr=img->dimx*img->dimy*img->dimz;
204 if(verbose>2) printf(" pixels/frame := %llu\n", pxlNr);
205 long long rawSize=pxlNr*(bitpix/8);
206 if(verbose>1) printf(" raw bytes per frame := %lld\n", rawSize);
207 if(verbose>1) printf(" allocating memory for raw binary data\n");
208 unsigned char *buf=(unsigned char*)malloc(rawSize);
209 if(buf==NULL) {
210 fclose(fp); imgFree(img);
211 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
213 }
214
215 /* Read the data, frame-by-frame */
216 if(verbose>1) printf(" reading binary data\n");
217 int little=endianLittle(); // Are we on little endian platform?
218 int byteconv=0;
219 if(little!=dsr.byte_order) {
220 byteconv=1;
221 if(verbose>1) printf(" byte conversion needed\n");
222 }
223 /* Get scaling factors */
224 float scl_slope, scl_inter;
225 if(dsr.n==1) {scl_slope=dsr.h1.scl_slope; scl_inter=dsr.h1.scl_inter;}
226 else {scl_slope=dsr.h2.scl_slope; scl_inter=dsr.h2.scl_inter;}
227 if(scl_slope==0.0) scl_slope=1.0;
228
229 for(int ti=0; ti<img->dimt; ti++) {
230 if(verbose>3) printf(" frame %d\n", 1+ti);
231 if(fread(buf, rawSize, 1, fp) < 1) {
232 fclose(fp); imgFree(img); free(buf);
233 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_READ);
234 return(TPCERROR_CANNOT_READ);
235 }
236 /* Convert byte order if necessary */
237 if(byteconv) switch(bitpix) {
238 case 8: /* no conversion needed */ break;
239 case 16: swap16ip(buf, pxlNr); break;
240 case 32: swap32ip(buf, pxlNr); break;
241 case 64: swap64ip(buf, pxlNr); break;
242 default: /* others not supported */ break;
243 }
244 /* Copy data to float pixel values */
245 int ret=0;
246 unsigned char *bptr=buf;
247 switch(datatype) {
250 if(bitpix!=8) {ret=1; break;}
251 for(int zi=0; zi<img->dimz; zi++)
252 for(int yi=0; yi<img->dimy; yi++)
253 for(int xi=0; xi<img->dimx; xi++) {
254 img->m[zi][yi][xi][ti]=scl_inter+scl_slope*(float)(*bptr);
255 bptr++;
256 }
257 break;
259 if(bitpix!=16) {ret=1; break;}
260 for(int zi=0; zi<img->dimz; zi++)
261 for(int yi=0; yi<img->dimy; yi++)
262 for(int xi=0; xi<img->dimx; xi++) {
263 uint16_t a;
264 memcpy(&a, bptr, 2);
265 img->m[zi][yi][xi][ti]=scl_inter+scl_slope*(float)a;
266 bptr+=bytepix;
267 }
268 break;
270 if(bitpix!=16) {ret=1; break;}
271 for(int zi=0; zi<img->dimz; zi++)
272 for(int yi=0; yi<img->dimy; yi++)
273 for(int xi=0; xi<img->dimx; xi++) {
274 int16_t a;
275 memcpy(&a, bptr, 2);
276 img->m[zi][yi][xi][ti]=scl_inter+scl_slope*(float)a;
277 bptr+=bytepix;
278 }
279 break;
281 if(bitpix!=32) {ret=1; break;}
282 for(int zi=0; zi<img->dimz; zi++)
283 for(int yi=0; yi<img->dimy; yi++)
284 for(int xi=0; xi<img->dimx; xi++) {
285 int32_t a;
286 memcpy(&a, bptr, 4);
287 img->m[zi][yi][xi][ti]=scl_inter+scl_slope*(float)a;
288 bptr+=bytepix;
289 }
290 break;
292 if(bitpix!=32) {ret=1; break;}
293 for(int zi=0; zi<img->dimz; zi++)
294 for(int yi=0; yi<img->dimy; yi++)
295 for(int xi=0; xi<img->dimx; xi++) {
296 uint32_t a;
297 memcpy(&a, bptr, 4);
298 img->m[zi][yi][xi][ti]=scl_inter+scl_slope*(float)a;
299 bptr+=bytepix;
300 }
301 break;
303 if(bitpix!=64) {ret=1; break;}
304 for(int zi=0; zi<img->dimz; zi++)
305 for(int yi=0; yi<img->dimy; yi++)
306 for(int xi=0; xi<img->dimx; xi++) {
307 int64_t a;
308 memcpy(&a, bptr, 8);
309 img->m[zi][yi][xi][ti]=scl_inter+scl_slope*(float)a;
310 bptr+=bytepix;
311 }
312 break;
314 if(bitpix!=64) {ret=1; break;}
315 for(int zi=0; zi<img->dimz; zi++)
316 for(int yi=0; yi<img->dimy; yi++)
317 for(int xi=0; xi<img->dimx; xi++) {
318 uint64_t a;
319 memcpy(&a, bptr, 8);
320 img->m[zi][yi][xi][ti]=scl_inter+scl_slope*(float)a;
321 bptr+=bytepix;
322 }
323 break;
324 case NIFTI_DT_FLOAT:
325 if(bitpix!=32) {ret=1; break;}
326 for(int zi=0; zi<img->dimz; zi++)
327 for(int yi=0; yi<img->dimy; yi++)
328 for(int xi=0; xi<img->dimx; xi++) {
329 float a;
330 memcpy(&a, bptr, 4);
331 img->m[zi][yi][xi][ti]=scl_inter+scl_slope*a;
332 bptr+=bytepix;
333 }
334 break;
335 case NIFTI_DT_DOUBLE:
336 if(bitpix!=64) {ret=1; break;}
337 for(int zi=0; zi<img->dimz; zi++)
338 for(int yi=0; yi<img->dimy; yi++)
339 for(int xi=0; xi<img->dimx; xi++) {
340 double a;
341 memcpy(&a, bptr, 8);
342 img->m[zi][yi][xi][ti]=scl_inter+scl_slope*(float)a;
343 bptr+=bytepix;
344 }
345 break;
346 default:
347 ret=2;
348 }
349 if(ret) {
350 fclose(fp); imgFree(img); free(buf);
351 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_UNSUPPORTED);
352 return(TPCERROR_UNSUPPORTED);
353 }
354 } // next frame
355 fclose(fp); free(buf);
356
357
358 /* Read SIF, if available */
359 if(siffile[0]) {
360 if(verbose>0) {printf("reading SIF %s\n", siffile); fflush(stdout);}
361 TAC sif; tacInit(&sif);
362 int ret=tacRead(&sif, siffile, status);
363 if(ret!=TPCERROR_OK) {imgFree(img); return(ret);}
364 ret=imgFromSIF(img, &sif, 1, 1, 0, verbose-1);
365 tacFree(&sif);
366 if(ret!=TPCERROR_OK) {
367 imgFree(img);
368 statusSet(status, __func__, __FILE__, __LINE__, ret);
369 return(ret);
370 }
371 }
372
373 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
374 return(TPCERROR_OK);
375}
void swap32ip(void *buf, unsigned long long size)
Definition endian.c:210
void swap64ip(void *buf, unsigned long long size)
Definition endian.c:184
int endianLittle()
Definition endian.c:53
void swap16ip(void *buf, unsigned long long size)
Definition endian.c:234
void imgFree(IMG *img)
Definition image.c:107
int imgAllocate(IMG *img, const unsigned int dimz, const unsigned int dimy, const unsigned int dimx, const unsigned int dimt, TPCSTATUS *status)
Definition image.c:126
char * imgFormatDescr(imgformat c)
Definition imageio.c:36
int imgGetNiftiHeader(IMG *img, NIFTI_DSR *dsr, int verbose)
Definition imagenii.c:794
int imgFromSIF(IMG *img, TAC *sif, int copy_header, int copy_frames, int copy_counts, int verbose)
Definition imagesif.c:126
int niftiExists(const char *filename, char *hdrfile, char *imgfile, char *siffile, NIFTI_DSR *header, TPCSTATUS *status)
Definition niftiio.c:17
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
float **** m
Definition tpcimage.h:161
short int datatype
Definition tpcnifti.h:243
short int bitpix
Definition tpcnifti.h:245
float vox_offset
Definition tpcnifti.h:251
float scl_inter
Definition tpcnifti.h:255
float scl_slope
Definition tpcnifti.h:253
int64_t vox_offset
Definition tpcnifti.h:333
int16_t datatype
Definition tpcnifti.h:317
double scl_inter
Definition tpcnifti.h:337
double scl_slope
Definition tpcnifti.h:335
int16_t bitpix
Definition tpcnifti.h:319
int byte_order
Definition tpcnifti.h:412
Definition tpctac.h:87
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
void tacFree(TAC *tac)
Definition tac.c:106
void tacInit(TAC *tac)
Definition tac.c:24
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
Definition tacio.c:413
@ TPCERROR_CANNOT_OPEN
Cannot open file.
@ TPCERROR_OUT_OF_MEMORY
Cannot allocate memory.
@ TPCERROR_CANNOT_READ
Cannot read file.
#define NIFTI_DT_LONG_DOUBLE
Definition tpcnifti.h:120
#define NIFTI_DT_RGB
Definition tpcnifti.h:106
#define NIFTI_DT_BINARY
Definition tpcnifti.h:92
#define NIFTI_DT_FLOAT
Definition tpcnifti.h:100
#define NIFTI_DT_UNSIGNED_SHORT
Definition tpcnifti.h:112
#define NIFTI_DT_SIGNED_SHORT
Definition tpcnifti.h:96
#define NIFTI_DT_UNSIGNED_INT
Definition tpcnifti.h:114
#define NIFTI_DT_UNSIGNED_LONG_LONG
Definition tpcnifti.h:118
#define NIFTI_DT_SIGNED_INT
Definition tpcnifti.h:98
#define NIFTI_DT_ALL
Definition tpcnifti.h:108
#define NIFTI_DT_UNSIGNED_CHAR
Definition tpcnifti.h:94
#define NIFTI1_HEADER_SIZE
Definition tpcnifti.h:33
#define NIFTI_DT_COMPLEX
Definition tpcnifti.h:102
#define NIFTI2_HEADER_SIZE
Definition tpcnifti.h:37
#define NIFTI_DT_DOUBLE_PAIR
Definition tpcnifti.h:122
#define NIFTI_DT_RGBA
Definition tpcnifti.h:126
#define NIFTI_DT_UNKNOWN
Definition tpcnifti.h:90
#define NIFTI_DT_SIGNED_CHAR
Definition tpcnifti.h:110
#define NIFTI_DT_LONG_LONG
Definition tpcnifti.h:116
#define NIFTI_DT_DOUBLE
Definition tpcnifti.h:104
#define NIFTI_DT_LONG_DOUBLE_PAIR
Definition tpcnifti.h:124

Referenced by imgRead().

◆ imgSetNiftiHeader()

int imgSetNiftiHeader ( IMG * img,
NIFTI_DSR * dsr,
int verbose )

Copy header information in IMG structure into NIfTI header structure.

Header contents will depend on the output format as specified in IMG->oformat, which can be set to IMG_FORMAT_NIFTI_1D, IMG_FORMAT_NIFTI_1S, IMG_FORMAT_NIFTI_2D, or IMG_FORMAT_NIFTI_2S. NIFTI_DSR->n will tell whether NIfTI-1 or NIfTI-2 header was filled.

Todo
Add tests.
See also
imgGetNiftiHeader, imgWriteNifti, niftiWriteHeader
Returns
enum tpcerror (TPCERROR_OK when successful).
Parameters
imgPointer to IMG structure from which header information is read.
dsrPointer to NIfTI header structure to be filled; any previous contents are removed.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 576 of file imagenii.c.

583 {
584 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
585
586 if(img==NULL || imgHasData(img)==0 || dsr==NULL) return(TPCERROR_FAIL);
587
588 /* Check file format */
589 switch(img->oformat) {
591 dsr->n=1;
592 break;
594 dsr->n=1;
595 break;
597 dsr->n=2;
598 break;
600 dsr->n=2;
601 break;
602 default:
604 }
605
606 /* Find pixel value range */
607 float pmin, pmax;
608 int ret=imgMinMax(img, &pmin, &pmax);
609 if(ret!=TPCERROR_OK) return(ret);
610 if(verbose>1) {printf(" min=%g\n max=%g\n", pmin, pmax); fflush(stdout);}
611
612 /* Set NIfTI byte order to current machines byte order */
614
615 /* Initiate header structures with zeroes */
616 memset(&dsr->h1, 0, sizeof(NIFTI_1_HEADER));
617 memset(&dsr->h2, 0, sizeof(NIFTI_2_HEADER));
618 memset(&dsr->e, 0, sizeof(NIFTI_EXTENDER));
619
620
621 /* Set header */
622 if(dsr->n==1) { // NIfTI-1
623
624 dsr->h1.sizeof_hdr=NIFTI1_HEADER_SIZE; // 348
625 strcpy(dsr->h1.data_type, ""); // not used in NIfTI
626 strcpy(dsr->h1.db_name, ""); // not used in NIfTI
627 dsr->h1.extents=16384; // not used in NIfTI, but required for Analyze compatibility
628 dsr->h1.regular='r'; // not used in NIfTI, but required for Analyze compatibility
629 dsr->h1.dim_info='\0'; // MRI slice ordering
630 if(img->oformat==IMG_FORMAT_NIFTI_1S) {
632 strcpy(dsr->h1.magic, "n+1");
633 } else {
634 dsr->h1.vox_offset=0;
635 strcpy(dsr->h1.magic, "ni1");
636 }
637 strcpy(dsr->h1.aux_file, "");
638
639 /* Image dimension */
640 for(int i=0; i<8; i++) dsr->h1.dim[i]=1;
641 dsr->h1.dim[0]=4;
642 dsr->h1.dim[1]=img->dimx;
643 dsr->h1.dim[2]=img->dimy;
644 dsr->h1.dim[3]=img->dimz;
645 dsr->h1.dim[4]=img->dimt;
646
647 /* Intent */
649 dsr->h1.intent_p1=0.0;
650 dsr->h1.intent_p2=0.0;
651 dsr->h1.intent_p3=0.0;
652 strcpy(dsr->h1.intent_name, "");
653
654 /* Save data as floats, so that there is no need to scale */
656 dsr->h1.bitpix=32; // bits per pixel
657 dsr->h1.scl_slope=1.0; // data as floats, so no need to scale
658 dsr->h1.scl_inter=0.0; // data as floats, so no need to scale
659 dsr->h1.glmax=pmax; // unused in NIfTI
660 dsr->h1.glmin=pmin; // unused in NIfTI
661 dsr->h1.cal_max=pmax;
662 dsr->h1.cal_min=0.0; // scale display colours to have black at zero
663
664 /* Pixel size */
665 dsr->h1.slice_start=0;
666 for(int i=0; i<8; i++) dsr->h1.pixdim[i]=0.0;
667 // https://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/nifti1fields_pages/qsform.html
668 dsr->h1.pixdim[0]=1.0; // Set to either 1.0 or -1.0; default should be 1.0.
669 dsr->h1.pixdim[1]=img->sizex;
670 dsr->h1.pixdim[2]=img->sizey;
671 dsr->h1.pixdim[3]=img->sizez;
672 dsr->h1.slice_end=0;
673 dsr->h1.slice_code=0;
674 dsr->h1.xyzt_units=NIFTI_UNITS_MM; // Voxel size in mm in IMG structure
675 dsr->h1.slice_duration=0.0;
676 dsr->h1.toffset=0.0;
677
678 /* Coordinate system */
679 dsr->h1.qform_code=img->xform[0];
680 dsr->h1.sform_code=img->xform[1];
681 dsr->h1.quatern_b=img->quatern[0];
682 dsr->h1.quatern_c=img->quatern[1];
683 dsr->h1.quatern_d=img->quatern[2];
684 dsr->h1.qoffset_x=img->quatern[3];
685 dsr->h1.qoffset_y=img->quatern[4];
686 dsr->h1.qoffset_z=img->quatern[5];
687
688 /* Save pixel units into description (not standard NIfTI) */
689 if(img->cunit==UNIT_UNKNOWN) strcpy(dsr->h1.descrip, "");
690 else strlcpy(dsr->h1.descrip, unitName(img->cunit), 80);
691
692 for(int i=0; i<4; i++) dsr->h1.srow_x[i]=img->srow[i];
693 for(int i=0; i<4; i++) dsr->h1.srow_y[i]=img->srow[4+i];
694 for(int i=0; i<4; i++) dsr->h1.srow_z[i]=img->srow[8+i];
695
696 /* Extension is left as 0 0 0 0 */
697
698 } else { // NIfTI-2
699
700 /* Header size. Used for identifying the format and endianness of data */
701 dsr->h2.sizeof_hdr=NIFTI2_HEADER_SIZE; // 540
702
703 /* Magic string. Used for identifying the format and verifying validity */
704 if(img->oformat==IMG_FORMAT_NIFTI_2S) strcpy(dsr->h2.magic, "n+2");
705 else strcpy(dsr->h2.magic, "ni2");
706 dsr->h2.magic[3]='\0';
707 dsr->h2.magic[4]='\r';
708 dsr->h2.magic[5]='\n';
709 dsr->h2.magic[6]=(char)32;
710 dsr->h2.magic[7]='\n';
711
712 /* Save data as 32-bit floats, so that there is no need to scale */
714 dsr->h2.bitpix=32; // bits per pixel
715
716 /* Image dimensions */
717 for(int i=0; i<8; i++) dsr->h2.dim[i]=1;
718 dsr->h2.dim[0]=4;
719 dsr->h2.dim[1]=img->dimx;
720 dsr->h2.dim[2]=img->dimy;
721 dsr->h2.dim[3]=img->dimz;
722 dsr->h2.dim[4]=img->dimt;
723
724 /* Intent */
726 dsr->h2.intent_p1=0.0;
727 dsr->h2.intent_p2=0.0;
728 dsr->h2.intent_p3=0.0;
729 strcpy(dsr->h2.intent_name, "");
730
731 /* Grid spacings */
732 dsr->h2.pixdim[0]=1.0; // Set to either 1.0 or -1.0; default should be 1.0.
733 dsr->h2.pixdim[1]=img->sizex;
734 dsr->h2.pixdim[2]=img->sizey;
735 dsr->h2.pixdim[3]=img->sizez;
736 for(int i=4; i<8; i++) dsr->h2.pixdim[i]=0.0;
737
738 /* Offset into pixel data; zero for dual file */
739 if(img->oformat==IMG_FORMAT_NIFTI_2S) {
741 } else {
742 dsr->h2.vox_offset=0;
743 }
744
745 /* Scaling */
746 dsr->h2.scl_slope=1.0; // data as floats, so no need to scale
747 dsr->h2.scl_inter=0.0; // data as floats, so no need to scale
748 dsr->h2.cal_max=pmax;
749 dsr->h2.cal_min=0.0; // scale display colours to have black at zero
750
751 dsr->h2.slice_duration=0.0;
752 dsr->h2.toffset=0.0;
753 dsr->h2.slice_start=0;
754 dsr->h2.slice_end=img->dimz-1;
755
756 /* Save pixel units into description (not standard NIfTI) */
757 if(img->cunit==UNIT_UNKNOWN) strcpy(dsr->h2.descrip, "");
758 else strlcpy(dsr->h2.descrip, unitName(img->cunit), 80);
759
760 strcpy(dsr->h2.aux_file, "");
761
762 /* Coordinate system */
763 dsr->h2.qform_code=img->xform[0];
764 dsr->h2.sform_code=img->xform[1];
765 dsr->h2.quatern_b=img->quatern[0];
766 dsr->h2.quatern_c=img->quatern[1];
767 dsr->h2.quatern_d=img->quatern[2];
768 dsr->h2.qoffset_x=img->quatern[3];
769 dsr->h2.qoffset_y=img->quatern[4];
770 dsr->h2.qoffset_z=img->quatern[5];
771 for(int i=0; i<4; i++) dsr->h2.srow_x[i]=img->srow[i];
772 for(int i=0; i<4; i++) dsr->h2.srow_y[i]=img->srow[4+i];
773 for(int i=0; i<4; i++) dsr->h2.srow_z[i]=img->srow[8+i];
774
775 dsr->h2.slice_code=0;
777 dsr->h2.dim_info='\0'; // MRI slice ordering
778
779 /* Extension is left as 0 0 0 0 */
780
781 }
782
783 return(TPCERROR_OK);
784}
int imgHasData(IMG *img)
Definition image.c:218
int imgMinMax(IMG *img, float *minvalue, float *maxvalue)
Definition image.c:396
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
imgformat oformat
Definition tpcimage.h:105
char db_name[18]
Definition tpcnifti.h:220
short int slice_start
Definition tpcnifti.h:247
short int slice_end
Definition tpcnifti.h:257
float slice_duration
Definition tpcnifti.h:267
float intent_p2
Definition tpcnifti.h:237
char aux_file[24]
Definition tpcnifti.h:278
float intent_p1
Definition tpcnifti.h:235
char intent_name[16]
Definition tpcnifti.h:303
float intent_p3
Definition tpcnifti.h:239
char data_type[10]
Definition tpcnifti.h:218
short int intent_code
Definition tpcnifti.h:241
char aux_file[24]
Definition tpcnifti.h:353
double slice_duration
Definition tpcnifti.h:343
double cal_min
Definition tpcnifti.h:341
double intent_p2
Definition tpcnifti.h:327
int64_t slice_start
Definition tpcnifti.h:347
double intent_p3
Definition tpcnifti.h:329
int64_t slice_end
Definition tpcnifti.h:349
double intent_p1
Definition tpcnifti.h:325
double toffset
Definition tpcnifti.h:345
double cal_max
Definition tpcnifti.h:339
char intent_name[16]
Definition tpcnifti.h:384
NIFTI_EXTENDER e
Definition tpcnifti.h:408
char * unitName(int unit_code)
Definition units.c:143
#define NIFTI1_HEADER_EXTENDER_SIZE
Definition tpcnifti.h:35
#define NIFTI2_HEADER_EXTENDER_SIZE
Definition tpcnifti.h:39
#define NIFTI_INTENT_NONE
Definition tpcnifti.h:129
#define NIFTI_UNITS_SEC
Definition tpcnifti.h:52

Referenced by imgWriteNifti().

◆ imgWriteNifti()

int imgWriteNifti ( IMG * img,
const char * fname,
TPCSTATUS * status )

Write NIfTI from IMG data structure.

IMG field oformat (or secondarily format) determines whether NIfTI is written in single file format (*.nii) or dual file format (*.hdr and *.img).

SIF file is saved to store frame times, if frame times are available.

Todo
Add tests.
See also
imgInit, imgRead, imgWrite, imgFree, niftiCreateFNames, niftiWriteHeader
Returns
enum tpcerror (TPCERROR_OK when successful).
Parameters
imgPointer to image structure. Any previous contents removed.
fnamePointer to the database name. Path not accepted.
statusPointer to status data; enter NULL if not needed.

Definition at line 390 of file imagenii.c.

397 {
398 int verbose=0; if(status!=NULL) verbose=status->verbose;
399 if(verbose>0) {printf("%s(..., %s, ...)\n", __func__, fname); fflush(stdout);}
400
401 if(img==NULL || strnlen(fname, 2)<1) {
402 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
403 return(TPCERROR_FAIL);
404 }
405 if(!imgHasData(img)) {
406 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
407 return(TPCERROR_NO_DATA);
408 }
409
410 /* Determine the output format */
411 if(verbose>1) {printf("determine output format\n"); fflush(stdout);}
412 if(img->oformat==IMG_FORMAT_UNKNOWN) {
413 char *cptr=filenameGetExtension(fname);
414 if(cptr!=NULL && strcasecmp(cptr, ".nii")==0) img->oformat=IMG_FORMAT_NIFTI_1S;
415 else img->oformat=img->format;
416 }
420
421 /* Get database name, in case file name was given with extension */
422 if(verbose>1) {printf("get dbname\n"); fflush(stdout);}
423 char basename[FILENAME_MAX];
424 strlcpy(basename, fname, FILENAME_MAX); niftiBasename(basename);
425 /* Check that there is something left after path */
426 char basenamewopath[FILENAME_MAX];
427 strcpy(basenamewopath, basename); filenameRmPath(basenamewopath);
428 if(strlen(basenamewopath)<1) {
429 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FILENAME);
431 }
432 /* Create output file names (now to catch some errors) */
433 if(verbose>1) {printf("determine output file names\n"); fflush(stdout);}
434 char hdrfile[FILENAME_MAX], imgfile[FILENAME_MAX], siffile[FILENAME_MAX];
435 hdrfile[0]=imgfile[0]=siffile[0]=(char)0;
436 if(niftiCreateFNames(basename, hdrfile, imgfile, siffile, img->oformat)!=TPCERROR_OK) {
437 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FILENAME);
439 }
440 /* If we have path, then create it */
441 char filepath[FILENAME_MAX];
442 strcpy(filepath, basename); filenameRmFile(filepath);
443 if(pathCreate(filepath)) {
444 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FILENAME);
446 }
447
448
449 /* Fill the header structure */
450 NIFTI_DSR dsr;
451 int ret=imgSetNiftiHeader(img, &dsr, verbose-1);
452 if(ret!=TPCERROR_OK) {
453 statusSet(status, __func__, __FILE__, __LINE__, ret);
454 return(ret);
455 }
456
457 /* Delete previous NIfTI */
458 if(verbose>1) {printf("removing any previous files\n"); fflush(stdout);}
459 if(fileExist(hdrfile)) remove(hdrfile);
460 if(fileExist(imgfile)) remove(imgfile);
461 //if(fileExist(siffile)) remove(siffile); // NO, not this!
462
463 /* Write the header */
464 if(verbose>1) {printf("writing the header\n"); fflush(stdout);}
466 ret=niftiWriteHeader(hdrfile, &dsr, verbose-1);
467 } else if(img->oformat==IMG_FORMAT_NIFTI_1S || img->oformat==IMG_FORMAT_NIFTI_2S) {
468 ret=niftiWriteHeader(imgfile, &dsr, verbose-1);
469 }
470 if(ret!=TPCERROR_OK) {
471 statusSet(status, __func__, __FILE__, __LINE__, ret);
472 return(ret);
473 }
474 /* Write the pixel data */
475 if(verbose>1) {printf("opening file for pixel data\n"); fflush(stdout);}
476 FILE *fp;
478 fp=fopen(imgfile, "wb");
479 } else { // if(img->oformat==IMG_FORMAT_NIFTI_1S || if(img->oformat==IMG_FORMAT_NIFTI_2S
480 fp=fopen(imgfile, "r+b");
481 }
482 if(fp==NULL) {
483 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_OPEN);
484 return(TPCERROR_CANNOT_OPEN);
485 }
486 /* Move pointer to the start of pixel data */
487 long int pos;
488 if(dsr.n==1) pos=(int)dsr.h1.vox_offset; else pos=(int)dsr.h2.vox_offset;
489 if(fseek(fp, pos, SEEK_SET)!=0) {
490 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
491 fclose(fp); return(TPCERROR_CANNOT_WRITE);
492 }
493 /* Allocate memory for pixel matrix */
494 unsigned long long voxNr=img->dimt*img->dimz*img->dimy*img->dimx;
495 float *fdata;
496 fdata=(float*)calloc(voxNr, sizeof(float));
497 if(fdata==NULL) {
498 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
499 fclose(fp); return(TPCERROR_OUT_OF_MEMORY);
500 }
501 /* Write voxel values as floats */
502 float *fptr=fdata;
503 for(unsigned int fi=0; fi<img->dimt; fi++)
504 for(unsigned int zi=0; zi<img->dimz; zi++)
505 for(unsigned int yi=0; yi<img->dimy; yi++)
506 for(unsigned int xi=0; xi<img->dimx; xi++, fptr++)
507 *fptr=img->m[zi][yi][xi][fi];
508 if(verbose>1) {printf("writing pixel data\n"); fflush(stdout);}
509 fptr=fdata;
510 if(fwrite(fptr, sizeof(float), voxNr, fp) != voxNr) {
511 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
512 free(fdata); fclose(fp); return(TPCERROR_CANNOT_WRITE);
513 }
514
515 free(fdata);
516 fclose(fp);
517
518 /* Frame times into SIF */
519 if(!imgHasTimes(img)) { // no frame times to save
520 if(verbose>1) printf(" no frame times to save into SIF\n");
521 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
522 return(TPCERROR_OK);
523 }
524 {
525 if(verbose>1) {printf("making SIF\n"); fflush(stdout);}
526 TAC sif; tacInit(&sif);
527 /* Try to read existing SIF */
528 if(fileExist(siffile) && tacRead(&sif, siffile, status)==TPCERROR_OK && sif.sampleNr==img->dimt)
529 {
530 /* If SIF was found and frameNr matches with image, then update the SIF contents,
531 but keep counts, in case previous SIF comes with actual count info from scanner */
532 ret=imgToSIF(img, &sif, 1, 1, 0, verbose-3);
533 } else {
534 /* otherwise create SIF contents */
535 ret=imgToSIF(img, &sif, 1, 1, 2, verbose-3);
536 }
537 if(ret!=TPCERROR_OK) {
538 if(verbose>0) fprintf(stderr, " Error: cannot create SIF contents.\n");
539 tacFree(&sif);
540 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_X);
541 return(TPCERROR_INVALID_X);
542 }
543 if(verbose>1) {printf("writing SIF\n"); fflush(stdout);}
544 fp=fopen(siffile, "w");
545 if(fp==NULL) {
546 tacFree(&sif);
547 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_OPEN);
548 return(TPCERROR_CANNOT_OPEN);
549 }
550 ret=tacWrite(&sif, fp, TAC_FORMAT_SIF, 0, status);
551 fclose(fp); tacFree(&sif);
552 if(ret!=TPCERROR_OK) {
553 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
554 return(TPCERROR_CANNOT_WRITE);
555 }
556 }
557
558
559 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
560 return(TPCERROR_OK);
561}
void filenameRmFile(char *s)
Definition filename.c:44
char * filenameGetExtension(const char *s)
Get the last extension of a file name.
Definition filename.c:178
void filenameRmPath(char *s)
Definition filename.c:20
int fileExist(const char *filename)
Definition filexist.c:17
int imgHasTimes(IMG *img)
Definition image.c:235
int imgSetNiftiHeader(IMG *img, NIFTI_DSR *dsr, int verbose)
Definition imagenii.c:576
int niftiCreateFNames(const char *filename, char *hdrfile, char *imgfile, char *siffile, int fileformat)
Definition imagenii.c:17
int imgToSIF(IMG *img, TAC *sif, int copy_header, int copy_frames, int copy_counts, int verbose)
Definition imagesif.c:18
int niftiWriteHeader(const char *filename, NIFTI_DSR *dsr, int verbose)
Definition niftiio.c:445
void niftiBasename(char *filename)
Definition niftiname.c:14
int pathCreate(const char *pathname)
Definition pathexist.c:81
int sampleNr
Definition tpctac.h:89
int tacWrite(TAC *tac, FILE *fp, tacformat format, int extra, TPCSTATUS *status)
Definition tacio.c:332
@ TPCERROR_INVALID_X
Invalid sample time.
@ TPCERROR_INVALID_FILENAME
Invalid file name.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
@ IMG_FORMAT_UNKNOWN
Unknown format.
Definition tpcimage.h:33
@ TAC_FORMAT_SIF
Scan information file.
Definition tpctac.h:43

Referenced by imgWrite().

◆ niftiCreateFNames()

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

Construct the file names for NIfTI image.

See also
imgReadNifti, imgWriteNifti, niftiRemoveFNameExtension
Returns
enum tpcerror (TPCERROR_OK when successful).
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); in single file format this will be set to the name of the single file; enter NULL if not needed.
imgfileImage filename will be written in this char pointer (space needs to allocated by caller); in single file format this will be set to the name of the single 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_FORMAT_NIFTI_1D, IMG_FORMAT_NIFTI_1S, IMG_NIFTI_FORMAT_2D, or IMG_FORMAT_NIFTI_2S.

Definition at line 17 of file imagenii.c.

35 {
36 if(hdrfile!=NULL) strcpy(hdrfile, "");
37 if(imgfile!=NULL) strcpy(imgfile, "");
38 if(siffile!=NULL) strcpy(siffile, "");
39 if(filename==NULL) return(TPCERROR_INVALID_FILENAME);
40
41 char basename[FILENAME_MAX];
42 strlcpy(basename, filename, FILENAME_MAX); niftiBasename(basename);
43 /* Check that there is something left after path */
44 char basenamewopath[FILENAME_MAX];
45 strcpy(basenamewopath, basename); filenameRmPath(basenamewopath);
46 if(strlen(basenamewopath)<1) return(TPCERROR_INVALID_FILENAME);
47
48 /* Create database filenames */
49 if(fileformat==IMG_FORMAT_NIFTI_1D || fileformat==IMG_FORMAT_NIFTI_2D) {
50 if(hdrfile!=NULL) snprintf(hdrfile, FILENAME_MAX, "%s.hdr", basename);
51 if(imgfile!=NULL) snprintf(imgfile, FILENAME_MAX, "%s.img", basename);
52 } else if(fileformat==IMG_FORMAT_NIFTI_1S || fileformat==IMG_FORMAT_NIFTI_2S) {
53 if(hdrfile!=NULL) snprintf(hdrfile, FILENAME_MAX, "%s.nii", basename);
54 if(imgfile!=NULL) snprintf(imgfile, FILENAME_MAX, "%s.nii", basename);
55 } else {
57 }
58 if(siffile!=NULL) snprintf(siffile, FILENAME_MAX, "%s.sif", basename);
59
60 return(TPCERROR_OK);
61}

Referenced by imgWriteNifti().