TPCCLIB
Loading...
Searching...
No Matches
imgdelfr.c
Go to the documentation of this file.
1
7/*****************************************************************************/
8#include "tpcclibConfig.h"
9/*****************************************************************************/
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include <string.h>
14#include <math.h>
15#include <time.h>
16/*****************************************************************************/
17#include "libtpcmisc.h"
18#include "libtpcmodel.h"
19#include "libtpccurveio.h"
20#include "libtpcimgio.h"
21#include "libtpcimgp.h"
22/*****************************************************************************/
23
24/*****************************************************************************/
25static char *info[] = {
26 "Delete specified frames from PET image in ECAT 6.3, 7.x, NIfTI-1, or",
27 "Analyze 7.5 format.",
28 "Analyze and NIfTI image must have the SIF in the same folder.",
29 " ",
30 "Usage: @P [Options] image startframe endframe newimage",
31 " ",
32 "Options:",
33 " -zero",
34 " Frames are not actually deleted, but pixel values are set to zero.",
35 " -sec",
36 " Start and end times (in sec) are given instead of frame numbers.",
37 " -min",
38 " Start and end times (in min) are given instead of frame numbers.",
39 " -stdoptions", // List standard options like --help, -v, etc
40 " ",
41 "See also: esplit, ecatcat, eframe, ecattime, imgbox, imgdelpl, imgdim",
42 " ",
43 "Keywords: image, cropping, compression, time",
44 0};
45/*****************************************************************************/
46
47/*****************************************************************************/
48/* Turn on the globbing of the command line, since it is disabled by default in
49 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
50 In Unix&Linux wildcard command line processing is enabled by default. */
51/*
52#undef _CRT_glob
53#define _CRT_glob -1
54*/
55int _dowildcard = -1;
56/*****************************************************************************/
57
58/*****************************************************************************/
62int main(int argc, char **argv)
63{
64 int ai, help=0, version=0, verbose=1;
65 int doCrop=1; // 0=zeroes; 1=crop
66 int times=-1; // -1=frames; 0=sec, 1=min
67 char petfile[FILENAME_MAX], outfile[FILENAME_MAX];
68 int ret;
69 int fstart, fstop;
70 double tstart, tstop;
71
72
73
74 /*
75 * Get arguments
76 */
77 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
78 petfile[0]=outfile[0]=(char)0;
79 /* Get options */
80 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
81 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
82 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
83 if(strcasecmp(cptr, "CROP")==0) {
84 doCrop=1; continue;
85 } else if(strcasecmp(cptr, "ZERO")==0) {
86 doCrop=0; continue;
87 } else if(strncasecmp(cptr, "SECONDS", 3)==0) {
88 times=0; continue;
89 } else if(strncasecmp(cptr, "MINUTES", 3)==0) {
90 times=1; continue;
91 }
92 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
93 return(1);
94 } else break;
95
96 /* Print help or version? */
97 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
98 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
99 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
100
101 /* Process other arguments, starting from the first non-option */
102 if(ai<argc) {strlcpy(petfile, argv[ai++], FILENAME_MAX);}
103 if(ai<argc) {
104 if(times<0) ret=atoi_with_check(argv[ai], &fstart);
105 else if(times==0) ret=atof_with_check(argv[ai], &tstart);
106 else {ret=atof_with_check(argv[ai], &tstart); tstart*=60.0;}
107 if(ret!=0) {fprintf(stderr, "Error: invalid cut start '%s'.\n", argv[ai]); return(1);}
108 ai++;
109 }
110 if(ai<argc) {
111 if(times<0) ret=atoi_with_check(argv[ai], &fstop);
112 else if(times==0) ret=atof_with_check(argv[ai], &tstop);
113 else {ret=atof_with_check(argv[ai], &tstop); tstop*=60.0; times=0;}
114 if(ret!=0) {fprintf(stderr, "Error: invalid cut stop '%s'.\n", argv[ai]); return(1);}
115 ai++;
116 }
117 if(ai<argc) {strlcpy(outfile, argv[ai++], FILENAME_MAX);}
118 if(ai<argc) {
119 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
120 return(1);
121 }
122
123 /* Did we get all the information that we need? */
124 if(!outfile[0]) {
125 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
126 return(1);
127 }
128 if(times<0 && fstart>fstop) {
129 fprintf(stderr, "Error: invalid frame number range.\n");
130 return(1);
131 }
132 if(times>=0 && tstart>=tstop) {
133 fprintf(stderr, "Error: invalid frame time range.\n");
134 return(1);
135 }
136 if(strcasecmp(outfile, petfile)==0) {
137 fprintf(stderr, "Error: check the output filename.\n");
138 return(1);
139 }
140
141
142 /* In verbose mode print arguments and options */
143 if(verbose>1) {
144 printf("petfile := %s\n", petfile);
145 printf("outfile := %s\n", outfile);
146 printf("doCrop := %d\n", doCrop);
147 if(times<0) {
148 printf("cut_start_frame := %d\n", fstart);
149 printf("cut_stop_frame := %d\n", fstop);
150 } else {
151 printf("cut_start_time_in_sec := %g\n", tstart);
152 printf("cut_stop_time_in_sec := %g\n", tstop);
153 }
154 }
155 if(verbose>9) IMG_TEST=verbose-9; else IMG_TEST=0;
156
157
158 /*
159 * Read image
160 */
161 if(verbose>0) fprintf(stdout, "reading image %s\n", petfile);
162 IMG img; imgInit(&img);
163 ret=imgRead(petfile, &img);
164 if(ret) {
165 fprintf(stderr, "Error: %s\n", img.statmsg); if(verbose>1) imgInfo(&img);
166 return(2);
167 }
168
169 /* Check that frame times are available, if frame time range was given */
170 if(times>=0 && !imgExistentTimes(&img)) {
171 fprintf(stderr, "Error: image does not contain frame times.\n");
172 imgEmpty(&img); return(2);
173 }
174
175 /* If frame time range was given, get frame number range */
176 if(times>=0) {
177 if(verbose>1) printf("PET time range: %g - %g s\n", img.start[0], img.end[img.dimt-1]);
178 fstart=fstop=-1;
179 for(int fi=0; fi<img.dimt; fi++) if(img.mid[fi]>=tstart) {fstart=fi; break;}
180 for(int fi=img.dimt-1; fi>=0; fi--) if(img.mid[fi]<=tstop) {fstop=fi; break;}
181 if(fstart<0 || fstop<0) {
182 fprintf(stderr, "Error: invalid time range.\n");
183 imgEmpty(&img); return(2);
184 }
185 if(verbose>1) {
186 printf("cut_start_frame := %d\n", 1+fstart);
187 printf("cut_stop_frame := %d\n", 1+fstop);
188 }
189 }
190 /* If frame number range was given, check the range, and convert to indices */
191 if(times<0) {
192 if(fstart<1) fstart=1;
193 if(fstop>img.dimt) fstop=img.dimt;
194 fstart--; fstop--;
195 }
196 if(fstart>fstop || fstart>=img.dimt || fstop<0) {
197 fprintf(stderr, "Error: invalid frame time range.\n");
198 imgEmpty(&img); return(1);
199 }
200 if(verbose>1) {
201 printf("Selected PET time range: %g - %g s\n", img.start[fstart], img.end[fstop]);
202 }
203
204
205 /*
206 * If contents of selected frames are just to be set to zero,
207 * then do it in place, save the image in new file, and exit.
208 */
209 if(doCrop==0) {
210 if(verbose>1) printf("setting selected pixel values to zero...\n");
211 int fi, zi, yi, xi;
212 for(fi=fstart; fi<=fstop; fi++)
213 for(zi=0; zi<img.dimz; zi++)
214 for(yi=0; yi<img.dimy; yi++)
215 for(xi=0; xi<img.dimx; xi++)
216 img.m[zi][yi][xi][fi]=0.0;
217 if(verbose>1) fprintf(stdout, "writing image...\n");
218 ret=imgWrite(outfile, &img);
219 if(ret) {
220 fprintf(stderr, "Error: %s\n", img.statmsg);
221 imgEmpty(&img); return(11);
222 }
223 if(verbose>0) fprintf(stdout, "%s written.\n", outfile);
224 imgEmpty(&img);
225 return(0);
226 }
227
228
229 /*
230 * Create new IMG without the frames marked to be deleted,
231 * and save it.
232 */
233 if(verbose>1) printf("deleting selected frames...\n");
234 /* Calculate the nr of remaining frames */
235 int frameNr=img.dimt-(1+fstop-fstart);
236 if(frameNr<1) {
237 fprintf(stderr, "Error: all frames would be cropped.\n");
238 imgEmpty(&img);
239 return(4);
240 }
241 if(verbose>2) fprintf(stdout, "allocating memory\n");
242 IMG out; imgInit(&out);
243 ret=imgAllocateWithHeader(&out, img.dimz, img.dimy, img.dimx, frameNr, &img);
244 if(ret) {
245 fprintf(stderr, "Error: cannot allocate memory for new image.\n");
246 imgEmpty(&img);
247 return(5);
248 }
249 /* Copy data from the original image */
250 if(verbose>2) fprintf(stdout, "copying data\n");
251 int fi, fj=0, zi, yi, xi;
252 for(fi=0; fi<fstart; fi++, fj++) {
253 for(zi=0; zi<img.dimz; zi++)
254 for(yi=0; yi<img.dimy; yi++)
255 for(xi=0; xi<img.dimx; xi++)
256 out.m[zi][yi][xi][fj]=img.m[zi][yi][xi][fi];
257 out.start[fj]=img.start[fi];
258 out.end[fj]=img.end[fi];
259 out.mid[fj]=img.mid[fi];
260 }
261 for(fi=fstop+1; fi<img.dimt; fi++, fj++) {
262 for(zi=0; zi<img.dimz; zi++)
263 for(yi=0; yi<img.dimy; yi++)
264 for(xi=0; xi<img.dimx; xi++)
265 out.m[zi][yi][xi][fj]=img.m[zi][yi][xi][fi];
266 out.start[fj]=img.start[fi];
267 out.end[fj]=img.end[fi];
268 out.mid[fj]=img.mid[fi];
269 }
270 imgEmpty(&img);
271 if(verbose>1) fprintf(stdout, "writing cropped image...\n");
272 ret=imgWrite(outfile, &out);
273 if(ret) {
274 fprintf(stderr, "Error: %s\n", out.statmsg);
275 imgEmpty(&out); return(11);
276 }
277 if(verbose>0) fprintf(stdout, "%s written.\n", outfile);
278 imgEmpty(&out);
279
280 return(0);
281}
282/*****************************************************************************/
283
284/*****************************************************************************/
int atof_with_check(char *double_as_string, double *result_value)
Definition decpoint.c:107
int atoi_with_check(const char *int_as_string, int *result_value)
Definition decpoint.c:238
int IMG_TEST
Definition img.c:6
int imgExistentTimes(IMG *img)
Definition img.c:613
void imgInfo(IMG *image)
Definition img.c:359
int imgAllocateWithHeader(IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
Definition img.c:279
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgRead(const char *fname, IMG *img)
Definition imgfile.c:26
int imgWrite(const char *fname, IMG *img)
Definition imgfile.c:136
Header file for libtpccurveio.
Header file for libtpcimgio.
Header file for libtpcimgp.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:40
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:213
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:383
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:158
Header file for libtpcmodel.
unsigned short int dimx
float **** m
unsigned short int dimt
float * start
unsigned short int dimz
unsigned short int dimy
float * end
const char * statmsg
float * mid