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