TPCCLIB
Loading...
Searching...
No Matches
image.c File Reference

Functions to basic processing with TPCCLIB image data structure. More...

#include "tpcclibConfig.h"
#include "tpcimage.h"

Go to the source code of this file.

Functions

char * imgModalityDescr (imgmodality c)
 
char * imgContentDescr (imgcontent c)
 
void imgInit (IMG *img)
 
void imgFree (IMG *img)
 
int imgAllocate (IMG *img, const unsigned int dimz, const unsigned int dimy, const unsigned int dimx, const unsigned int dimt, TPCSTATUS *status)
 
int imgHasData (IMG *img)
 
int imgHasTimes (IMG *img)
 
int imgHasCounts (IMG *img)
 
int imgHasWeights (IMG *img)
 
void imgContents (IMG *img, FILE *fp)
 
unsigned long long imgNaNs (IMG *img, int fix)
 
int imgMinMax (IMG *img, float *minvalue, float *maxvalue)
 
int imgXRange (IMG *img, double *xmin, double *xmax)
 

Detailed Description

Functions to basic processing with TPCCLIB image data structure.

Author
Vesa Oikonen

Definition in file image.c.

Function Documentation

◆ imgAllocate()

int imgAllocate ( IMG * img,
const unsigned int dimz,
const unsigned int dimy,
const unsigned int dimx,
const unsigned int dimt,
TPCSTATUS * status )

Allocates memory for image data. Old contents are not saved.

See also
imgInit, imgFree, imgWrite, imgHasData, imgCopyHeader
Returns
enum tpcerror (TPCERROR_OK when successful).
Parameters
imgPointer to initialized image structure; old contents are deleted.
Precondition
Initialize structure using imgInit() before this.
Parameters
dimzNr of image planes to allocate.
dimyNr of image rows to allocate.
dimxNr of image columns to allocate.
dimtNr of image time frames (samples) to allocate.
statusPointer to status data; enter NULL if not needed.

Definition at line 126 of file image.c.

140 {
141 int verbose=0; if(status!=NULL) verbose=status->verbose;
142 if(verbose>0) {
143 printf("%s(img, %u, %u, %u, %u)\n", __func__, dimz, dimy, dimx, dimt); fflush(stdout);}
144
145 if(img==NULL || dimz<1 || dimy<1 || dimx<1 || dimt<1) {
146 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
147 return(TPCERROR_FAIL);
148 }
149
150 /* Remove any previous contents */
151 imgFree(img);
152
153 /* Memory for frame times */
154 int ret=0; {img->x1=calloc(dimt, sizeof(float)); if(img->x1==NULL) ret++;}
155 if(!ret) {img->x2=calloc(dimt, sizeof(float)); if(img->x2==NULL) ret++;}
156 if(!ret) {img->x=calloc(dimt, sizeof(float)); if(img->x==NULL) ret++;}
157 if(ret) {
158 imgFree(img);
159 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
161 }
162
163 /* Memory for weights */
164 ret=0; {img->weight=calloc(dimt, sizeof(float)); if(img->weight==NULL) ret++;}
165 if(!ret) {img->prompts=calloc(dimt, sizeof(float)); if(img->prompts==NULL) ret++;}
166 if(!ret) {img->randoms=calloc(dimt, sizeof(float)); if(img->randoms==NULL) ret++;}
167 if(ret) {
168 imgFree(img);
169 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
171 }
172
173 /* Memory for pixel matrix */
174 ret=0; {img->_t=(float*)malloc((size_t)dimz*dimy*dimx*dimt*sizeof(float)); if(img->_t==NULL) ret++;}
175 if(!ret) {img->_x=(float**)malloc((size_t)dimz*dimy*dimx*sizeof(float*)); if(img->_x==NULL) ret++;}
176 if(!ret) {img->_y=(float***)malloc((size_t)dimz*dimy*sizeof(float**)); if(img->_y==NULL) ret++;}
177 if(!ret) {img->_z=(float****)malloc((size_t)dimz*sizeof(float***)); if(img->_z==NULL) ret++;}
178 if(ret) {
179 imgFree(img);
180 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
182 }
183 /* Set matrix data pointers */
184 {
185 float ***yptr, **xptr, *tptr;
186 yptr=img->_y; xptr=img->_x; tptr=img->_t;
187 for(unsigned int zi=0; zi<dimz; zi++) {
188 img->_z[zi]=yptr;
189 for(unsigned int yi=0; yi<dimy; yi++) {
190 *yptr++=xptr;
191 for(unsigned int xi=0; xi<dimx; xi++) {
192 *xptr++=tptr; tptr+=dimt;
193 }
194 }
195 }
196 }
197 img->m=img->_z;
198 img->p=img->_t;
199 /* Set all pixel values to zero */
200 for(unsigned int zi=0; zi<dimz; zi++)
201 for(unsigned int yi=0; yi<dimy; yi++)
202 for(unsigned int xi=0; xi<dimx; xi++)
203 for(unsigned int ti=0; ti<dimt; ti++)
204 img->m[zi][yi][xi][ti]=(float)0.0;
205 /* Set matrix dimensions */
206 img->dimz=dimz; img->dimy=dimy; img->dimx=dimx; img->dimt=dimt;
207
208 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
209 return(TPCERROR_OK);
210}
void imgFree(IMG *img)
Definition image.c:107
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
unsigned short int dimx
Definition tpcimage.h:112
float * x1
Definition tpcimage.h:180
float **** m
Definition tpcimage.h:161
float * x2
Definition tpcimage.h:182
float * prompts
Definition tpcimage.h:195
unsigned short int dimt
Definition tpcimage.h:110
float * weight
Definition tpcimage.h:193
unsigned short int dimz
Definition tpcimage.h:116
unsigned short int dimy
Definition tpcimage.h:114
float * p
Definition tpcimage.h:174
float * x
Definition tpcimage.h:184
float * randoms
Definition tpcimage.h:197
int verbose
Verbose level, used by statusPrint() etc.
@ TPCERROR_FAIL
General error.
@ TPCERROR_OUT_OF_MEMORY
Cannot allocate memory.
@ TPCERROR_OK
No error.

Referenced by imgReadDICOM(), and imgReadNifti().

◆ imgContentDescr()

char * imgContentDescr ( imgcontent c)

Return pointer to content type of the image data.

Returns
pointer to the data content type string.
See also
imgdata
Parameters
cIMG content code

Definition at line 51 of file image.c.

54 {
55 if(c<IMG_CONTENT_UNKNOWN || c>=IMG_CONTENT_LAST) return NULL;
56 return (char*)img_content[c];
57}
@ IMG_CONTENT_LAST
End of list.
Definition tpcimage.h:76

Referenced by imgContents(), and imgFillOHeader().

◆ imgContents()

void imgContents ( IMG * img,
FILE * fp )

Print general information on the contents of the IMG data structure.

See also
imgInit, imgRead, imgHasData, imgHasTimes
Parameters
imgPointer to IMG structure.
fpFile pointer for output; usually stdout.

Definition at line 293 of file image.c.

298 {
299 if(fp==NULL) return;
300 if(img==NULL) {fprintf(fp, "IMG pointer is NULL\n"); fflush(fp); return;}
301
302 fprintf(fp, "modality: %s\n", imgModalityDescr(img->modality));
303 fprintf(fp, "content: %s\n", imgContentDescr(img->content));
304 fprintf(fp, "format: %s\n", imgFormatDescr(img->format));
306 fprintf(fp, "output_format: %s\n", imgFormatDescr(img->oformat));
307
308 fprintf(fp, "hasData := %d\n", imgHasData(img));
309 fprintf(fp, "hasTimes := %d\n", imgHasTimes(img));
310 fprintf(fp, "hasCounts := %d\n", imgHasCounts(img));
311
312 if(img->scanStart[0]) fprintf(fp, "scanStart: %s\n", img->scanStart);
313
314 fprintf(fp, "dimensions: %u x %u x %u x %u\n", img->dimx, img->dimy, img->dimz, img->dimt);
315 if(img->sizex!=0.0 || img->sizey!=0.0 || img->sizez!=0.0)
316 fprintf(fp, "voxel_size: %g x %g x %g\n", img->sizex, img->sizey, img->sizez);
317 if(img->gapx!=0.0 || img->gapy!=0.0 || img->gapz!=0.0)
318 fprintf(fp, "voxel_gaps: %g x %g x %g\n", img->gapx, img->gapy, img->gapz);
319
320 fprintf(fp, "qform := %d\n", img->xform[0]);
321 fprintf(fp, "sform := %d\n", img->xform[1]);
322 if(floatNonzeroes(img->quatern, 6)>0) {
323 fprintf(fp, "quatern_b := %g\n", img->quatern[0]);
324 fprintf(fp, "quatern_c := %g\n", img->quatern[1]);
325 fprintf(fp, "quatern_d := %g\n", img->quatern[2]);
326 fprintf(fp, "quatern_x_shift := %g\n", img->quatern[3]);
327 fprintf(fp, "quatern_y_shift := %g\n", img->quatern[4]);
328 fprintf(fp, "quatern_z_shift := %g\n", img->quatern[5]);
329 }
330 if(floatNonzeroes(img->srow, 12)>0) {
331 for(int i=0; i<4; i++) fprintf(fp, "srow_x[%d] := %g\n", i, img->srow[i]);
332 for(int i=0; i<4; i++) fprintf(fp, "srow_y[%d] := %g\n", i, img->srow[4+i]);
333 for(int i=0; i<4; i++) fprintf(fp, "srow_z[%d] := %g\n", i, img->srow[8+i]);
334 }
335 if(floatNonzeroes(img->iop, 6)>0) {
336 fprintf(fp, "image_orientation_patient := %g", img->iop[0]);
337 for(int i=1; i<6; i++) fprintf(fp, ", %g", img->iop[i]);
338 fprintf(fp, "\n");
339 }
340 if(floatNonzeroes(img->ipp, 3)>0) {
341 fprintf(fp, "image_position_patient := %g", img->ipp[0]);
342 for(int i=1; i<3; i++) fprintf(fp, ", %g", img->ipp[i]);
343 fprintf(fp, "\n");
344 }
345 if(floatNonzeroes(img->mt, 3)>0) {
346 fprintf(fp, "image_matrix_transformation_parameters := %g", img->mt[0]);
347 for(int i=1; i<12; i++) fprintf(fp, ", %g", img->mt[i]);
348 fprintf(fp, "\n");
349 }
350
351 if(img->isot!=ISOTOPE_UNKNOWN) fprintf(fp, "isotope: %s\n", isotopeName(img->isot));
352 if(img->decayCorrection==DECAY_CORRECTED) fprintf(fp, "physical_decay: corrected\n");
353 else if(img->decayCorrection==DECAY_NOTCORRECTED) fprintf(fp, "physical_decay: not corrected\n");
354
355 if(imgHasWeights(img)) fprintf(fp, "weighting: no\n");
356 else fprintf(fp, "weighting: yes\n");
357
358 if(img->cunit!=UNIT_UNKNOWN) fprintf(fp, "pixel_unit := %s\n", unitName(img->cunit));
359 if(img->tunit!=UNIT_UNKNOWN) fprintf(fp, "time_unit := %s\n", unitName(img->tunit));
360
361 fprintf(fp, "original header: %d items\n", img->ih.keyNr);
362
363 fflush(fp);
364 return;
365}
unsigned int floatNonzeroes(float *a, const unsigned int n)
Definition floatutil.c:247
int imgHasData(IMG *img)
Definition image.c:218
char * imgModalityDescr(imgmodality c)
Definition image.c:27
int imgHasWeights(IMG *img)
Definition image.c:278
char * imgContentDescr(imgcontent c)
Definition image.c:51
int imgHasTimes(IMG *img)
Definition image.c:235
int imgHasCounts(IMG *img)
Definition image.c:251
char * imgFormatDescr(imgformat c)
Definition imageio.c:36
char * isotopeName(int isotope_code)
Definition isotope.c:101
int keyNr
Definition tpcift.h:47
float sizex
Definition tpcimage.h:119
imgmodality modality
Definition tpcimage.h:100
unit cunit
Definition tpcimage.h:203
float gapx
Definition tpcimage.h:126
imgformat format
Definition tpcimage.h:103
float ipp[3]
Definition tpcimage.h:141
short int xform[2]
Definition tpcimage.h:133
float quatern[6]
Definition tpcimage.h:135
float iop[6]
Definition tpcimage.h:139
float srow[12]
Definition tpcimage.h:137
float sizey
Definition tpcimage.h:121
IFT ih
Definition tpcimage.h:208
imgcontent content
Definition tpcimage.h:97
char scanStart[20]
Definition tpcimage.h:94
float mt[12]
Definition tpcimage.h:144
decaycorrection decayCorrection
Definition tpcimage.h:91
float gapy
Definition tpcimage.h:128
isotope isot
Definition tpcimage.h:88
float gapz
Definition tpcimage.h:130
imgformat oformat
Definition tpcimage.h:105
float sizez
Definition tpcimage.h:123
unit tunit
Definition tpcimage.h:205
@ UNIT_UNKNOWN
Unknown unit.
char * unitName(int unit_code)
Definition units.c:143
@ IMG_FORMAT_UNKNOWN
Unknown format.
Definition tpcimage.h:33
@ DECAY_NOTCORRECTED
Data is not corrected for physical decay.
Definition tpcisotope.h:80
@ DECAY_CORRECTED
Data is corrected for physical decay.
Definition tpcisotope.h:81
@ ISOTOPE_UNKNOWN
Unknown.
Definition tpcisotope.h:51

◆ imgFree()

void imgFree ( IMG * img)

Free memory allocated for IMG. All data is cleared.

See also
imgInit, imgAllocate, imgRead
Parameters
imgPointer to IMG structure.

Definition at line 107 of file image.c.

110 {
111 if(img==NULL) return;
112 iftFree(&img->ih);
113 iftFree(&img->oh);
114 free(img->weight); free(img->prompts); free(img->randoms);
115 free(img->x1); free(img->x2); free(img->x);
116 free(img->_t); free(img->_z); free(img->_x); free(img->_y);
117 imgInit(img);
118}
void iftFree(IFT *ift)
Definition ift.c:37
void imgInit(IMG *img)
Definition image.c:64
IFT oh
Definition tpcimage.h:210

Referenced by imgAllocate(), imgRead(), imgReadDICOM(), and imgReadNifti().

◆ imgHasCounts()

int imgHasCounts ( IMG * img)

Verify that IMG contains prompts and randoms.

See also
imgHasData, imgHasTimes, imgHasWeights, imgInit, imgFree, imgRead, imgWrite, imgContents
Returns
0, if no prompts or randoms, 1 if prompts exist, 2 if randoms exist, and 3 if both prompts and randoms exist.
Parameters
imgPointer to image structure.

Definition at line 251 of file image.c.

254 {
255 if(img==NULL || img->dimt<1) return(0);
256 int p=0, r=0;
257 /* If image has only one frame, then any value > 0 is fine */
258 if(img->dimt==1) {
259 if(img->prompts[0]>0.000000001) p=1;
260 if(img->randoms[0]>0.000000001) r=2;
261 return(p+r);
262 }
263 /* When more frames, we check that frames have different count level */
264 for(unsigned short int i=1; i<img->dimt; i++) {
265 if(fabsf(img->prompts[i]-img->prompts[i-1])>0.001) p=1;
266 if(fabsf(img->randoms[i]-img->randoms[i-1])>0.001) r=2;
267 if((p+r)>2) break;
268 }
269 return(p+r);
270}

Referenced by imgContents(), and imgToSIF().

◆ imgHasData()

int imgHasData ( IMG * img)

Verify that image data actually contains pixel data.

See also
imgHasTimes, imgNaNs, imgRead, imgWrite, imgContents
Returns
0, if no data, 1 if contains data.
Parameters
imgPointer to image structure.

Definition at line 218 of file image.c.

221 {
222 if(img==NULL) return(0);
223 if(img->dimz<1 || img->dimy<1 || img->dimx<1 || img->dimz<1) return(0);
224 if(img->m==NULL || img->p==NULL) return(0);
225 if(img->x1==NULL || img->x2==NULL) return(0);
226 return(1);
227}

Referenced by imgContents(), imgCopyHeader(), imgFillOHeader(), imgHasTimes(), imgMinMax(), imgSetNiftiHeader(), imgWrite(), imgWriteNifti(), and imgXRange().

◆ imgHasTimes()

int imgHasTimes ( IMG * img)

Verify that IMG contains frame times.

See also
imgHasData, imgInit, imgFree, imgRead, imgWrite, imgContents
Returns
0, if no frame times, 1 if frame times exist.
Parameters
imgPointer to image structure.

Definition at line 235 of file image.c.

238 {
239 if(imgHasData(img)==0) return(0);
240 for(int i=0; i<img->dimt; i++) if(img->x2[i]>0.00000001) return(1);
241 return(0);
242}

Referenced by imgContents(), imgToSIF(), and imgWriteNifti().

◆ imgHasWeights()

int imgHasWeights ( IMG * img)

Check if image contains weights as indicated by the 'weighting' field.

See also
imgHasCounts, imgHasData, imgHasTimes, imgInit, tacIsWeighted
Returns
Returns 1 if weighted, and 0 if not or in case of an error.
Parameters
imgPointer to image structure.

Definition at line 278 of file image.c.

281 {
282 if(img==NULL || img->dimt<1) return(0);
283 if(img->weighting==WEIGHTING_UNKNOWN || img->weighting==WEIGHTING_OFF) return(0);
284 if(img->weighting<WEIGHTING_LAST) return(1);
285 return(0);
286}
weights weighting
Definition tpcimage.h:191
@ WEIGHTING_OFF
Not weighted or weights not available (weights for all included samples are 1.0).
@ WEIGHTING_UNKNOWN
Not known; usually assumed that not weighted.

Referenced by imgContents().

◆ imgInit()

void imgInit ( IMG * img)

Initiate the IMG structure before any use.

See also
imgFree, imgAllocate, imgRead
Parameters
imgPointer to IMG structure.

Definition at line 64 of file image.c.

67 {
68 if(img==NULL) return;
69 img->dimt=img->dimx=img->dimy=img->dimz=0;
70 iftInit(&img->ih);
71 iftInit(&img->oh);
75
76 for(int i=0; i<20; i++) img->scanStart[i]=(char)0;
77 for(int i=0; i<MAX_STUDYNR_LEN+1; i++) img->studyNr[i]=(char)0;
78
79
80 img->sizex=img->sizey=img->sizez=0.0;
81 img->gapx=img->gapy=img->gapz=0.0;
82 img->xform[0]=img->xform[1]=0;
83 for(int i=0; i<6; i++) img->quatern[i]=0.0;
84 for(int i=0; i<12; i++) img->srow[i]=0.0;
85 for(int i=0; i<6; i++) img->iop[i]=0.0;
86 for(int i=0; i<3; i++) img->ipp[i]=0.0;
87 for(int i=0; i<12; i++) img->mt[i]=0.0;
88
91
93 img->weight=img->prompts=img->randoms=NULL;
94
95 img->cunit=img->tunit=UNIT_UNKNOWN;
96
97 img->x1=img->x2=img->x=NULL;
98 img->m=(float****)0; img->p=0;
99 img->_z=(float****)0; img->_y=(float***)0; img->_x=(float**)0; img->_t=(float*)0;
100}
void iftInit(IFT *ift)
Definition ift.c:21
char studyNr[MAX_STUDYNR_LEN+1]
Definition tpcimage.h:85
#define MAX_STUDYNR_LEN
Define max study number length.
@ IMG_MODALITY_UNKNOWN
Unknown modality.
Definition tpcimage.h:57
@ IMG_CONTENT_UNKNOWN
Unknown data content.
Definition tpcimage.h:71
@ DECAY_UNKNOWN
Not known; usually assumed that data is corrected.
Definition tpcisotope.h:79

Referenced by imgFree().

◆ imgMinMax()

int imgMinMax ( IMG * img,
float * minvalue,
float * maxvalue )

Searches the min and max pixel value in the image data.

See also
imgXRange, imgInit, imgFree, imgHasData
Returns
enum tpcerror (TPCERROR_OK when successful).
Parameters
imgPointer to IMG structure from where min and max pixel values are searched.
minvaluePointer to min pixel value; Enter NULL if not needed.
maxvaluePointer to max pixel value; Enter NULL if not needed.

Definition at line 396 of file image.c.

403 {
404 if(img==NULL || !imgHasData(img)) return(TPCERROR_FAIL);
405 float f1, f2;
406 f1=f2=nanf("");
407 if(minvalue!=NULL) *minvalue=f1;
408 if(maxvalue!=NULL) *maxvalue=f2;
409 unsigned long long i, n=img->dimt*img->dimz*img->dimy*img->dimx;
410 // search first valid number
411 for(i=0; i<n; i++) if(isfinite(img->p[i])) break;
412 if(i==n) return(TPCERROR_MISSING_DATA);
413 f1=f2=img->p[i++];
414 for(; i<n; i++) {
415 if(img->p[i]>f2) f2=img->p[i];
416 else if(img->p[i]<f1) f1=img->p[i];
417 }
418 if(minvalue!=NULL) *minvalue=f1;
419 if(maxvalue!=NULL) *maxvalue=f2;
420 return(TPCERROR_OK);
421}
@ TPCERROR_MISSING_DATA
File contains missing values.

Referenced by imgSetNiftiHeader().

◆ imgModalityDescr()

char * imgModalityDescr ( imgmodality c)

Return pointer to modality of the image data.

Returns
pointer to the modality string.
See also
imgmodality
Parameters
cIMG modality code

Definition at line 27 of file image.c.

30 {
31 if(c<IMG_MODALITY_UNKNOWN || c>=IMG_MODALITY_LAST) return NULL;
32 return (char*)img_modality[c];
33}
@ IMG_MODALITY_LAST
End of list.
Definition tpcimage.h:62

Referenced by imgContents(), and imgFillOHeader().

◆ imgNaNs()

unsigned long long imgNaNs ( IMG * img,
int fix )

Searches the image data for missing pixel values, optionally setting those to zero.

See also
imgHasData
Returns
the number of missing pixel values.
Parameters
imgPointer to IMG structure.
fixSet (1) or do not set (0) missing pixels to zero.

Definition at line 373 of file image.c.

378 {
379 if(img==NULL) return(0);
380 unsigned long long i, n=0, pxlNr=img->dimt*img->dimz*img->dimy*img->dimx;
381 for(i=0; i<pxlNr; i++) {
382 if(!isfinite(img->p[i])) {
383 n++;
384 if(fix!=0) img->p[i]=0.0;
385 }
386 }
387 return(n);
388}

◆ imgXRange()

int imgXRange ( IMG * img,
double * xmin,
double * xmax )

Get the range of x values (times) in the image data.

Data is not modified. Data does not need to be sorted.

See also
imgMinMax, imgHasData
Returns
enum tpcerror (TPCERROR_OK when successful).
Parameters
imgPointer to IMG structure.
xminPointer to variable for min x value (NULL if not needed).
xmaxPointer to variable for max x value (NULL if not needed).

Definition at line 430 of file image.c.

437 {
438 if(xmin!=NULL) *xmin=nan("");
439 if(xmax!=NULL) *xmax=nan("");
440 if(img==NULL || !imgHasData(img)) return(TPCERROR_FAIL);
441 float f1=nanf(""), f2=nanf("");
442 for(int i=0; i<img->dimt; i++) {
443 if(isfinite(img->x1[i])) {
444 if(isnan(f1) || img->x1[i]<f1) f1=img->x1[i];
445 }
446 if(isfinite(img->x2[i])) {
447 if(isnan(f2) || img->x2[i]>f2) f2=img->x2[i];
448 }
449 }
450 if(xmin!=NULL) *xmin=f1;
451 if(xmax!=NULL) *xmax=f2;
452 if(isnan(f1) || isnan(f2)) return(TPCERROR_FAIL);
453 return(TPCERROR_OK);
454}