TPCCLIB
Loading...
Searching...
No Matches
imagedcm.c
Go to the documentation of this file.
1
6/*****************************************************************************/
7#include "tpcclibConfig.h"
8/*****************************************************************************/
9#include "tpcimage.h"
10#include "tpcfileutil.h"
11/*****************************************************************************/
12//#include <sys/stat.h>
13//#include <unistd.h>
14/*****************************************************************************/
15
16/*****************************************************************************/
25 IMG *img,
27 const char *fname,
29 TPCSTATUS *status
30) {
31 int verbose=0; if(status!=NULL) verbose=status->verbose;
32 if(verbose>0) {printf("%s(..., %s, ...)\n", __func__, fname); fflush(stdout);}
33
34 if(img==NULL || strnlen(fname, 2)<1) {
35 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
36 return(TPCERROR_FAIL);
37 }
38
39 /* Delete any old contents in data structure */
40 imgFree(img);
41
42 /* Read DICOM file */
43 DCMFILE dcm; dcmfileInit(&dcm);
44 int ret=dcmFileRead(fname, &dcm, 0, status);
45 if(ret!=TPCERROR_OK) {dcmfileFree(&dcm); return(ret);}
46
47//verbose=20;
48
49 /* Get modality */
51 {
52 DCMTAG tag; dcmTagSet(&tag, 0x0008, 0x0060); DCMITEM *iptr=dcmFindTag(dcm.item, 0, &tag, 0);
53 if(iptr==NULL) {
54 if(verbose>0) {fprintf(stderr, "Error: cannot find modality.\n"); fflush(stderr);}
55 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
56 dcmfileFree(&dcm); return(TPCERROR_NO_KEY);
57 }
58 char *buf=dcmValueString(iptr);
59 if(verbose>12) printf("Modality := '%s'\n", buf);
60 if(strncmp(buf, "PT", 2)==0) modality=IMG_MODALITY_PET;
61 else if(strncmp(buf, "CT", 2)==0) modality=IMG_MODALITY_CT;
62 else if(strncmp(buf, "MR", 2)==0) modality=IMG_MODALITY_MRI;
63 else if(strncmp(buf, "NM", 2)==0) modality=IMG_MODALITY_SPECT;
64 else if(verbose>0) fprintf(stderr, "Warning: modality '%s' not supported.\n", buf);
65 free(buf);
66 }
67
68 /* Get the number of frames and planes */
69 if(verbose>10) {printf("reading matrix dimensions\n"); fflush(stdout);}
70 unsigned short int imgdim[4];
71 ret=dcmImgDim(&dcm, imgdim, verbose-2);
72 if(ret!=0 || imgdim[0]<=0 || imgdim[1]<=0 || imgdim[2]<=0 || imgdim[3]<=0) {
73 if(verbose>0) {fprintf(stderr, "Error: cannot find matrix dimensions.\n"); fflush(stderr);}
74 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
75 dcmfileFree(&dcm); return(TPCERROR_NO_KEY);
76 }
77 unsigned short int dimx, dimy, sliceNr, frameNr;
78 dimx=imgdim[0]; dimy=imgdim[1]; sliceNr=imgdim[2]; frameNr=imgdim[3];
79 if(verbose>11)
80 printf("dimx := %u\ndimy := %u\ndimz := %u\ndimt := %u\n", dimx, dimy, sliceNr, frameNr);
81
82 /*
83 * Allocate memory for IMG data
84 */
85 ret=imgAllocate(img, sliceNr, dimy, dimx, frameNr, status);
86 if(ret!=TPCERROR_OK) {dcmfileFree(&dcm); return(ret);}
87
88
89 /* Get the status of decay correction and isotope */
90 ret=dcmImgIsotope(&dcm, &img->isot, &img->decayCorrection, verbose-2);
91 if(ret!=0 && verbose>0) {
92 fprintf(stderr, "Warning: decay correction and isotope unknown.\n"); fflush(stderr);
93 }
94 if(verbose>11) {
95 printf("decayCorrection := %s\n", decayDescr(img->decayCorrection));
96 printf("isotope := %s\n", isotopeName(img->isot));
97 fflush(stdout);
98 }
99
100 /* If decay is corrected, read time of decay correction; otherwise read start time */
101 char zeroDateTime[32]; zeroDateTime[0]=(char)0;
103 DCMTAG tag; dcmTagSet(&tag, 0x0018, 0x9701);
104 DCMITEM *iptr=dcmFindTag(dcm.item, 0, &tag, 0);
105 if(iptr!=NULL) dcmDT2intl(iptr->rd, zeroDateTime);
106 } else {
107 /* Get Acquisition DateTime */
108 DCMTAG tag; dcmTagSet(&tag, 0x0008, 0x002A);
109 DCMITEM *iptr=dcmFindTag(dcm.item, 0, &tag, 0);
110 if(iptr!=NULL) dcmDT2intl(iptr->rd, zeroDateTime);
111 }
112 if(!zeroDateTime[0]) {
113 if(verbose>0) fprintf(stderr, "Error: missing Acquisition Date and Time.\n");
114 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
115 imgFree(img); dcmfileFree(&dcm); return(TPCERROR_NO_KEY);
116 }
117 if(verbose>14) printf("zeroDateTime := %s\n", zeroDateTime);
118
119 /* Get frame times */
120 if(modality==IMG_MODALITY_PET || modality==IMG_MODALITY_SPECT) {
121 /* Initiate frame times to NaN */
122 for(unsigned short int i=0; i<img->dimt; i++) img->x1[i]=img->x2[i]=img->x[i]=nanf("");
123
124 /* Find Per Frame Functional Groups Sequence */
125 DCMTAG tag; dcmTagSet(&tag, 0x5200, 0x9230);
126 DCMITEM *iptr=dcmFindTag(dcm.item, 0, &tag, 0);
127 if(iptr==NULL) {
128 if(verbose>0) fprintf(stderr, "Error: Per Frame Functional Groups Sequence not found.\n");
129 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
130 imgFree(img); dcmfileFree(&dcm); return(TPCERROR_NO_KEY);
131 }
132 /* Loop through all Frame Content Sequences under it */
133 dcmTagSet(&tag, 0x0020, 0x9111);
134 DCMTAG tagstart; dcmTagSet(&tagstart, 0x0018, 0x9074);
135 DCMTAG tagdur; dcmTagSet(&tagdur, 0x0018, 0x9220);
136 DCMTAG tagfr; dcmTagSet(&tagfr, 0x0020, 0x9128);
137 DCMITEM *fptr=iptr->child_item;
138 while(fptr!=NULL) {
139 /* Find Frame Content Sequence */
140 iptr=dcmFindDownTag(fptr, 0, &tag, 0); if(iptr==NULL) break;
141 if(verbose>20) printf(" found Frame Content Sequence\n");
142 DCMITEM *jptr;
143 /* Find Temporal Position Index */
144 jptr=dcmFindDownTag(iptr->child_item, 0, &tagfr, 0);
145 if(jptr==NULL) {fptr=fptr->next_item; continue;}
146 if(verbose>30) dcmitemPrint(jptr);
147 unsigned short int frameIndex=(unsigned short int)(dcmitemGetInt(jptr)-1);
148 /* Find Frame Acquisition DateTime */
149 jptr=dcmFindDownTag(iptr->child_item, 0, &tagstart, 0);
150 char facqDateTime[32]; facqDateTime[0]=(char)0;
151 if(jptr!=NULL) dcmDT2intl(jptr->rd, facqDateTime);
152 if(!facqDateTime[0]) {
153 if(verbose>0) fprintf(stderr, "Error: missing Frame Acquisition DateTime.\n");
154 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
155 imgFree(img); dcmfileFree(&dcm); return(TPCERROR_NO_KEY);
156 }
157 if(verbose>20) printf("facqDateTime := %s\n", facqDateTime);
158 /* Calculate the Frame start time */
159 float t1=(float)strDateTimeDifference(facqDateTime, zeroDateTime);
160 /* Set frame start time */
161 if(frameIndex<img->dimt) {
162 if(isnan(img->x1[frameIndex])) {
163 /* Save frame start time, since there is no previous value for this frame */
164 img->x1[frameIndex]=t1;
165 if(verbose>29) printf("t1[%u]=%g\n", frameIndex, t1);
166 } else {
167 /* Check whether previous frame start time is the same as current */
168 if(!floatMatch(img->x1[frameIndex], t1, 0.001)) {
169 // not the same, this probably is whole-body study with more than one bed pos
170 if(verbose>1) printf(" different t1=%g\n", t1);
171 }
172 }
173 }
174
175 /* Find Frame Acquisition Duration */
176 jptr=dcmFindDownTag(iptr->child_item, 0, &tagdur, 0);
177 if(jptr==NULL) {fptr=fptr->next_item; continue;}
178 if(verbose>20) dcmitemPrint(jptr);
179 if(frameIndex<img->dimt) {
180 img->x2[frameIndex]=img->x1[frameIndex]+(float)0.001*dcmitemGetReal(jptr);
181 img->x[frameIndex]=0.5*(img->x1[frameIndex]+img->x2[frameIndex]);
182 }
183 /* prepare for the next frame */
184 fptr=iptr->next_item;
185 }
186 }
187
188 /* Get pixel sizes and image position */
189 {
190 double pxlsize[3];
191 ret=dcmImgPxlsize(&dcm, pxlsize, verbose-2);
192 if(ret!=0) {
193 if(verbose>0) fprintf(stderr, "Error: missing Pixel size.\n");
194 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
195 imgFree(img); dcmfileFree(&dcm); return(TPCERROR_NO_KEY);
196 }
197 img->sizex=(float)pxlsize[0];
198 img->sizey=(float)pxlsize[1];
199 img->sizez=(float)pxlsize[2];
200 if(verbose>13) printf(" pixel_size := %g x %g x %g\n", img->sizex, img->sizey, img->sizez);
201
202 double ipp[3];
203 int ret1=dcmImgPos(&dcm, ipp, verbose-2);
204 if(ret1==0) {
205 for(int i=0; i<3; i++) img->ipp[i]=ipp[i];
206 } else {
207 if(verbose>0) fprintf(stderr, "Warning: missing Image Position (Patient).\n");
208 }
209 double iop[6];
210 int ret2=dcmImgOrient(&dcm, iop, verbose-2);
211 if(ret2==0) {
212 for(int i=0; i<6; i++) img->iop[i]=iop[i];
213 } else {
214 if(verbose>0) fprintf(stderr, "Warning: missing Image Orientation (Patient).\n");
215 }
216 if(ret1==0 && ret2==0) { // calculate xform into IMG
217 double xform[16];
218 ret=dcmImgXform(iop, pxlsize, ipp, xform, verbose-2);
219 if(ret==0) {
220 img->xform[0]=1;
221 for(int i=0; i<12; i++) img->srow[i]=(float)xform[i];
222 double quatern[3], qoffset[3];
223 if(dcmXformToQuatern(xform, quatern, qoffset, verbose-2)==0) {
224 for(int i=0; i<3; i++) img->quatern[i]=(float)quatern[i];
225 for(int i=0; i<3; i++) img->quatern[3+i]=(float)qoffset[i];
226 }
227 }
228 }
229 }
230
231
232 /* Get Accession Number and write it in IMG as studyNr */
233 {
234 img->studyNr[0]=(char)0;
235 DCMITEM *iptr; DCMTAG tag; dcmTagSet(&tag, 0x0008, 0x0050);
236 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
237 if(iptr!=NULL) {
238 char *buf=dcmValueString(iptr); if(verbose>12) printf("Accession Number := '%s'\n", buf);
239 if(buf!=NULL && strlen(buf)>1) strncpyClean(img->studyNr, buf, MAX_STUDYNR_LEN+1);
240 free(buf);
241 }
242 if(!strcasecmp(img->studyNr, "empty")) img->studyNr[0]=(char)0;
243 }
244 /* If not successful, then try Patient ID */
245 if(!img->studyNr[0]) {
246 DCMITEM *iptr; DCMTAG tag; dcmTagSet(&tag, 0x0010, 0x0020);
247 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
248 if(iptr!=NULL) {
249 char *buf=dcmValueString(iptr); if(verbose>12) printf("Patient ID := '%s'\n", buf);
250 if(buf!=NULL && strlen(buf)>1) strncpyClean(img->studyNr, buf, MAX_STUDYNR_LEN+1);
251 free(buf);
252 }
253 }
254
255
256 /* Get pixel data scaling factors */
257 double rescale_intercept=0.0, rescale_slope=0.0;
258 {
259 DCMTAG tag; DCMITEM *iptr, *jptr;
260 dcmTagSet(&tag, 0x0040, 0x9096);
261 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
262 if(iptr==NULL) {
263 if(verbose>0) fprintf(stderr, "Error: missing Real World Value Mapping Sequence.\n");
264 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
265 imgFree(img); dcmfileFree(&dcm); return(TPCERROR_NO_KEY);
266 }
267 dcmTagSet(&tag, 0x0040, 0x9224);
268 jptr=dcmFindDownTag(iptr->child_item, 0, &tag, 0);
269 if(jptr!=NULL) rescale_intercept=dcmitemGetReal(jptr);
270 dcmTagSet(&tag, 0x0040, 0x9225);
271 jptr=dcmFindDownTag(iptr->child_item, 0, &tag, 0);
272 if(jptr!=NULL) rescale_slope=dcmitemGetReal(jptr);
273 if(rescale_slope<=0.0 && verbose>0) {
274 fprintf(stderr, "Warning: rescale_slope := %g\n", rescale_slope); fflush(stderr);
275 } else if(verbose>14) {
276 printf("rescale_slope := %g\n", rescale_slope);
277 printf("rescale_intercept := %g\n", rescale_intercept); // always 0 for PET
278 }
279 /* Unit */
280 dcmTagSet(&tag, 0x0040, 0x9210);
281 jptr=dcmFindDownTag(iptr->child_item, 0, &tag, 0);
282 if(jptr!=NULL) {
283 char *buf=dcmValueString(jptr); if(verbose>14) printf(" buf := '%s'\n", buf);
284 strClean(buf); img->cunit=unitIdentify(buf);
285 free(buf);
286 }
287 if(verbose>14) printf("image_unit := %s\n", unitName(img->cunit));
288 }
289
290 /* Fill IMG pixel values */
291 {
292 DCMTAG tag; dcmTagSet(&tag, 0x7fe0, 0x0010);
293 DCMITEM *iptr=dcmFindTag(dcm.item, 0, &tag, 0);
294 if(iptr==NULL || iptr->rd==NULL) {
295 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
296 imgFree(img); dcmfileFree(&dcm); return(TPCERROR_NO_DATA);
297 }
298 unsigned long long bi=0, byteNr=iptr->vl;
299 if(verbose>13) printf(" pixel data byteNr := %llu\n", byteNr);
300
301 char *cptr=iptr->rd;
302 short int s;
303 for(unsigned int ti=0; ti<img->dimt; ti++) {
304 for(unsigned int zi=0; zi<img->dimz; zi++)
305 for(unsigned int yi=0; yi<img->dimy; yi++)
306 for(unsigned int xi=0; xi<img->dimx; xi++) {
307 if(bi>=byteNr) {printf("missing pixel data\n"); fflush(stdout); break;}
308 memcpy(&s, cptr, 2); cptr+=2; bi+=2;
309 img->m[zi][yi][xi][ti]=(float)(rescale_slope*(double)s + rescale_intercept);
310 }
311 }
312 }
313
314
315 dcmfileFree(&dcm);
316
317 /* Set IMG header fields */
318 img->modality=modality;
321 strcpy(img->scanStart, zeroDateTime);
322
323 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
324 return(TPCERROR_OK);
325}
326/*****************************************************************************/
327
328/*****************************************************************************/
337 IMG *img,
339 const char *fname,
341 TPCSTATUS *status
342) {
343 if(status==NULL) return(TPCERROR_FAIL);
344 if(status->verbose>1) {printf("%s(..., %s, ...)\n", __func__, fname); fflush(stdout);}
345 if(img==NULL || img->dimt<1 || img->dimz<1) {
346 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA); return(status->error);}
347 if(fname==NULL || strnlen(fname, 1)<1) {
348 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FILENAME); return(status->error);}
349
350 /*
351 * Make DCMFILE data structure
352 */
353 DCMFILE dcm; dcmfileInit(&dcm);
354 /* Set Transfer UID */
356 {
357 DCMTAG tag;
358 unsigned int ul;
359 char buf[256];
360
361 /* Meta Element Group */
362 dcmTagSet(&tag, 0x0002, 0x0000); ul=0;
363 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_UL, 0xFFFFFFFF, (char*)&ul, 0);
364 dcmTagSet(&tag, 0x0002, 0x0001); // File Meta Information Version
365 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_OB, 2, "\0\1", 0);
366 dcmTagSet(&tag, 0x0002, 0x0002); // Media Stored SOP Class UID
367 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_UI, 0xFFFFFFFF, "1.2.840.10008.5.1.4.1.1.128", 0);
368 dcmTagSet(&tag, 0x0002, 0x0003); // Media Stored SOP Instance UID
369 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_UI, 0xFFFFFFFF, "1.2.826.0.1.3417726.3.0.20180616", 0);
370 dcmTagSet(&tag, 0x0002, 0x0010); // Transfer Syntax UID
371 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_UI, 0xFFFFFFFF, dcmTrUIDString(dcm.truid), 0);
372 dcmTagSet(&tag, 0x0002, 0x0012); // Implementation Class UID
373 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_UI, 0xFFFFFFFF, "1.3.6.1.4.1.25403.1.1.1", 0);
374 dcmTagSet(&tag, 0x0002, 0x0013); // Implementation Version Name
375 snprintf(buf, 256, "TPCCLIB_%d.%d.%d", tpcclib_VERSION_MAJOR, tpcclib_VERSION_MINOR, tpcclib_VERSION_PATCH);
376 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_SH, 0xFFFFFFFF, buf, 0);
377
378 /* Identifying Group */
379 dcmTagSet(&tag, 0x0008, 0x0000); ul=0;
380 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_UL, 0xFFFFFFFF, (char*)&ul, 0);
381 dcmTagSet(&tag, 0x0008, 0x0008); // Image Type
382 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_CS, 17, "ORIGINAL/PRIMARY", 0);
383 {
384 time_t t=time(NULL);
385 struct tm *local_tm; local_tm=localtime(&t);
386 dcmTagSet(&tag, 0x0008, 0x0012); // Instance Creation Date
387 strftime(buf, 256, "%Y%m%d", local_tm);
388 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_DA, 0xFFFFFFFF, buf, 0);
389 dcmTagSet(&tag, 0x0008, 0x0013); // Instance Creation Time
390 strftime(buf, 256, "%H%M%S", local_tm);
391 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_DA, 0xFFFFFFFF, buf, 0);
392 }
393 dcmTagSet(&tag, 0x0008, 0x0016); // SOP Class UID; see dcmsop.c
394 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_UI, 0xFFFFFFFF, "1.2.840.10008.5.1.4.1.1.128", 0);
395 dcmTagSet(&tag, 0x0008, 0x0018); // SOP Instance UID
396 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_UI, 0xFFFFFFFF, "1.2.826.0.1.3417726.3.0.20180616", 0);
397 dcmTagSet(&tag, 0x0008, 0x0060); // Modality
398 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_CS, 3, "PT", 0);
399
400 /* Acquisition Group */
401 dcmTagSet(&tag, 0x0018, 0x0000); ul=0;
402 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_UL, 0xFFFFFFFF, (char*)&ul, 0);
403 dcmTagSet(&tag, 0x0018, 0x0050); // Slice thickness (mm)
404 snprintf(buf, 256, "%g", img->sizez);
405 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_DS, 0xFFFFFFFF, buf, 0);
406 dcmTagSet(&tag, 0x0018, 0x1075); // half-life
407 if(img->isot!=ISOTOPE_UNKNOWN) {
408 snprintf(buf, 256, "%g", 60.0*isotopeHalflife(img->isot));
409 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_DS, 0xFFFFFFFF, buf, 0);
410 }
411
412 /* Relationship Group */
413 dcmTagSet(&tag, 0x0020, 0x0000); ul=0;
414 dcmAddItem(&dcm, NULL, 0, tag, DCM_VR_UL, 0xFFFFFFFF, (char*)&ul, 0);
415
416
417
418 }
419
420
421 /* Create folder, or if it already exists check that it is empty */
422 if(pathExist(fname)) {
423 if(status->verbose>2) {
424 fprintf(stdout, " checking that folder '%s' is empty\n", fname); fflush(stdout);}
425 if(pathFileNr(fname)>0) {
426 dcmfileFree(&dcm);
427 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FILE_EXISTS);
428 return(status->error);
429 }
430 } else {
431 if(status->verbose>2) {
432 fprintf(stdout, " creating subdirectory '%s'\n", fname); fflush(stdout);}
433 if(pathCreate(fname)) {
434 dcmfileFree(&dcm);
435 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
436 return(status->error);
437 }
438 }
439
440 /*
441 * Write each image plane in its own DICOM file
442 */
443 for(int zi=0; zi<img->dimz; zi++) {
444 char dname[strlen(fname)+25];
445 snprintf(dname, strlen(fname)+25, "%s/%0*d.dcm", fname, 1+(int)floor(log10(img->dimz)), 1+zi);
446 if(status->verbose>2) {printf(" writing '%s'\n", dname); fflush(stdout);}
447
448 /* Write */
449 dcmFileWrite(dname, &dcm, status);
450 if(status->error!=TPCERROR_OK) {
451 dcmfileFree(&dcm);
452 dcmFileRemove(dname, NULL);
453 pathRemove(fname);
454 return(status->error);
455 }
456 } // next plane
457 dcmfileFree(&dcm);
458
459 if(0) { // Remove files and empty folder in case of error
460 dcmFileRemove(fname, NULL);
461 pathRemove(fname);
462 }
463
464 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
465 return(TPCERROR_OK);
466}
467/*****************************************************************************/
468
469/*****************************************************************************/
470
double strDateTimeDifference(const char *dt1, const char *dt0)
Definition datetime.c:519
int dcmAddItem(DCMFILE *dcm, DCMITEM *d, short int aschild, DCMTAG tag, dcmvr vr, unsigned int vl, char *rd, const int verbose)
Definition dcmdata.c:501
long int dcmitemGetInt(DCMITEM *d)
Definition dcmdata.c:295
void dcmfileInit(DCMFILE *d)
Definition dcmdata.c:22
void dcmTagSet(DCMTAG *tag, unsigned short int group, unsigned short int element)
Definition dcmdata.c:483
DCMITEM * dcmFindTag(DCMITEM *d, const short int omit, DCMTAG *tag, const int verbose)
Definition dcmdata.c:375
DCMITEM * dcmFindDownTag(DCMITEM *d, const short int omit, DCMTAG *tag, const int verbose)
Definition dcmdata.c:428
void dcmfileFree(DCMFILE *d)
Definition dcmdata.c:67
void dcmitemPrint(DCMITEM *d)
Definition dcmdata.c:467
double dcmitemGetReal(DCMITEM *d)
Definition dcmdata.c:331
char * dcmValueString(DCMITEM *d)
Definition dcmdata.c:141
int dcmFileRemove(const char *filename, TPCSTATUS *status)
Remove DICOM files belonging to one image.
Definition dcmfile.c:270
int dcmImgPxlsize(DCMFILE *d, double *pxlsize, const int verbose)
Definition dcmimage.c:320
int dcmImgDim(DCMFILE *d, unsigned short int *imgdim, const int verbose)
Definition dcmimage.c:232
int dcmImgOrient(DCMFILE *d, double *iop, const int verbose)
Definition dcmimage.c:387
int dcmImgIsotope(DCMFILE *d, isotope *isot, decaycorrection *dc, const int verbose)
Definition dcmimage.c:24
int dcmImgPos(DCMFILE *d, double *imgpos, const int verbose)
Definition dcmimage.c:121
int dcmXformToQuatern(double *xform, double *quatern, double *qoffset, const int verbose)
Definition dcmimage.c:540
int dcmImgXform(double *iop, double *xyzMM, double *imgPos, double *xform, const int verbose)
Definition dcmimage.c:431
int dcmFileRead(const char *filename, DCMFILE *dcm, const short int headerOnly, TPCSTATUS *status)
Definition dcmio.c:768
int dcmFileWrite(const char *filename, DCMFILE *dcm, TPCSTATUS *status)
Definition dcmio.c:852
char * dcmTrUIDString(dcmtruid id)
Definition dcmuid.c:105
char * dcmDT2intl(const char *orig, char *intl)
Definition dcmvr.c:225
char * decayDescr(decaycorrection d)
Definition decay.c:32
unsigned short int pathFileNr(const char *pathname)
Definition filexist.c:33
int floatMatch(const float v1, const float v2, const float lim)
Definition floatutil.c:27
void imgFree(IMG *img)
Definition image.c:107
int imgAllocate(IMG *img, const unsigned int dimz, const unsigned int dimy, const unsigned int dimx, const unsigned int dimt, TPCSTATUS *status)
Definition image.c:126
int imgReadDICOM(IMG *img, const char *fname, TPCSTATUS *status)
Definition imagedcm.c:23
int imgWriteDICOM(IMG *img, const char *fname, TPCSTATUS *status)
Definition imagedcm.c:335
char * isotopeName(int isotope_code)
Definition isotope.c:101
double isotopeHalflife(int isotope_code)
Definition isotope.c:62
int pathExist(const char *pathname)
Definition pathexist.c:17
int pathCreate(const char *pathname)
Definition pathexist.c:81
int pathRemove(const char *pathname)
Definition pathexist.c:43
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
size_t strnlen(const char *s, size_t n)
Definition stringext.c:566
int strncpyClean(char *s1, const char *s2, int maxlen)
Definition stringext.c:321
int strClean(char *s)
Definition stringext.c:389
dcmtruid truid
Definition tpcdcm.h:162
DCMITEM * item
Definition tpcdcm.h:164
struct DCMITEM * child_item
Definition tpcdcm.h:143
struct DCMITEM * next_item
Definition tpcdcm.h:147
unsigned int vl
Definition tpcdcm.h:141
char * rd
Definition tpcdcm.h:152
Definition tpcimage.h:82
float sizex
Definition tpcimage.h:119
unsigned short int dimx
Definition tpcimage.h:112
float * x1
Definition tpcimage.h:180
imgmodality modality
Definition tpcimage.h:100
unit cunit
Definition tpcimage.h:203
float **** m
Definition tpcimage.h:161
imgformat format
Definition tpcimage.h:103
float ipp[3]
Definition tpcimage.h:141
float * x2
Definition tpcimage.h:182
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
unsigned short int dimt
Definition tpcimage.h:110
float sizey
Definition tpcimage.h:121
imgcontent content
Definition tpcimage.h:97
char scanStart[20]
Definition tpcimage.h:94
unsigned short int dimz
Definition tpcimage.h:116
unsigned short int dimy
Definition tpcimage.h:114
float * x
Definition tpcimage.h:184
decaycorrection decayCorrection
Definition tpcimage.h:91
char studyNr[MAX_STUDYNR_LEN+1]
Definition tpcimage.h:85
isotope isot
Definition tpcimage.h:88
float sizez
Definition tpcimage.h:123
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
@ DCM_VR_UI
DICOM unique identifier (UID), max 64 bytes.
Definition tpcdcm.h:117
@ DCM_VR_CS
DICOM code (control) string, max 16 bytes.
Definition tpcdcm.h:95
@ DCM_VR_SH
DICOM short string, max 16 chars.
Definition tpcdcm.h:110
@ DCM_VR_OB
DICOM other byte string, even bytes, endian insensitive.
Definition tpcdcm.h:104
@ DCM_VR_DA
DICOM date in format YYYYMMDD, 8 bytes fixed.
Definition tpcdcm.h:96
@ DCM_VR_UL
DICOM unsigned long (32-bit) integer, 4 bytes fixed.
Definition tpcdcm.h:118
@ DCM_VR_DS
DICOM decimal string, max 16 bytes.
Definition tpcdcm.h:97
@ DCM_TRUID_LEE
Little Endian Explicit VR.
Definition tpcdcm.h:60
@ TPCERROR_FAIL
General error.
@ TPCERROR_NO_KEY
Key not found.
@ TPCERROR_FILE_EXISTS
File exists.
@ TPCERROR_OK
No error.
@ TPCERROR_INVALID_FILENAME
Invalid file name.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
int unitIdentify(const char *s)
Definition units.c:162
char * unitName(int unit_code)
Definition units.c:143
#define MAX_STUDYNR_LEN
Define max study number length.
Header file for libtpcfileutil.
Header file for libtpcimage.
imgmodality
Definition tpcimage.h:56
@ IMG_MODALITY_MRI
MRI.
Definition tpcimage.h:61
@ IMG_MODALITY_CT
CT.
Definition tpcimage.h:60
@ IMG_MODALITY_SPECT
SPECT.
Definition tpcimage.h:59
@ IMG_MODALITY_UNKNOWN
Unknown modality.
Definition tpcimage.h:57
@ IMG_MODALITY_PET
PET.
Definition tpcimage.h:58
@ IMG_FORMAT_DICOM
DICOM.
Definition tpcimage.h:34
@ IMG_CONTENT_IMAGE
Image data.
Definition tpcimage.h:72
@ DECAY_CORRECTED
Data is corrected for physical decay.
Definition tpcisotope.h:81
@ ISOTOPE_UNKNOWN
Unknown.
Definition tpcisotope.h:51