TPCCLIB
Loading...
Searching...
No Matches
imgcat.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 <math.h>
14#include <string.h>
15#include <unistd.h>
16#include <time.h>
17/*****************************************************************************/
18#include "libtpcmisc.h"
19#include "libtpcimgio.h"
20#include "libtpcimgp.h"
21/*****************************************************************************/
22
23/*****************************************************************************/
24static char *info[] = {
25 "For simulation of simple PET images for software testing;",
26 "adds the contents of existing image files as new frame(s) and writes",
27 "the combined image as a new image file.",
28 "Images are catenated in the order given to the program.",
29 "Frame times or decay correction are not changed here.",
30 " ",
31 "Usage: @P [Options] newfile file1 [file2 [file3 ...]]",
32 " ",
33 "Options:",
34 " -stdoptions", // List standard options like --help, -v, etc
35 " ",
36 "See also: ecatcat, imgdim, imgdelfr, imgadd, imgmove, flat2img",
37 " ",
38 "Keywords: image, simulation, software testing, catenate",
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 ci, fi, ri, ret, pi, fileNr=0, firstfile=0;
61 char outfile[FILENAME_MAX], file1[FILENAME_MAX], file2[FILENAME_MAX];
62 IMG img1, img2, img3;
63 int dimt;
64
65 /*
66 * Get arguments
67 */
68 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
69 file1[0]=file2[0]=outfile[0]=(char)0;
70 imgInit(&img1); imgInit(&img2); imgInit(&img3);
71 /* Options */
72 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
73 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
74 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
75 fprintf(stderr, "Error: invalid option %s\n", argv[ai]);
76 return(1);
77 } else break;
78
79 /* Print help or version? */
80 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
81 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
82 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
83
84 /* Process other arguments, starting from the first non-option */
85 /* Output filename */
86 if(ai<argc) {strlcpy(outfile, argv[ai], FILENAME_MAX); ai++;}
87 /* Input filenames */
88 for(; ai<argc; ai++) {
89 if(firstfile<1) firstfile=ai;
91 //if(access(argv[ai], 0) == -1) {
92 // fprintf(stderr, "Error: file '%s' does not exist.\n", argv[ai]);
93 // return(1);
94 //}
95 /* Check that filename is not the same as the output filename */
96 if(strcasecmp(argv[ai], outfile)==0) {
97 fprintf(stderr, "Error: the same name for input and output image.\n");
98 return(1);
99 }
100 fileNr++;
101 }
102
103 /* Is something missing? */
104 if(fileNr<1) {
105 fprintf(stderr, "Error: missing command-line argument; try %s --help\n", argv[0]);
106 return(1);
107 }
108
109
110 /* In verbose mode print arguments and options */
111 if(verbose>1) {
112 printf("fileNr := %d\n", fileNr);
113 printf("outfile := %s\n", outfile);
114 }
115
116
117 /*
118 * Read the image dimensions from each image
119 * and verify that images can be combined
120 */
121 if(verbose>1) printf("reading image headers\n");
122 strlcpy(file1, argv[firstfile], FILENAME_MAX);
123 if(verbose>2) printf("reading header in %s\n", file1);
124 ret=imgReadHeader(file1, &img1, img1._fileFormat);
125 if(ret!=STATUS_OK) {
126 fprintf(stderr, "Error: %s\n", img1.statmsg);
127 if(verbose>4) imgInfo(&img1);
128 imgEmpty(&img1);
129 return(2);
130 }
131 dimt=img1.dimt;
132 for(ai=firstfile+1; ai<argc; ai++) {
133 strlcpy(file2, argv[ai], FILENAME_MAX);
134 imgEmpty(&img2);
135 if(verbose>2) printf("reading header in %s\n", file2);
136 ret=imgReadHeader(file2, &img2, img2._fileFormat);
137 if(ret!=STATUS_OK) {
138 fprintf(stderr, "Error: %s\n", img2.statmsg);
139 if(verbose>4) imgInfo(&img2);
140 imgEmpty(&img1); imgEmpty(&img2);
141 return(2);
142 }
143 /* Add the nr of frames */
144 dimt+=img2.dimt;
145 /* Check that images can be combined */
146 /* Data type */
147 if(img1.type!=img2.type) {
148 fprintf(stderr, "Error: different PET data type.\n");
149 imgEmpty(&img1); imgEmpty(&img2);
150 return(3);
151 }
152 /* Matrix size */
153 if(img1.dimx!=img2.dimx || img1.dimy!=img2.dimy || img1.dimz!=img2.dimz) {
154 fprintf(stderr, "Error: different matrix size.\n");
155 imgEmpty(&img1); imgEmpty(&img2);
156 return(3);
157 }
158 /* Other not that important things */
159 if(img1.unit!=img2.unit ||
160 img1.isotopeHalflife!=img2.isotopeHalflife ||
161 img1.zoom!=img2.zoom ||
162 img1.axialFOV!=img2.axialFOV ||
163 img1.transaxialFOV!=img2.transaxialFOV) {
164 fprintf(stderr, "Warning: different header information.\n");
165 if(verbose>1) {
166 printf("unit: %d vs %d\n", img1.unit, img2.unit);
167 printf("isotopeHalflife: %g vs %g\n", img1.isotopeHalflife, img2.isotopeHalflife);
168 printf("zoom: %g vs %g\n", img1.zoom, img2.zoom);
169 printf("axialFOV: %g vs %g\n", img1.axialFOV, img2.axialFOV);
170 printf("transaxialFOV: %g vs %g\n", img1.transaxialFOV, img2.transaxialFOV);
171 }
172 }
173 }
174 imgEmpty(&img2);
175 if(verbose>1) printf("combined_dimt := %d\n", dimt);
176
177
178 /*
179 * Read the whole contents of file1
180 */
181 if(verbose>=0) printf("reading %s\n", file1);
182 if(imgRead(file1, &img1)) {
183 fprintf(stderr, "Error: %s\n", img1.statmsg);
184 if(verbose>5) imgInfo(&img1);
185 imgEmpty(&img1);
186 return(4);
187 }
188
189 /*
190 * Create place for new combined PET data
191 */
192 if(verbose>1) printf("creating combined data\n");
193 ret=imgAllocateWithHeader(&img3, img1.dimz, img1.dimy, img1.dimx, dimt, &img1);
194 if(ret) {
195 fprintf(stderr, "Error: cannot allocate memory for combined data.\n");
196 imgEmpty(&img1);
197 return(5);
198 }
199
200 /* Copy pixel values from the first image */
201 for(pi=0; pi<img1.dimz; pi++)
202 for(ri=0; ri<img1.dimy; ri++)
203 for(ci=0; ci<img1.dimx; ci++)
204 for(fi=0; fi<img1.dimt; fi++)
205 img3.m[pi][ri][ci][fi]=img1.m[pi][ri][ci][fi];
206 /* Copy frame times */
207 for(fi=0; fi<img1.dimt; fi++) {
208 img3.start[fi]=img1.start[fi];
209 img3.end[fi]=img1.end[fi];
210 img3.mid[fi]=img1.mid[fi];
211 }
212 /* Save the current frame number */
213 dimt=img1.dimt;
214 /* Original image 1 data is no more needed */
215 imgEmpty(&img1); if(verbose>4) imgInfo(&img3);
216
217 /*
218 * Combine the data from the other images
219 */
220 for(ai=firstfile+1; ai<argc; ai++) {
221 strlcpy(file2, argv[ai], FILENAME_MAX); if(verbose>=0) printf("reading %s\n", file2);
222 ret=imgRead(file2, &img2);
223 if(ret!=STATUS_OK) {
224 fprintf(stderr, "Error: %s\n", img2.statmsg);
225 if(verbose>5) imgInfo(&img2);
226 imgEmpty(&img2); imgEmpty(&img3);
227 return(4);
228 }
229 if(verbose>4) printf(" read ok\n");
230 /* Copy pixel values */
231 for(pi=0; pi<img2.dimz; pi++)
232 for(ri=0; ri<img2.dimy; ri++)
233 for(ci=0; ci<img2.dimx; ci++)
234 for(fi=0; fi<img2.dimt; fi++)
235 img3.m[pi][ri][ci][dimt+fi]=img2.m[pi][ri][ci][fi];
236 /* Copy frame times */
237 for(fi=0; fi<img2.dimt; fi++) {
238 img3.start[dimt+fi]=img2.start[fi];
239 img3.end[dimt+fi]=img2.end[fi];
240 img3.mid[dimt+fi]=img2.mid[fi];
241 }
242 /* Save the current plane number */
243 dimt+=img2.dimt;
244 imgEmpty(&img2);
245 }
246
247
248 /*
249 * Write combined PET data
250 */
251 if(verbose>=0) printf("writing combined data in %s\n", outfile);
252 if(imgWrite(outfile, &img3)) {
253 fprintf(stderr, "Error: %s\n", img3.statmsg);
254 imgEmpty(&img3);
255 return(11);
256 }
257 imgEmpty(&img3);
258 if(verbose>0) printf("done.\n");
259
260 return(0);
261}
262/*****************************************************************************/
263
264/*****************************************************************************/
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
int imgReadHeader(const char *fname, IMG *img, int format)
Definition imgfile.c:199
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
unsigned short int dimx
char type
float **** m
float transaxialFOV
char unit
int _fileFormat
unsigned short int dimt
float * start
unsigned short int dimz
unsigned short int dimy
float * end
float zoom
const char * statmsg
float isotopeHalflife
float axialFOV
float * mid