8#include "tpcclibConfig.h"
24static char *info[] = {
25 "Check if NIfTI image has missing pixel values.",
26 "Optionally, set missing pixel values to zero.",
28 "Usage: @P niftifile",
32 " Set missing pixel values to zero.",
35 "See also: tacdelna, nii_lhdr, nii_ehdr, imgmax, tac2nii",
37 "Keywords: image, NIfTI, tool",
56int main(
int argc,
char **argv)
58 int ai, help=0, version=0, verbose=1;
59 char fname[FILENAME_MAX];
65 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
68 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
70 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
71 if(strcasecmp(cptr,
"FIX")==0) {
74 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
79 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
84 if(ai<argc)
strlcpy(fname, argv[ai++], FILENAME_MAX);
85 if(ai<argc) {fprintf(stderr,
"Error: too many arguments: '%s'.\n", argv[ai]);
return(1);}
87 if(!fname[0]) {
tpcPrintUsage(argv[0], info, stdout);
return(1);}
91 printf(
"fname := %s\n", fname);
92 printf(
"mode := %d\n", mode);
102 if(verbose>1) printf(
" checking that %s exists and is NIfTI\n", fname);
103 char hdrfile[FILENAME_MAX], imgfile[FILENAME_MAX], siffile[FILENAME_MAX];
105 if(!
niftiExists(fname, hdrfile, imgfile, siffile, &dsr, &status)) {
106 fprintf(stderr,
"Error: cannot read %s\n", fname);
109 if(verbose>1) printf(
" NIfTI header read from %s\n", hdrfile);
112 if(verbose>2) printf(
" verifying datatype\n");
117 if(verbose>2) printf(
" bits per pixel := %d\n", bitpix);
119 fprintf(stderr,
"Error: currently unsupported NIfTI datatype.\n");
122 int bytepix=bitpix/8;
123 if(verbose>2) printf(
" bytes per pixel := %d\n", bytepix);
127 if(dsr.
n==1) dimNr=dsr.
h1.
dim[0];
else dimNr=dsr.
h2.
dim[0];
128 if(dimNr<2 || dimNr>4) {
129 fprintf(stderr,
"Error: currently unsupported NIfTI dimensions.\n");
132 long long dimx, dimy, dimz=1, dimt=1;
135 if(dimNr>2) {dimz=dsr.
h1.
dim[3];
if(dimNr>3) dimt=dsr.
h1.
dim[4];}
138 if(dimNr>2) {dimz=dsr.
h2.
dim[3];
if(dimNr>3) dimt=dsr.
h2.
dim[4];}
140 long long pxlNr=dimx*dimy*dimz;
141 if(pxlNr<1 || dimt<0) {
142 fprintf(stderr,
"Error: invalid NIfTI dimensions.\n");
147 printf(
" image_dim := %llu x %llu x %llu\n", dimx, dimy, dimz);
148 printf(
" frames := %llu\n", dimt);
153 if(verbose>1) printf(
" reading pixel data in %s\n", imgfile);
154 FILE *fp=fopen(imgfile,
"r+b");
156 fprintf(stderr,
"Error: cannot open %s\n", imgfile);
163 long long start_pos=0;
167 if(s<0) start_pos=-s;
else start_pos=s;
169 if(verbose>2) printf(
" image_start_pos := %llu\n", start_pos);
172 fseeko(fp, start_pos, SEEK_SET);
173 if(ftello(fp)!=start_pos) {
174 fprintf(stderr,
"Error: invalid NIfTI format.\n");
175 fclose(fp);
return(3);
180 if(verbose>2) printf(
" pixels/frame := %llu\n", pxlNr);
181 long long rawSize=pxlNr*(bitpix/8);
182 if(verbose>1) printf(
" raw bytes per frame := %lld\n", rawSize);
183 if(verbose>1) printf(
" allocating memory for raw binary data\n");
184 unsigned char *buf=(
unsigned char*)malloc(rawSize);
186 fprintf(stderr,
"Error: cannot allocate memory.\n");
187 fclose(fp);
return(3);
192 if(verbose>1) printf(
" reading binary data\n");
197 if(verbose>1) printf(
" byte conversion needed\n");
201 float scl_slope, scl_inter;
204 if(!isfinite(scl_slope) || !isfinite(scl_inter)) {
206 fprintf(stderr,
"Error: missing scaling factors.\n");
207 fclose(fp); free(buf);
return(4);
209 if(!isfinite(scl_slope)) scl_slope=1.0;
210 if(!isfinite(scl_inter)) scl_inter=0.0;
212 if(scl_slope==0.0) scl_slope=1.0;
215 for(
int ti=0; ti<dimt; ti++) {
216 if(verbose>3) printf(
" frame %d\n", 1+ti);
217 if(fread(buf, rawSize, 1, fp) < 1) {
218 fprintf(stderr,
"Error: cannot read image frame %d.\n", 1+ti);
219 fclose(fp); free(buf);
return(4);
225 long long frameNaNr=0;
226 unsigned char *bptr=buf;
227 for(
int zi=0; zi<dimz; zi++) {
228 for(
int yi=0; yi<dimy; yi++) {
229 for(
int xi=0; xi<dimx; xi++) {
234 if(mode!=0) {a=0.0; memcpy(bptr, &a, 4);}
240 if(frameNaNr==0)
continue;
242 if(verbose>1) printf(
" %llu missing pixel(s) in frame %d\n", frameNaNr, 1+ti);
243 if(mode==0)
continue;
248 fseeko(fp, -pxlNr*bytepix, SEEK_CUR);
249 if(fwrite(buf, rawSize, 1, fp) < 1) {
250 fprintf(stderr,
"Error: cannot write image frame %d.\n", 1+ti);
251 fclose(fp); free(buf);
return(11);
254 fclose(fp); free(buf);
256 if(mode==0 || verbose>0) {
257 printf(
"missing_pixel_values := %llu\n", NaNr);
void swap32ip(void *buf, unsigned long long size)
int niftiExists(const char *filename, char *hdrfile, char *imgfile, char *siffile, NIFTI_DSR *header, TPCSTATUS *status)
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
void statusInit(TPCSTATUS *s)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
int verbose
Verbose level, used by statusPrint() etc.
Header file for library libtpcextensions.
Header file for libtpcimage.