TPCCLIB
Loading...
Searching...
No Matches
img2flat.c
Go to the documentation of this file.
1
10/*****************************************************************************/
11#include "tpcclibConfig.h"
12/*****************************************************************************/
13#include <stdio.h>
14#include <stdlib.h>
15#include <math.h>
16#include <string.h>
17#include <time.h>
18#include <float.h>
19/*****************************************************************************/
20#include "libtpcmisc.h"
21#include "libtpcimgio.h"
22/*****************************************************************************/
23
24/*****************************************************************************/
25static char *info[] = {
26 "Extract the pixel values in PET image to a binary flat file",
27 "as 4-byte (32-bit) floating point values, in this order of matrices:",
28 "All image planes of the first frame, then planes of the 2nd frame, and so on.",
29 "The current platforms byte order (little or big endian) is used.",
30 " ",
31 "Plane and frame number and matrix dimensions x and y are written on screen",
32 "or in specified matrix information file (MIF), if file name for it is given.",
33 "These numbers are needed when binary data is imported in another application.",
34 " ",
35 "Usage: @P [Options] imagefile flatfile [MIF]",
36 " ",
37 "Options:",
38/*
39 " -inf=<Matrix information file>",
40 " Plane and frame number and matrix dimensions x and y are written in",
41 " specified text file; these numbers are needed when binary data",
42 " is imported in another application program",
43*/
44 " -bins=<Nr of bins>",
45 " This application supports also 2D ECAT sinogram data. With this option",
46 " only specified nr of bins in the mid part of sinogram are saved,",
47 " leaving out bins from both sides.",
48 " -stdoptions", // List standard options like --help, -v, etc
49 " ",
50 "See also: flat2img, ecat2ana, ecat2nii, imgunit, eframe, convend",
51 " ",
52 "Keywords: ECAT, image, sinogram, format conversion",
53 0};
54/*****************************************************************************/
55
56/*****************************************************************************/
57/* Turn on the globbing of the command line, since it is disabled by default in
58 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
59 In Unix&Linux wildcard command line processing is enabled by default. */
60/*
61#undef _CRT_glob
62#define _CRT_glob -1
63*/
64int _dowildcard = -1;
65/*****************************************************************************/
66
67/*****************************************************************************/
71int main(int argc, char **argv)
72{
73 int ai, help=0, version=0, verbose=1;
74 int ret, binNr=0;
75 int pi, yi, xi;
76 char imgfile[FILENAME_MAX], datfile[FILENAME_MAX], miffile[FILENAME_MAX];
77
78
79
80 /*
81 * Get arguments
82 */
83 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
84 imgfile[0]=datfile[0]=miffile[0]=(char)0;
85 /* Options */
86 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
87 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
88 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
89 cptr=argv[ai]+1;
90 if(strncasecmp(cptr, "BINS=", 5)==0) {
91 binNr=atoi(cptr+5); if(binNr>0.0) continue;
92 } else if(strncasecmp(cptr, "INF=", 4)==0) {
93 strcpy(miffile, cptr+4); if(strlen(miffile)>0) continue;
94 } else if(strncasecmp(cptr, "MIF=", 4)==0) {
95 strcpy(miffile, cptr+4); if(strlen(miffile)>0) continue;
96 }
97 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
98 return(1);
99 } else break;
100
101 /* Print help or version? */
102 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
103 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
104 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
105
106 /* Process other arguments, starting from the first non-option */
107 if(ai<argc) {strlcpy(imgfile, argv[ai], FILENAME_MAX); ai++;}
108 if(ai<argc) {strlcpy(datfile, argv[ai], FILENAME_MAX); ai++;}
109 if(ai<argc) {strlcpy(miffile, argv[ai], FILENAME_MAX); ai++;}
110 if(ai<argc) {fprintf(stderr, "Error: too many arguments.\n"); return(1);}
111
112
113 /* Is something missing? */
114 if(!datfile[0]) {
115 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
116 return(1);
117 }
118 if(strcasecmp(imgfile, datfile)==0 || strcasecmp(imgfile, miffile)==0) {
119 fprintf(stderr, "Error: same name for input and output file.\n");
120 return(1);
121 }
122
123 /* In verbose mode print arguments and options */
124 if(verbose>1) {
125 printf("imgfile := %s\n", imgfile);
126 printf("datfile := %s\n", datfile);
127 printf("miffile := %s\n", miffile);
128 printf("binNr := %d\n", binNr);
129 }
130
131
132 if(verbose>1) printf("reading %s frame-by-frame\n", imgfile);
133 IMG img; imgInit(&img);
134 int frameNr=0;
135 FILE *fp=NULL;
136 float *fdata=NULL, *fptr;
137 size_t pxlNr=0;
138
139 if(verbose>0) fprintf(stdout, " processing frames");
140 while((ret=imgReadFrame(imgfile, frameNr+1, &img, 0)) == 0) {
141 /* report to user that we are still doing something */
142 if(verbose>0) {fprintf(stdout, "."); fflush(stdout);}
143 /* If first frame, and sinogram, then check and set binNr */
144 if(frameNr==0) {
145 if(binNr>0 && img.type!=IMG_TYPE_RAW) {
146 fprintf(stderr, "\nError: bin nr can be used only with sinograms.\n");
147 imgEmpty(&img); return(1);
148 }
149 if(binNr>0 && img.dimx<=binNr) {
150 fprintf(stderr, "\nError: bin nr should be smaller than sinogram dimx.\n");
151 imgEmpty(&img); return(1);
152 }
153 if(binNr<1) binNr=img.dimx; /* If bin nr was not set; also for images ! */
154 }
155 /* When the 1st frame, then open output file and allocate memory for
156 output data */
157 if(frameNr==0) {
158 /* Open output data file */
159 if(verbose>1) printf("\nOpening output datafile %s\n", datfile);
160 if((fp=fopen(datfile, "wb")) == NULL) {
161 fprintf(stderr, "\nError: cannot open file %s\n", datfile);
162 imgEmpty(&img); return(11);
163 }
164 /* Allocate memory for float data only once */
165 pxlNr=binNr*img.dimy;
166 fdata=(float*)malloc(pxlNr*sizeof(float));
167 if(fdata==NULL) {
168 fprintf(stderr, "\nError: out of memory\n");
169 imgEmpty(&img); fclose(fp); return(5);
170 }
171 }
172 /* Write the frame */
173 for(pi=0; pi<img.dimz; pi++) {
174 fptr=fdata;
175 for(yi=0; yi<img.dimy; yi++)
176 for(xi=(img.dimx-binNr)/2; xi<(img.dimx+binNr)/2; xi++)
177 *fptr++=img.m[pi][yi][xi][0];
178 fptr=fdata;
179 if(fwrite((float*)fdata, 4, pxlNr, fp) != pxlNr) {
180 fprintf(stderr, "\nError: cannot write matrix data in %s\n", datfile);
181 fclose(fp); remove(datfile); free(fdata); imgEmpty(&img);
182 return(12);
183 }
184 } /* next plane */
185 /* Prepare to the next frame */
186 frameNr++;
187 }
188 if(verbose>0) {
189 if(ret==STATUS_NOMATRIX) fprintf(stdout, " ok");
190 fprintf(stdout, "\n");
191 }
192 if(fp!=NULL) fclose(fp); // close the output binary file
193 free(fdata);
194 if(verbose>3) printf("imgReadFrame() return value := %d\n", ret);
195 if(ret!=0 && ret!=STATUS_NOMATRIX) {
196 fprintf(stderr, "Error: %s\n", imgStatus(ret)); //if(TEST) imgInfo(&img);
197 imgEmpty(&img);
198 return(2);
199 }
200 if(frameNr<1) {
201 fprintf(stderr, "Error: no frames could be read in %s\n", imgfile);
202 imgEmpty(&img);
203 return(3);
204 }
205
206 /*
207 * Write matrix information on stdout
208 */
209 if(verbose>0 || !miffile[0]) {
210 fp=stdout;
211 fprintf(fp, "%d %d %d %d\n", img.dimz, frameNr, binNr, img.dimy);
212 }
213
214 /*
215 * Write matrix information in specified file
216 */
217 if(miffile[0]) {
218 if(verbose>1) printf("Opening matrix information file %s\n", miffile);
219 if((fp=fopen(miffile, "w")) == NULL) {
220 fprintf(stderr, "Error: cannot open file %s\n", miffile);
221 imgEmpty(&img); return(21);
222 }
223 ret=fprintf(fp, "%d %d %d %d\n", img.dimz, frameNr, binNr, img.dimy);
224 fclose(fp);
225 if(ret<7) {
226 fprintf(stderr, "Error: cannot write in file %s\n", miffile);
227 imgEmpty(&img); return(22);
228 }
229 if(verbose>0) fprintf(stdout, "Matrix information saved in %s\n", miffile);
230 }
231
232 /* Quit */
233 if(verbose>0)
234 fprintf(stdout, "written data as 4-byte floats in %s\n", datfile);
235 imgEmpty(&img);
236 return(0);
237}
238/*****************************************************************************/
239
240/*****************************************************************************/
char * imgStatus(int status_index)
Definition img.c:330
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgReadFrame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition imgfile.c:269
Header file for libtpcimgio.
#define IMG_TYPE_RAW
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
unsigned short int dimz
unsigned short int dimy