TPCCLIB
Loading...
Searching...
No Matches
dcmmatrix.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10#include <time.h>
11#include <string.h>
12/*****************************************************************************/
13#include "tpcextensions.h"
14/*****************************************************************************/
15#include "tpcdcm.h"
16/*****************************************************************************/
17
18/*****************************************************************************/
24 DCMMATRIX *m
25) {
26 if(m==NULL) return;
27 m->filename=NULL;
28 m->acqDate[0]=m->acqTime[0]=(char)0;
29 m->frame=m->plane=0;
30 m->frameStart=m->frameDur=0.0;
31}
32/*****************************************************************************/
33
34/*****************************************************************************/
42 DCMMATRIX *m
43) {
44 if(m==NULL) return;
45 if(m->filename!=NULL) free(m->filename);
47}
48/*****************************************************************************/
49
50/*****************************************************************************/
56 DCMML *d
57) {
58 if(d==NULL) return;
59 d->nr=d->anr=0;
60 d->m=(DCMMATRIX*)NULL;
61}
62/*****************************************************************************/
63
64/*****************************************************************************/
72 DCMML *d
73) {
74 if(d==NULL) return;
75 if(d->m!=NULL) {
76 for(unsigned int i=0; i<d->anr; i++) dcmmatrixFree(d->m+i);
77 free(d->m);
78 }
79 dcmmlInit(d);
80}
81/*****************************************************************************/
82
83/*****************************************************************************/
92 DCMML *d,
95 int mNr
96) {
97 if(d==NULL) return TPCERROR_FAIL;
98 /* Check if there is enough space already */
99 unsigned int newNr, addNr;
100 newNr=d->nr+mNr;
101 if(d->anr>=newNr) return TPCERROR_OK;
102 addNr=newNr-d->anr;
103
104 /* (Re)allocate memory. */
105 DCMMATRIX *mptr;
106 mptr=(DCMMATRIX*)realloc(d->m, sizeof(DCMMATRIX)*newNr);
107 if(mptr==NULL) return TPCERROR_OUT_OF_MEMORY;
108 d->m=mptr;
109 mptr=d->m+d->anr; for(unsigned int i=0; i<addNr; i++) dcmmatrixInit(mptr++);
110 d->anr=newNr;
111 return TPCERROR_OK;
112}
113/*****************************************************************************/
114
115/*****************************************************************************/
122 IFT *ift,
124 DCMML *ml,
126 TPCSTATUS *status
127) {
128 int verbose=0; if(status!=NULL) verbose=status->verbose;
129 if(verbose>1) printf("%s()\n", __func__);
130 if(ift==NULL || ml==NULL) {
131 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
132 return TPCERROR_FAIL;
133 }
134 if(ift->keyNr<1) {
135 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
136 return TPCERROR_NO_DATA;
137 }
138
139 /* Delete any previous data */
140 dcmmlFree(ml);
141
142 /*
143 * Read the first file in list
144 */
145 int fi=0, ret=TPCERROR_OK;
146 DCMFILE dcm; dcmfileInit(&dcm);
147 ret=dcmFileRead(ift->item[fi].value, &dcm, 1, status);
148 if(ret!=TPCERROR_OK) {dcmfileFree(&dcm); return(ret);}
149
150 /* Read some information common to the whole image */
151 DCMTAG tag;
152 DCMITEM *iptr;
153
154 /* Get and check the Image Type */
155 int dynamic=0; // 0=no, 1=yes
156 tag.group=0x0008; tag.element=0x0008;
157 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
158 if(iptr==NULL) {
159 ret=TPCERROR_NO_KEY; statusSet(status, __func__, __FILE__, __LINE__, ret);
160 dcmfileFree(&dcm); return(ret);
161 }
162 /* Check if dynamic; see DICOM 3.3 C.7.6.16.2.2.6
163 https://dicom.nema.org/MEDICAL/dicom/current/output/chtml/part03/sect_C.7.6.16.2.html
164 */
165 {
166 char *buf=dcmValueString(iptr);
167 if(verbose>2) printf("imageType := %s\n", buf);
168 if(strcasestr(buf, "DYNAMIC")!=NULL) dynamic=1; else dynamic=0;
169 free(buf);
170 }
171 if(verbose>1) {printf("dynamic := %d\n", dynamic); fflush(stdout);}
172
173 /* Check whether Per-frame Functional Groups Sequence is set */
174 int multiframe=0; // 0=no, 1=yes
175 tag.group=0x5200; tag.element=0x9230;
176 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
177 if(iptr!=NULL) {
178 if(verbose>1) fprintf(stderr, "Notice: Per-frame Functional Groups Sequence is available.\n");
179 multiframe=1;
180 }
181
182
183 if(multiframe) { /* Multi-frame file */
184
185 /* Get the number of frames and planes */
186 if(verbose>1) {printf("reading frame and slice number\n"); fflush(stdout);}
187 unsigned short int frameNr=0;
188 /* Get frame number from 'Temporal position index' */
189 tag.group=0x0020; tag.element=0x9128;
190 int a, b;
191 if(dcmTagIntRange(dcm.item, &tag, &a, &b, verbose-100)==0) frameNr=b;
192 if(verbose>1) printf("frameNr := %u\n", frameNr);
193 unsigned short int sliceNr=0;
194 /* Get plane number from 'In Stack Position Number' */
195 tag.group=0x0020; tag.element=0x9057;
196 if(dcmTagIntRange(dcm.item, &tag, &a, &b, verbose-100)==0) sliceNr=b;
197 else {
198 /* Get plane number from 'Dimension Index Values' */
199 tag.group=0x0020; tag.element=0x9157;
200 if(dcmTagIntRange(dcm.item, &tag, &a, &b, verbose-1)==0) sliceNr=b;
201 }
202 if(verbose>1) printf("sliceNr := %u\n", sliceNr);
203 if(frameNr<=0 || sliceNr<=0) {
204 if(verbose>0) fprintf(stderr, "Error: cannot find frame/slice number.\n");
205 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
206 dcmfileFree(&dcm); return(TPCERROR_NO_KEY);
207 }
208
209 /* Get Decay Correction */
210 short unsigned int decayCorrection=0; // 0=NO, 1=YES
211 tag.group=0x0018; tag.element=0x9758;
212 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
213 if(iptr!=NULL) {
214 char *buf=dcmValueString(iptr);
215 if(verbose>2) printf("Decay Correction := '%s'\n", buf);
216 if(strcasestr(buf, "YES")!=NULL) decayCorrection=1;
217 free(buf);
218 }
219 if(verbose>1) printf("decayCorrection := %d\n", decayCorrection);
220
221 /* If decay is corrected, read time of decay correction; otherwise read start time */
222 char zeroDateTime[32]; zeroDateTime[0]=(char)0;
223 if(decayCorrection==0) {
224 /* Get Acquisition DateTime */
225 tag.group=0x0008; tag.element=0x002A;
226 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
227 if(iptr!=NULL) dcmDT2intl(iptr->rd, zeroDateTime);
228 } else {
229 tag.group=0x0018; tag.element=0x9701;
230 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
231 if(iptr!=NULL) dcmDT2intl(iptr->rd, zeroDateTime);
232 }
233 if(!zeroDateTime[0]) {
234 if(verbose>0) fprintf(stderr, "Error: missing Acquisition Date and Time.\n");
235 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
236 dcmfileFree(&dcm); return(TPCERROR_NO_KEY);
237 }
238 if(verbose>4) printf("zeroDateTime := %s\n", zeroDateTime);
239
240 /* Initially allocate for frameNr x sliceNr matrices */
241 ret=dcmmlAllocate(ml, sliceNr*frameNr);
242 if(ret!=TPCERROR_OK) {
243 statusSet(status, __func__, __FILE__, __LINE__, ret);
244 dcmfileFree(&dcm); return ret;
245 }
246
247 /*
248 * Get the information from one matrix at a time
249 */
250 /* Find Per Frame Functional Groups Sequence */
251 tag.group=0x5200; tag.element=0x9230;
252 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
253 if(iptr==NULL) {
254 if(verbose>0) {
255 fprintf(stderr, "Error: cannot find Per Frame Functional Groups Sequence.\n");
256 fflush(stderr);
257 }
258 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_KEY);
259 dcmmlFree(ml); dcmfileFree(&dcm); return(TPCERROR_NO_KEY);
260 }
261 /* Loop through all Frame Content Sequences under it */
262 tag.group=0x0020; tag.element=0x9111;
263 DCMTAG tagstart; tagstart.group=0x0018; tagstart.element=0x9074;
264 DCMTAG tagdur; tagdur.group=0x0018; tagdur.element=0x9220;
265 DCMTAG tagfr; tagfr.group=0x0020; tagfr.element=0x9128;
266 DCMITEM *fptr=iptr->child_item;
267 while(fptr!=NULL) {
268 /* Find Frame Content Sequence */
269 iptr=dcmFindDownTag(fptr, 0, &tag, 0); if(iptr==NULL) break; // not an error!
270 if(verbose>10) printf(" found Frame Content Sequence\n");
271 /* Check that we have room */
272 if(ml->nr>=ml->anr) {
273 ret=dcmmlAllocate(ml, 100);
274 if(ret!=TPCERROR_OK) break;
275 }
276 /* Set file name */
277 ml->m[ml->nr].filename=strdup(ift->item[0].value);
278 /* Find Temporal Position Index */
279 DCMITEM *jptr;
280 jptr=dcmFindDownTag(iptr->child_item, 0, &tagfr, 0);
281 if(jptr==NULL) {
282 if(verbose>0) {printf("cannot find Temporal Position Index.\n"); fflush(stdout);}
283 ret=TPCERROR_NO_KEY; break;
284 }
285 if(verbose>20) dcmitemPrint(jptr);
286 ml->m[ml->nr].frame=(unsigned int)dcmitemGetInt(jptr);
287 //unsigned short int frameIndex=(unsigned short int)(dcmitemGetInt(jptr)-1);
288 /* Find slice index */
289 DCMTAG tagpl; tagpl.group=0x0020; tagpl.element=0x9057;
290 jptr=dcmFindDownTag(iptr->child_item, 0, &tagpl, 0);
291 if(jptr==NULL) {
292 tagpl.group=0x0020; tagpl.element=0x9157;
293 jptr=dcmFindDownTag(iptr->child_item, 0, &tagpl, 0);
294 }
295 if(jptr==NULL) {
296 if(verbose>0) {printf("cannot find Slice Index.\n"); fflush(stdout);}
297 ret=TPCERROR_NO_KEY; break;
298 }
299 if(verbose>20) dcmitemPrint(jptr);
300 ml->m[ml->nr].plane=(unsigned int)dcmitemGetInt(jptr);
301 /* Find Frame Acquisition DateTime */
302 jptr=dcmFindDownTag(iptr->child_item, 0, &tagstart, 0);
303 char facqDateTime[32]; facqDateTime[0]=(char)0;
304 if(jptr!=NULL) dcmDT2intl(jptr->rd, facqDateTime);
305 if(!facqDateTime[0]) {
306 if(verbose>0) {printf("cannot find Frame Acquisition DateTime.\n"); fflush(stdout);}
307 ret=TPCERROR_NO_KEY; break;
308 }
309 if(verbose>20) printf("facqDateTime := %s\n", facqDateTime);
310 strlcpy(ml->m[ml->nr].acqDate, facqDateTime, 11);
311 if(strlen(facqDateTime)>17) strlcpy(ml->m[ml->nr].acqTime, facqDateTime+11, 9);
312 /* Calculate the Frame start time */
313 ml->m[ml->nr].frameStart=strDateTimeDifference(facqDateTime, zeroDateTime);
314 /* Find Frame Acquisition Duration */
315 jptr=dcmFindDownTag(iptr->child_item, 0, &tagdur, 0);
316 if(jptr!=NULL) ml->m[ml->nr].frameDur=0.001*dcmitemGetReal(jptr);
317
318 /* prepare for the next matrix */
319 fptr=iptr->next_item;
320 ml->nr++;
321 }
322
323 dcmfileFree(&dcm);
324 if(ret!=TPCERROR_OK) {
325 statusSet(status, __func__, __FILE__, __LINE__, ret);
326 dcmmlFree(ml);
327 return(ret);
328 }
329
330 } else { /* Single-frame files */
331
332 /* Get the number of frames (time slices) */
333 unsigned short int frameNr=0;
334 tag.group=0x0054; tag.element=0x0101;
335 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
336 if(iptr!=NULL) {
337 frameNr=(unsigned short int)dcmitemGetInt(iptr);
338 } else {
339 if(dynamic!=0) { // error, if dynamic
340 ret=TPCERROR_NO_KEY; statusSet(status, __func__, __FILE__, __LINE__, ret);
341 dcmfileFree(&dcm); return(ret);
342 } else { // assume 1, if static or whole-body
343 frameNr=1;
344 }
345 }
346 if(verbose>1) printf("frameNr := %u\n", frameNr);
347
348 /* Get the number of slices (needed to understand image index) */
349 unsigned short int sliceNr=0;
350 tag.group=0x0054; tag.element=0x0081;
351 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
352 if(iptr==NULL) {
353 ret=TPCERROR_NO_KEY; statusSet(status, __func__, __FILE__, __LINE__, ret);
354 dcmfileFree(&dcm); return(ret);
355 }
356 sliceNr=(unsigned short int)dcmitemGetInt(iptr);
357 if(verbose>1) printf("sliceNr := %u\n", sliceNr);
358
359 /* Get Decay correction type */
360 short unsigned int decayCorrection=0; // 0=NONE, 1=START, 2=ADMIN
361 tag.group=0x0054; tag.element=0x1102;
362 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
363 if(iptr!=NULL) {
364 char *buf=dcmValueString(iptr);
365 if(verbose>2) printf("Decay Correction := %s\n", buf);
366 if(strcasecmp(buf, "NONE")==0) decayCorrection=0;
367 else if(strcasecmp(buf, "START")==0) decayCorrection=1;
368 else if(strcasecmp(buf, "ADMIN")==0) decayCorrection=2;
369 free(buf);
370 }
371
372 /* If decay is corrected to tracer administration time, the we must read it */
373 char injDateTime[32]; injDateTime[0]=(char)0;
374 if(decayCorrection==2) {
375 /* Get the Tracer Start DateTime */
376 tag.group=0x0018; tag.element=0x1078;
377 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
378 if(iptr!=NULL) {
379 if(dcmDT2intl(iptr->rd, injDateTime)==NULL) iptr=NULL;
380 }
381 /* If not successful, the try other tags */
382 if(iptr==NULL) {
383 char s1[16], s2[16];
384 /* Get the Tracer Start Time */
385 tag.group=0x0018; tag.element=0x1072;
386 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
387 if(iptr!=NULL) {
388 /* Get the Series Date */
389 tag.group=0x0008; tag.element=0x0021;
390 DCMITEM *jptr=dcmFindTag(dcm.item, 0, &tag, 0);
391 if(jptr!=NULL) {
392 if(dcmDA2intl(jptr->rd, s1)!=NULL && dcmTM2intl(iptr->rd, s2)!=NULL)
393 sprintf(injDateTime, "%s %s", s1, s2);
394 }
395 }
396 }
397 if(injDateTime[0] && verbose>3) printf("injection_time := %s\n", injDateTime);
398 }
399
400 /* Get the Series DateTime
401 https://dicom.nema.org/MEDICAL/dicom/current/output/chtml/part03/sect_C.8.9.html#figure_C.8.9.1.1.11-1a
402 */
403 char seriesDateTime[32]; seriesDateTime[0]=(char)0;
404 tag.group=0x0008; tag.element=0x0021;
405 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
406 if(iptr!=NULL) {
407 tag.group=0x0008; tag.element=0x0031;
408 DCMITEM *jptr=dcmFindTag(dcm.item, 0, &tag, 0);
409 if(jptr!=NULL) {
410 char s1[16], s2[16];
411 if(dcmDA2intl(iptr->rd, s1)!=NULL && dcmTM2intl(jptr->rd, s2)!=NULL)
412 sprintf(seriesDateTime, "%s %s", s1, s2);
413 }
414 }
415 if(seriesDateTime[0] && verbose>3) printf("seriesDateTime := %s\n", seriesDateTime);
416
417
418 /* Initially allocate for frameNr x sliceNr matrices */
419 ret=dcmmlAllocate(ml, sliceNr*frameNr);
420 if(ret!=TPCERROR_OK) {
421 statusSet(status, __func__, __FILE__, __LINE__, ret);
422 dcmfileFree(&dcm); return ret;
423 }
424
425
426 /*
427 * Get the information from one file at a time
428 */
429 //char startDateTime[32]; startDateTime[0]=(char)0;
430 //int fi=0, beds=0;
431 do {
432
433 /* Get the Image Index; DICOM PS3.3 C.8.9.4.1.9 */
434 unsigned short int imageIndex=0;
435 tag.group=0x0054; tag.element=0x1330;
436 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
437 if(iptr==NULL) {ret=TPCERROR_NO_KEY; break;}
438 imageIndex=(unsigned short int)dcmitemGetInt(iptr);
439 /* Calculate the current frame and slice (index starting from 0) */
440 unsigned short int frameIndex, sliceIndex;
441 {
442 div_t meh=div(imageIndex-1, sliceNr);
443 frameIndex=meh.quot;
444 sliceIndex=meh.rem;
445 }
446 /* Set file name, plane, and frame into matrix list */
447 if(ml->nr>=ml->anr) {
448 ret=dcmmlAllocate(ml, 100);
449 if(ret!=TPCERROR_OK) break;
450 }
451 ml->m[ml->nr].filename=strdup(ift->item[fi].value);
452 ml->m[ml->nr].plane=1+sliceIndex;
453 ml->m[ml->nr].frame=1+frameIndex;
454
455 /* Get acquisition date and time */
456 char acqDateTime[32]; acqDateTime[0]=(char)0;
457 /* Try first Acquisition Datetime */
458 tag.group=0x0008; tag.element=0x002A;
459 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
460 if(iptr!=NULL) dcmDT2intl(iptr->rd, acqDateTime);
461 /* If that did not work, try Acquisition Date and Time */
462 if(!acqDateTime[0]) {
463 tag.group=0x0008; tag.element=0x0022;
464 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
465 if(iptr!=NULL) {
466 tag.group=0x0008; tag.element=0x0032;
467 DCMITEM *jptr=dcmFindTag(dcm.item, 0, &tag, 0);
468 if(jptr!=NULL) {
469 char s1[16], s2[16];
470 if(dcmDA2intl(iptr->rd, s1)!=NULL && dcmTM2intl(jptr->rd, s2)!=NULL)
471 sprintf(acqDateTime, "%s %s", s1, s2);
472 }
473 }
474 }
475 if(acqDateTime[0]) {
476 strlcpy(ml->m[ml->nr].acqDate, acqDateTime, 11);
477 if(strlen(acqDateTime)>17) strlcpy(ml->m[ml->nr].acqTime, acqDateTime+11, 9);
478 }
479
480 /* Calculate the Frame start time, if possible */
481 if(acqDateTime[0]) {
482 double t1=nan("");
483 if(decayCorrection==2 && injDateTime[0]) {
484 /* Injection time is the reference time */
485 t1=strDateTimeDifference(acqDateTime, injDateTime);
486 ml->m[ml->nr].frameStart=t1;
487 } else if(seriesDateTime[0]) {
488 /* Use series time, for now */
489 t1=strDateTimeDifference(acqDateTime, seriesDateTime);
490 ml->m[ml->nr].frameStart=t1;
491 }
492 }
493
494 /* Get Actual Frame Duration */
495 tag.group=0x0018; tag.element=0x1242;
496 iptr=dcmFindTag(dcm.item, 0, &tag, 0);
497 if(iptr!=NULL) ml->m[ml->nr].frameDur=0.001*dcmitemGetReal(iptr);
498
499
500 /* Done with this file */
501 ml->nr++;
502 dcmfileFree(&dcm);
503
504 /* Read the next file in list */
505 fi++; if(fi>=ift->keyNr) {ret=TPCERROR_OK; break;}
506 ret=dcmFileRead(ift->item[fi].value, &dcm, 1, status);
507 if(ret!=TPCERROR_OK) break;
508
509 } while(1);
510 dcmfileFree(&dcm);
511 if(ret!=TPCERROR_OK) {
512 statusSet(status, __func__, __FILE__, __LINE__, ret);
513 dcmmlFree(ml);
514 return(ret);
515 }
516 }
517
518
519 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
520 return(TPCERROR_OK);
521}
522/*****************************************************************************/
523
524/*****************************************************************************/
526
527static int dcmmlQSortPlane(const void *m1, const void *m2)
528{
529 if(((DCMMATRIX*)m1)->plane < ((DCMMATRIX*)m2)->plane) return(-1);
530 else if(((DCMMATRIX*)m1)->plane > ((DCMMATRIX*)m2)->plane) return(+1);
531 else if(((DCMMATRIX*)m1)->frame < ((DCMMATRIX*)m2)->frame) return(-1);
532 else if(((DCMMATRIX*)m1)->frame > ((DCMMATRIX*)m2)->frame) return(+1);
533 else return(0);
534}
536
542 DCMML *d,
544 TPCSTATUS *status
545) {
546 int verbose=0; if(status!=NULL) verbose=status->verbose;
547 if(verbose>0) printf("%s()\n", __func__);
548 /* Check that required data exists */
549 if(d==NULL) {
550 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
551 return TPCERROR_NO_DATA;
552 }
553 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
554 if(d->nr<2) return TPCERROR_OK;
555 qsort(d->m, d->nr, sizeof(DCMMATRIX), dcmmlQSortPlane);
556 return TPCERROR_OK;
557}
558/*****************************************************************************/
559
560/*****************************************************************************/
double strDateTimeDifference(const char *dt1, const char *dt0)
Definition datetime.c:519
long int dcmitemGetInt(DCMITEM *d)
Definition dcmdata.c:295
void dcmfileInit(DCMFILE *d)
Definition dcmdata.c:22
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
int dcmTagIntRange(DCMITEM *d, DCMTAG *tag, int *mi, int *ma, const int verbose)
Definition dcmdata.c:631
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 dcmFileRead(const char *filename, DCMFILE *dcm, const short int headerOnly, TPCSTATUS *status)
Definition dcmio.c:768
int dcmMListRead(IFT *ift, DCMML *ml, TPCSTATUS *status)
Definition dcmmatrix.c:120
void dcmmlInit(DCMML *d)
Definition dcmmatrix.c:54
void dcmmlFree(DCMML *d)
Definition dcmmatrix.c:70
int dcmmlSortByPlane(DCMML *d, TPCSTATUS *status)
Definition dcmmatrix.c:540
void dcmmatrixInit(DCMMATRIX *m)
Definition dcmmatrix.c:22
int dcmmlAllocate(DCMML *d, int mNr)
Definition dcmmatrix.c:89
void dcmmatrixFree(DCMMATRIX *m)
Definition dcmmatrix.c:40
char * dcmDT2intl(const char *orig, char *intl)
Definition dcmvr.c:225
char * dcmDA2intl(const char *orig, char *intl)
Definition dcmvr.c:179
char * dcmTM2intl(const char *orig, char *intl)
Definition dcmvr.c:202
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
char * strdup(const char *s)
Definition stringext.c:185
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
char * strcasestr(const char *haystack, const char *needle)
Definition stringext.c:155
DCMITEM * item
Definition tpcdcm.h:164
struct DCMITEM * child_item
Definition tpcdcm.h:143
struct DCMITEM * next_item
Definition tpcdcm.h:147
char * rd
Definition tpcdcm.h:152
double frameDur
Definition tpcdcm.h:188
unsigned int plane
Definition tpcdcm.h:184
double frameStart
Definition tpcdcm.h:186
char * filename
Definition tpcdcm.h:175
char acqTime[16]
Definition tpcdcm.h:179
char acqDate[16]
Definition tpcdcm.h:177
unsigned int frame
Definition tpcdcm.h:182
DCMMATRIX * m
Definition tpcdcm.h:198
unsigned int anr
Definition tpcdcm.h:196
unsigned int nr
Definition tpcdcm.h:194
unsigned short int element
Definition tpcdcm.h:44
unsigned short int group
Definition tpcdcm.h:42
char * value
Definition tpcift.h:37
Definition tpcift.h:43
IFT_ITEM * item
Definition tpcift.h:57
int keyNr
Definition tpcift.h:47
int verbose
Verbose level, used by statusPrint() etc.
Header file for libtpcdcm.
Header file for library libtpcextensions.
@ TPCERROR_FAIL
General error.
@ TPCERROR_OUT_OF_MEMORY
Cannot allocate memory.
@ TPCERROR_NO_KEY
Key not found.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.