TPCCLIB
Loading...
Searching...
No Matches
e63emhdr.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 <math.h>
13#include <string.h>
14#include <unistd.h>
15#include <ctype.h>
16#include <time.h>
17/*****************************************************************************/
18#include "libtpcmisc.h"
19#include "libtpcimgio.h"
20/*****************************************************************************/
21
22/*****************************************************************************/
23static char *info[] = {
24 "Edit the information in the main header of an ECAT 6.3 file.",
25 " ",
26 "Usage: @P [Options] ecatfile fieldname := fieldvalue ",
27 " or: @P [Options] ecatfile headerfile",
28 " ",
29 "Options:",
30 " -stdoptions", // List standard options like --help, -v, etc
31 " ",
32 "Header file can contain one or more mainheader field names and values",
33 "in interfile-like format, for example:",
34 " patient_name := Einstein Albert",
35 " radiopharmaceutical := O-15 WATER",
36 " study_description := brain scan",
37 " facility_name := Turku PET Centre",
38 " ",
39 "Examples:",
40 " @P s2345dy1.img patient_name := \"Albert Einstein\"",
41 " @P s2345dy1.img s2345dy1.header",
42 " ",
43 "See also: lmhdr, lshdr, e7emhdr, lmlist, esetstrt, imgunit, imgdecay",
44 " ",
45 "Keywords: ECAT, image, header, tool",
46 0};
47/*****************************************************************************/
48
49/*****************************************************************************/
50/* Turn on the globbing of the command line, since it is disabled by default in
51 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
52 In Unix&Linux wildcard command line processing is enabled by default. */
53/*
54#undef _CRT_glob
55#define _CRT_glob -1
56*/
57int _dowildcard = -1;
58/*****************************************************************************/
59
60/*****************************************************************************/
64int main(int argc, char **argv)
65{
66 int ai, help=0, version=0, verbose=1;
67 int li, ret, change_nr=0;
68 char *cptr, petfile[FILENAME_MAX], iftfile[FILENAME_MAX];
69 char keyname[FILENAME_MAX], eqsign[FILENAME_MAX],
70 keyvalue[FILENAME_MAX];
71 FILE *fp;
72 ECAT63_mainheader main_header;
73 IFT ift;
74
75
76 /*
77 * Get arguments
78 */
79 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
80 petfile[0]=iftfile[0]=(char)0;
81 keyname[0]=eqsign[0]=keyvalue[0]=(char)0;
82 iftInit(&ift);
83 /* Options */
84 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
85 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
86 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
87 fprintf(stderr, "Error: invalid option %s\n", argv[ai]);
88 return(1);
89 } else break;
90
91 /* Print help or version? */
92 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
93 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
94 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
95
96 /* Process other arguments, starting from the first non-option */
97 /* PET filename */
98 if(ai<argc) {
99 strlcpy(petfile, argv[ai], FILENAME_MAX); ai++;
100 /* check that file exists */
101 if(access(petfile, 0) == -1) {
102 fprintf(stderr, "Error: file '%s' does not exist.\n", petfile);
103 return(1);
104 }
105 }
106 /* If the next argument is also the last, then that is header filename */
107 if(ai==argc-1) {
108 strlcpy(iftfile, argv[ai], FILENAME_MAX); ai++;
109 /* check that file exists */
110 if(access(iftfile, 0) == -1) {
111 fprintf(stderr, "Error: file '%s' does not exist.\n", iftfile);
112 return(1);
113 }
114 } else {
115 /* else we have header key and value */
116 if(ai<argc) {strcpy(keyname, argv[ai]); ai++;}
117 if(ai<argc) {
118 strlcpy(eqsign, argv[ai], FILENAME_MAX); ai++;
119 if(strcmp(eqsign, ":=")!=0) { /* check if eqsign is ok */
120 fprintf(stderr, "Error: use ' := ' to separate field name and value.\n");
121 return(1);
122 }
123 }
124 if(ai<argc) {strcpy(keyvalue, argv[ai]); ai++;}
125 /* if even more arguments, they probably are space-separated values */
126 for(; ai<argc; ai++) {strcat(keyvalue, " "); strcat(keyvalue, argv[ai]);}
127 }
128
129 /* Is something missing? */
130 /* Either header filename, or, both keyname and value must be given */
131 if((!keyname[0] && !iftfile[0]) || (keyname[0] && !keyvalue[0])) {
132 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
133 return(1);
134 }
135 /* If available, store the keyname and value */
136 if(keyname[0]) iftPut(&ift, keyname, keyvalue, NULL, 0);
137
138
139 /* In verbose mode print arguments and options */
140 if(verbose>1) {
141 printf("petfile := %s\n", petfile);
142 if(iftfile[0]) printf("iftfile := %s\n", iftfile);
143 if(keyname[0]) printf("%s := %s\n", keyname, keyvalue);
144 }
145
146
147 /*
148 * Read key names and values from file, if necessary
149 */
150 if(iftfile[0]) {
151 if(verbose>1) printf("reading %s\n", iftfile);
152 ret=iftRead(&ift, iftfile, 1, 0);
153 if(ret) {
154 fprintf(stderr, "Error: %s\n", ift.status);
155 iftEmpty(&ift); return(2);
156 }
157 }
158 if(verbose>2) iftWrite(&ift, "stdout", 0);
159
160
161 /*
162 * Read main header
163 */
164 /* Open input ECAT file */
165 if(verbose>1) printf("reading %s\n", petfile);
166 if((fp=fopen(petfile, "rb")) == NULL) {
167 fprintf(stderr, "Error: cannot open file %s\n", petfile);
168 iftEmpty(&ift); return(2);
169 }
170 /* Read the header */
171 if((ret=ecat63ReadMainheader(fp, &main_header))) {
172 fprintf(stderr, "Error (%d): cannot read main header.\n", ret);
173 iftEmpty(&ift); fclose(fp); return(3);
174 }
175 /* Close ECAT file */
176 fclose(fp);
177 if(verbose>9) ecat63PrintMainheader(&main_header, stdout);
178
179
180 /*
181 * Change the fields
182 */
183 for(li=0, change_nr=0; li<ift.keyNr; li++) {
184 if(verbose>1) iftWriteItem(&ift, li, stdout, 0);
185 /* Change field value */
186 ret=ecat63EditMHeader(&main_header, ift.item[li].key, ift.item[li].value, verbose-2);
187 if(ret==1) {
188 fprintf(stderr, " warning: invalid field name: %s\n", ift.item[li].key);
189 } else if(ret==2) {
190 fprintf(stderr, " warning: invalid field value: %s\n", ift.item[li].value);
191 } else change_nr++;
192 } /* next field */
193 if(verbose>4) ecat63PrintMainheader(&main_header, stdout);
194 iftEmpty(&ift);
195 if(change_nr==0) {
196 fprintf(stderr, "Error: no fields were changed.\n");
197 return(8);
198 }
199
200
201 /*
202 * Write main header
203 */
204 if(verbose>1) printf("writing edited %s\n", petfile);
205 /* Open input CTI file */
206 if((fp=fopen(petfile, "r+b")) == NULL) {
207 fprintf(stderr, "Error: cannot open %s for write.\n", petfile);
208 return(11);
209 }
210 /* Write header */
211 if((ret=ecat63WriteMainheader(fp, &main_header))) {
212 fprintf(stderr, "Error (%d): cannot write main header.\n", ret);
213 fclose(fp); return(12);
214 }
215 /* Close ECAT file */
216 fclose(fp);
217
218 if(verbose>0) {printf("%s edited.\n", petfile); fflush(stdout);}
219
220 return(0);
221}
222/*****************************************************************************/
223
224/*****************************************************************************/
int ecat63EditMHeader(ECAT63_mainheader *h, char *field, char *value, int verbose)
Definition ecat63h.c:140
void ecat63PrintMainheader(ECAT63_mainheader *h, FILE *fp)
Definition ecat63p.c:16
int ecat63ReadMainheader(FILE *fp, ECAT63_mainheader *h)
Definition ecat63r.c:25
int ecat63WriteMainheader(FILE *fp, ECAT63_mainheader *h)
Definition ecat63w.c:24
int iftPut(IFT *ift, char *key, char *value, char *cmt_type, int verbose)
Definition ift.c:82
void iftEmpty(IFT *ift)
Definition ift.c:60
void iftInit(IFT *ift)
Definition ift.c:45
int iftWriteItem(IFT *ift, int item, FILE *fp, int verbose)
Definition iftfile.c:221
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
Definition iftfile.c:24
int iftWrite(IFT *ift, char *filename, int verbose)
Definition iftfile.c:282
Header file for libtpcimgio.
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
int keyNr
Definition libtpcmisc.h:270
const char * status
Definition libtpcmisc.h:277
IFT_KEY_AND_VALUE * item
Definition libtpcmisc.h:279