TPCCLIB
Loading...
Searching...
No Matches
esplit.c
Go to the documentation of this file.
1
8/*****************************************************************************/
9#include "tpcclibConfig.h"
10/*****************************************************************************/
11#include <stdio.h>
12#include <stdlib.h>
13#include <unistd.h>
14#include <math.h>
15#include <string.h>
16#include <time.h>
17/*****************************************************************************/
18#include "libtpcmisc.h"
19#include "libtpcimgio.h"
20/*****************************************************************************/
21
22/*****************************************************************************/
23static char *info[] = {
24 "Extract specified time frames and planes in ECAT 6.3 or 7.x matrix file",
25 "to a new file.",
26 "Note! The program interprets ECAT 7 files as if they had only one plane.",
27 " ",
28 "Usage: @P [Options] file frames planes outputfile ",
29 " ",
30 "Options:",
31 " -stdoptions", // List standard options like --help, -v, etc
32 " ",
33 "Example:",
34 " @P a2345dy1.img 1-20 4,6,8,10 a2345dy1_part.img ",
35 " ",
36 "See also: lmlist, imgdelfr, imgdelpl, efixplnr, imgbox, imgslim, e63mreg",
37 " ",
38 "Keywords: image, ECAT, tool, cropping, modelling",
39 0};
40/*****************************************************************************/
41
42/*****************************************************************************/
43/* Turn on the globbing of the command line, since it is disabled by default in
44 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
45 In Unix&Linux wildcard command line processing is enabled by default. */
46/*
47#undef _CRT_glob
48#define _CRT_glob -1
49*/
50int _dowildcard = -1;
51/*****************************************************************************/
52
53/*****************************************************************************/
57int main(int argc, char **argv)
58{
59 int ai, help=0, version=0, verbose=1;
60 int bi, m, fi, pi, ret;
61 int frameNr=0, planeNr=0, delNr=0, blkNr=0;
62 int ecat_version=7, nxtblk;
63 char ecatfile[FILENAME_MAX], outfile[FILENAME_MAX],
64 tmp[FILENAME_MAX], *cptr, buf[MatBLKSIZE];
65 INTEGER_LIST planelist, framelist;
66 FILE *fp, *fp2;
67 ECAT7_mainheader mainheader7;
68 ECAT63_mainheader mainheader63;
69 ECAT7_MATRIXLIST mlist7;
70 MATRIXLIST mlist63;
71 ECAT7_Matval matval7;
72 Matval matval63;
73
74
75 /*
76 * Get arguments
77 */
78 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
79 ecatfile[0]=outfile[0]=(char)0;
80 ecat63InitMatlist(&mlist63); ecat7InitMatlist(&mlist7);
81 integerListInit(&planelist); integerListInit(&framelist);
82 /* Options */
83 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
84 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
85 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
86 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
87 return(1);
88 } else break;
89
90 /* Print help or version? */
91 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
92 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
93 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
94
95 /* Process other arguments, starting from the first non-option */
96 for(; ai<argc; ai++) {
97 if(!ecatfile[0]) {
98 /* check that file exists */
99 if(access(argv[ai], 0) == -1) {
100 fprintf(stderr, "Error: file '%s' does not exist.\n", argv[ai]);
101 return(1);
102 }
103 strlcpy(ecatfile, argv[ai], FILENAME_MAX); continue;
104 } else if(framelist.nr==0) {
105 m=integerListExpandFromString(argv[ai], ",;", &framelist, 1); if(m>0) continue;
106 } else if(planelist.nr==0) {
107 m=integerListExpandFromString(argv[ai], ",;", &planelist, 1); if(m>0) continue;
108 } else if(!outfile[0]) {
109 strlcpy(outfile, argv[ai], FILENAME_MAX); continue;
110 }
111 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
112 integerListEmpty(&planelist); integerListEmpty(&framelist);
113 return(1);
114 } /* next argument */
115
116 /* Is something missing? */
117 if(!outfile[0]) {
118 fprintf(stderr, "Error: missing command-line argument; try %s --help\n", argv[0]);
119 integerListEmpty(&planelist); integerListEmpty(&framelist);
120 return(1);
121 }
122
123 /* Check output filename */
124 if(strcasecmp(ecatfile, outfile)==0) {
125 fprintf(stderr, "Error: same name for input and output file.\n");
126 integerListEmpty(&planelist); integerListEmpty(&framelist);
127 return(1);
128 }
129
130 /* In verbose mode print arguments and options */
131 if(verbose>1) {
132 printf("ecatfile := %s\n", ecatfile);
133 printf("outputfile := %s\n", outfile);
134 printf("Frames:");
135 for(fi=0; fi<framelist.nr; fi++) printf(" %d", framelist.list[fi]);
136 printf("\n");
137 printf("Planes:");
138 for(pi=0; pi<planelist.nr; pi++) printf(" %d", planelist.list[pi]);
139 printf("\n");
140 }
141
142
143 /*
144 * Read main header and matrix list
145 */
146 if(verbose>1) {fprintf(stdout, "reading %s\n", ecatfile); fflush(stdout);}
147
148 /* Open file for read */
149 if((fp=fopen(ecatfile, "rb")) == NULL) {
150 fprintf(stderr, "Error: cannot read file %s\n", ecatfile);
151 integerListEmpty(&planelist); integerListEmpty(&framelist);
152 return(3);
153 }
154
155 /* Try to read ECAT 7.x main header */
156 ret=ecat7ReadMainheader(fp, &mainheader7);
157 if(ret) {
158 fprintf(stderr, "Error %d: cannot read main header.\n", ret);
159 integerListEmpty(&planelist); integerListEmpty(&framelist);
160 fclose(fp); return(2);
161 }
162 /* If header could be read, check for magic number */
163 if(strncmp(mainheader7.magic_number, ECAT7V_MAGICNR, 7)==0) {
164 ecat_version=7;
165 } else {
166 /* Check if file is in ECAT 6.3 format */
167 ret=ecat63ReadMainheader(fp, &mainheader63);
168 if(ret) {
169 fprintf(stderr, "Error %d: cannot read main header.\n", ret);
170 integerListEmpty(&planelist); integerListEmpty(&framelist);
171 fclose(fp); return(2);
172 }
173 ecat_version=6;
174 }
175 if(verbose>1) printf(" Format := %d\n", ecat_version);
176
177 /* Read matrix list */
178 if(ecat_version==7) {
179 ret=ecat7ReadMatlist(fp, &mlist7, verbose-2);
180 if(ret==0 && (mlist7.matrixNr<1 || ecat7CheckMatlist(&mlist7))) ret=99;
181 } else {
182 ret=ecat63ReadMatlist(fp, &mlist63, verbose-2);
183 if(ret==0 && (mlist63.matrixNr<1 || ecat63CheckMatlist(&mlist63))) ret=99;
184 }
185 if(ret) {
186 fprintf(stderr, "Error %d: invalid matrix list.\n", ret);
187 integerListEmpty(&planelist); integerListEmpty(&framelist);
188 fclose(fp); return(4);
189 }
190 if(verbose>20) {
191 if(ecat_version==7) ecat7PrintMatlist(&mlist7);
192 else ecat63PrintMatlist(&mlist63);
193 }
194
195 /*
196 * Mark non-listed matrices as deleted
197 */
198 delNr=0;
199 if(ecat_version==7) {
200 for(m=0; m<mlist7.matrixNr; m++) {
201 ecat7_id_to_val(mlist7.matdir[m].id, &matval7);
202 ret=0;
203 for(pi=0; pi<planelist.nr; pi++) if(planelist.list[pi]==matval7.plane) {ret++; break;}
204 for(fi=0; fi<framelist.nr; fi++) if(framelist.list[fi]==matval7.frame) {ret++; break;}
205 if(ret<2) {mlist7.matdir[m].status=-1; delNr++; continue;}
206 if(matval7.plane>planeNr) planeNr=matval7.plane;
207 if(matval7.frame>frameNr) frameNr=matval7.frame;
208 }
209 ret=mlist7.matrixNr-delNr;
210 mainheader7.num_planes=planeNr;
211 mainheader7.num_frames=frameNr;
212 } else {
213 for(m=0; m<mlist63.matrixNr; m++) {
214 mat_numdoc(mlist63.matdir[m].matnum, &matval63);
215 ret=0;
216 for(pi=0; pi<planelist.nr; pi++) if(planelist.list[pi]==matval63.plane) {ret++; break;}
217 for(fi=0; fi<framelist.nr; fi++) if(framelist.list[fi]==matval63.frame) {ret++; break;}
218 if(ret<2) {mlist63.matdir[m].matstat=-1; delNr++; continue;}
219 if(matval63.plane>planeNr) planeNr=matval63.plane;
220 if(matval63.frame>frameNr) frameNr=matval63.frame;
221 }
222 ret=mlist63.matrixNr-delNr;
223 mainheader63.num_planes=planeNr;
224 mainheader63.num_frames=frameNr;
225 }
226 if(ret==0) {
227 fprintf(stderr, "Error: none of the specified matrices were found.\n");
228 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
229 integerListEmpty(&planelist); integerListEmpty(&framelist);
230 fclose(fp); return(5);
231 }
232 if(verbose>0) fprintf(stdout, " extracting %d matrices\n", ret);
233 if(verbose>9) {
234 printf("After checking for matches:\n");
235 if(ecat_version==7) ecat7PrintMatlist(&mlist7);
236 else ecat63PrintMatlist(&mlist63);
237 }
238 integerListEmpty(&planelist); integerListEmpty(&framelist);
239
240
241 /*
242 * Write output file
243 */
244 /* Check if output file exists; rename to backup file, if necessary */
245 backupExistingFile(outfile, NULL, tmp);
246
247 if(ecat_version==7) {
248 /* Open output file */
249 fp2=ecat7Create(outfile, &mainheader7);
250 if(fp2==NULL) {
251 fprintf(stderr, "Error: cannot write ECAT file.\n");
252 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
253 fclose(fp); return(11);
254 }
255 /* Copy the matrices */
256 for(m=0; m<mlist7.matrixNr; m++) if(mlist7.matdir[m].status==1) {
257 blkNr=1+mlist7.matdir[m].endblk-mlist7.matdir[m].strtblk;
258 /* Get block number for matrix header and data */
259 nxtblk=ecat7EnterMatrix(fp2, mlist7.matdir[m].id, blkNr-1);
260 if(nxtblk<1) {
261 fprintf(stderr, "Error: cannot write ECAT matrix.\n");
262 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
263 fclose(fp); fclose(fp2); remove(outfile); return(13);
264 }
265 if(verbose>3) printf(" m=%d blkNr=%d nxtblk=%d\n", m, blkNr, nxtblk);
266 /* Copy each block */
267 for(bi=mlist7.matdir[m].strtblk; bi<=mlist7.matdir[m].endblk; bi++) {
268 /* Read block */
269 fseek(fp, (bi-1)*MatBLKSIZE, SEEK_SET);
270 if(ftell(fp)!=(bi-1)*MatBLKSIZE) {
271 fprintf(stderr, "Error: cannot find matrix block %d.\n", bi);
272 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
273 fclose(fp); fclose(fp2); remove(outfile); return(8);
274 }
275 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
276 fprintf(stderr, "Error: cannot read matrix block %d.\n", bi);
277 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
278 fclose(fp); fclose(fp2); remove(outfile); return(9);
279 }
280 /* Write block */
281 fseek(fp2, (nxtblk-1)*MatBLKSIZE, SEEK_SET);
282 if(ftell(fp2)!=(nxtblk-1)*MatBLKSIZE) {
283 fprintf(stderr, "Error: cannot find matrix block %d for write.\n", nxtblk);
284 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
285 fclose(fp); fclose(fp2); remove(outfile); return(15);
286 }
287 if(fwrite(buf, 1, MatBLKSIZE, fp2)<1) {
288 fprintf(stderr, "Error: cannot write matrix block %d.\n", nxtblk);
289 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
290 fclose(fp); fclose(fp2); remove(outfile); return(16);
291 }
292 nxtblk++;
293 }
294 }
295 } else {
296 /* Open output file */
297 fp2=ecat63Create(outfile, &mainheader63);
298 if(fp2==NULL) {
299 fprintf(stderr, "Error: cannot write ECAT file.\n");
300 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
301 fclose(fp); return(11);
302 }
303 /* Copy the matrices */
304 for(m=0; m<mlist63.matrixNr; m++) if(mlist63.matdir[m].matstat==1) {
305 blkNr=1+mlist63.matdir[m].endblk-mlist63.matdir[m].strtblk;
306 /* Get block number for matrix header and data */
307 nxtblk=ecat63Matenter(fp2, mlist63.matdir[m].matnum, blkNr-1);
308 if(nxtblk<1) {
309 fprintf(stderr, "Error: cannot write ECAT matrix.\n");
310 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
311 fclose(fp); fclose(fp2); remove(outfile); return(13);
312 }
313 if(verbose>3) printf(" m=%d blkNr=%d nxtblk=%d\n", m, blkNr, nxtblk);
314 /* Copy each block */
315 for(bi=mlist63.matdir[m].strtblk; bi<=mlist63.matdir[m].endblk; bi++) {
316 /* Read block */
317 fseek(fp, (bi-1)*MatBLKSIZE, SEEK_SET);
318 if(ftell(fp)!=(bi-1)*MatBLKSIZE) {
319 fprintf(stderr, "Error: cannot find matrix block %d.\n", bi);
320 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
321 fclose(fp); fclose(fp2); remove(outfile); return(8);
322 }
323 if(fread(buf, MatBLKSIZE, 1, fp)<1) {
324 fprintf(stderr, "Error: cannot read matrix block %d.\n", bi);
325 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
326 fclose(fp); fclose(fp2); remove(outfile); return(9);
327 }
328 /* Write block */
329 fseek(fp2, (nxtblk-1)*MatBLKSIZE, SEEK_SET);
330 if(ftell(fp2)!=(nxtblk-1)*MatBLKSIZE) {
331 fprintf(stderr, "Error: cannot find matrix block %d for write.\n", nxtblk);
332 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
333 fclose(fp); fclose(fp2); remove(outfile); return(15);
334 }
335 if(fwrite(buf, 1, MatBLKSIZE, fp2)<1) {
336 fprintf(stderr, "Error: cannot write matrix block %d.\n", nxtblk);
337 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
338 fclose(fp); fclose(fp2); remove(outfile); return(16);
339 }
340 nxtblk++;
341 }
342 }
343 }
344
345 /* Close files */
346 fclose(fp); fclose(fp2);
347 ecat7EmptyMatlist(&mlist7); ecat63EmptyMatlist(&mlist63);
348
349 if(verbose>0) fprintf(stdout, "done.\n");
350
351 return(0);
352}
353/*****************************************************************************/
354
355/*****************************************************************************/
int backupExistingFile(char *filename, char *backup_ext, char *status)
Definition backup.c:14
int ecat63Matenter(FILE *fp, int matnum, int blkNr)
Definition ecat63ml.c:159
int ecat63ReadMatlist(FILE *fp, MATRIXLIST *ml, int verbose)
Definition ecat63ml.c:46
void ecat63InitMatlist(MATRIXLIST *mlist)
Definition ecat63ml.c:20
void ecat63EmptyMatlist(MATRIXLIST *mlist)
Definition ecat63ml.c:31
void ecat63PrintMatlist(MATRIXLIST *ml)
Definition ecat63ml.c:130
int ecat63CheckMatlist(MATRIXLIST *ml)
Definition ecat63ml.c:324
void mat_numdoc(int matnum, Matval *matval)
Definition ecat63ml.c:254
int ecat63ReadMainheader(FILE *fp, ECAT63_mainheader *h)
Definition ecat63r.c:25
FILE * ecat63Create(const char *fname, ECAT63_mainheader *h)
Definition ecat63w.c:365
void ecat7InitMatlist(ECAT7_MATRIXLIST *mlist)
Definition ecat7ml.c:15
void ecat7_id_to_val(int matrix_id, ECAT7_Matval *matval)
Definition ecat7ml.c:262
int ecat7ReadMatlist(FILE *fp, ECAT7_MATRIXLIST *ml, int verbose)
Definition ecat7ml.c:41
void ecat7EmptyMatlist(ECAT7_MATRIXLIST *mlist)
Definition ecat7ml.c:26
int ecat7EnterMatrix(FILE *fp, int matrix_id, int block_nr)
Definition ecat7ml.c:147
void ecat7PrintMatlist(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:112
int ecat7CheckMatlist(ECAT7_MATRIXLIST *ml)
Definition ecat7ml.c:329
int ecat7ReadMainheader(FILE *fp, ECAT7_mainheader *h)
Definition ecat7r.c:15
FILE * ecat7Create(const char *fname, ECAT7_mainheader *h)
Definition ecat7w.c:567
int integerListEmpty(INTEGER_LIST *l)
Definition intex.c:175
int integerListInit(INTEGER_LIST *l)
Definition intex.c:161
int integerListExpandFromString(const char *s1, const char *s2, INTEGER_LIST *l, const int ifnew)
Definition intex.c:278
Header file for libtpcimgio.
#define MatBLKSIZE
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
ECAT7_MatDir * matdir
short int num_frames
char magic_number[14]
short int num_planes
MatDir * matdir
int matstat
int endblk
int matnum
int strtblk
int frame
int plane