11typedef struct DCM_VR {
31static DCM_VR dcm_vr[]={
32 {
DCM_VR_AE,
"AE", 0, 0, 16,
"application entity"},
34 {
DCM_VR_AT,
"AT", 0, 0, 4,
"attribute tag"},
35 {
DCM_VR_CS,
"CS", 0, 0, 16,
"code string"},
37 {
DCM_VR_DS,
"DS", 0, 0, 16,
"decimal string"},
38 {
DCM_VR_DT,
"DT", 0, 0, 26,
"date and time"},
39 {
DCM_VR_FL,
"FL", 0, 1, 4,
"floating point single precision"},
40 {
DCM_VR_FD,
"FD", 0, 1, 8,
"floating point double precision"},
41 {
DCM_VR_IS,
"IS", 0, 0, 12,
"integer string"},
42 {
DCM_VR_LO,
"LO", 0, 0, 64,
"long string"},
43 {
DCM_VR_LT,
"LT", 0, 0, 10240,
"long text"},
44 {
DCM_VR_OB,
"OB", 2, 0, 0,
"other byte (8-bit) stream"},
45 {
DCM_VR_OD,
"OD", 2, 1, 0,
"other double (64-bit) stream"},
46 {
DCM_VR_OF,
"OF", 2, 1, 0,
"other float (32-bit) stream"},
47 {
DCM_VR_OL,
"OL", 2, 1, 0,
"other long (32-bit) stream"},
48 {
DCM_VR_OW,
"OW", 2, 1, 0,
"other word (16-bit) stream"},
49 {
DCM_VR_PN,
"PN", 0, 0, 64,
"person name"},
50 {
DCM_VR_SH,
"SH", 0, 0, 16,
"short string"},
51 {
DCM_VR_SL,
"SL", 0, 1, 4,
"signed long (32-bit integer)"},
52 {
DCM_VR_SQ,
"SQ", 2, 0, 0,
"sequence of elements (used for nested data)"},
53 {
DCM_VR_SS,
"SS", 0, 1, 2,
"signed short (16-bit integer)"},
54 {
DCM_VR_ST,
"ST", 0, 0, 1024,
"short text"},
56 {
DCM_VR_UC,
"UC", 2, 0, 0,
"unlimited characters"},
58 {
DCM_VR_UL,
"UL", 0, 1, 4,
"unsigned long (32-bit integer)"},
59 {
DCM_VR_UN,
"UN", 2, 0, 0,
"unknown, any valid length of another VR"},
60 {
DCM_VR_UR,
"UR", 2, 0, 64,
"URI or URL string"},
61 {
DCM_VR_US,
"US", 0, 1, 2,
"unsigned short (16-bit integer)"},
62 {
DCM_VR_UT,
"UT", 2, 0, 0,
"unlimited text"},
64 {
DCM_VR_INVALID,
"INVALID", 0, 0, 0,
"invalid value representation"}
72typedef struct DCM_TRUID_ITEM {
86static DCM_TRUID_ITEM dcm_truid[]={
88 {
DCM_TRUID_LEI,
"1.2.840.10008.1.2",
"implicit VR little endian"},
89 {
DCM_TRUID_LEE,
"1.2.840.10008.1.2.1",
"explicit VR little endian"},
90 {
DCM_TRUID_BEE,
"1.2.840.10008.1.2.2",
"explicit VR big endian"},
91 {
DCM_TRUID_JPEG50,
"1.2.840.10008.1.2.4.50",
"lossy JPEG 8-bit compression"},
92 {
DCM_TRUID_JPEG51,
"1.2.840.10008.1.2.4.51",
"lossy JPEG 12-bit compression"},
98 {
DCM_TRUID_JPEG92,
"1.2.840.10008.1.2.4.92",
"lossless multicomponent JPEG 2000"},
114typedef struct DCM_SOP_ITEM {
125static DCM_SOP_ITEM dcm_sop[]={
126 {
"invalid",
"invalid SOP"},
127 {
"1.2.840.10008.5.1.4.1.1.1",
"Computed Radiography Image Storage"},
128 {
"1.2.840.10008.5.1.4.1.1.12.1",
"X-Ray Angiographic Image Storage"},
129 {
"1.2.840.10008.5.1.4.1.1.128",
"Positron Emission Tomography Image Storage"},
130 {
"1.2.840.10008.5.1.4.1.1.130",
"Enhanced PET Image Storage"},
131 {
"1.2.840.10008.5.1.4.1.1.128.1",
"Legacy Converted Enhanced PET Image Storage"},
132 {
"1.2.840.10008.5.1.4.1.1.2",
"CT Image Storage"},
133 {
"1.2.840.10008.5.1.4.1.1.20",
"NM Image Storage"},
134 {
"1.2.840.10008.5.1.4.1.1.30",
"Parametric Map Storage"},
135 {
"1.2.840.10008.5.1.4.1.1.3.1",
"Ultrasound Multiframe Image Storage"},
136 {
"1.2.840.10008.5.1.4.1.1.4",
"MR Image Storage"},
137 {
"1.2.840.10008.5.1.4.1.1.4.1",
"Enhanced MR Image Storage"},
138 {
"1.2.840.10008.5.1.4.1.1.4.2",
"MR Spectroscopy Storage"},
139 {
"1.2.840.10008.5.1.4.1.1.6.1",
"Ultrasound Image Storage"},
140 {
"1.2.840.10008.5.1.4.1.1.66",
"Raw Data Storage"},
141 {
"1.2.840.10008.5.1.4.1.1.66.1",
"Spatial Registration Storage"},
142 {
"1.2.840.10008.5.1.4.1.1.66.2",
"Spatial Fiducials Storage"},
143 {
"1.2.840.10008.5.1.4.1.1.66.3",
"Deformable Spatial Registration Storage"},
144 {
"1.2.840.10008.5.1.4.1.1.66.4",
"Segmentation Storage"},
145 {
"unknown",
"unknown SOP"}
160 const char *filename,
171 if(filename==NULL && fp==NULL)
return(0);
175 lfp=fopen(filename,
"rb");
177 if(lfp==NULL)
return(0);
180 if(fseek(lfp, 128, SEEK_SET)) {
if(fp==NULL) fclose(lfp);
return(0);}
184 size_t n=fread(&buf, 1, 4, lfp);
186 if(n!=(
size_t)4) {rewind(lfp);
return(0);}
189 if(strncmp(buf,
"DICM", 4)==0) {
190 if(fp==NULL) fclose(lfp);
193 if(fp==NULL) fclose(lfp);
else rewind(lfp);
209 unsigned short int i=0;
211 if(
id==dcm_vr[i].vr)
return(dcm_vr[i].res);
229 char buf[3]; buf[0]=s[0]; buf[1]=s[1]; buf[2]=(char)0;
232 unsigned short int i=0;
234 if(strncmp(dcm_vr[i].name, buf, 2)==0)
return(dcm_vr[i].vr);
250 unsigned short int i=0;
252 if(
id==dcm_vr[i].vr)
return(dcm_vr[i].name);
268 unsigned short int i=0;
270 if(
id==dcm_vr[i].vr)
return(dcm_vr[i].s);
286 unsigned short int i=0;
288 if(
id==dcm_vr[i].vr)
return(dcm_vr[i].descr);
306 if(orig==NULL || intl==NULL)
return(NULL);
307 if(
strnlen(orig, 10)<8)
return(NULL);
308 if(isdigit(orig[4])) {
309 sprintf(intl,
"%4.4s-%2.2s-%2.2s", orig, orig+4, orig+6);
311 sprintf(intl,
"%4.4s-%2.2s-%2.2s", orig, orig+5, orig+8);
313 if(
isdate(intl)) {intl[0]=(char)0;
return(NULL);}
329 if(orig==NULL || intl==NULL)
return(NULL);
330 if(
strnlen(orig, 14)<6)
return(NULL);
331 if(isdigit(orig[2])) {
332 sprintf(intl,
"%2.2s:%2.2s:%2.2s", orig, orig+2, orig+4);
334 sprintf(intl,
"%2.2s:%2.2s:%2.2s", orig, orig+3, orig+6);
336 if(
istime(intl)) {intl[0]=(char)0;
return(NULL);}
353 if(orig==NULL || intl==NULL)
return(NULL);
354 if(
strnlen(orig, 26)<14)
return(NULL);
355 sprintf(intl,
"%4.4s-%2.2s-%2.2s %2.2s:%2.2s:%2.2s",
356 orig, orig+4, orig+6, orig+8, orig+10, orig+12);
357 if(
isdatetime(intl, NULL)) {intl[0]=(char)0;
return(NULL);}
371 if(s==NULL ||
strnlen(s, 3)<3)
return(0);
375 while(strcmp(dcm_sop[i].uid,
"unknown")!=0) {
376 if(strcmp(dcm_sop[i].uid, s)==0)
return(i);
393 while(strcmp(dcm_sop[j].uid,
"unknown")!=0) {
394 if(i==j)
return(dcm_sop[j].name);
397 return(dcm_sop[j].name);
411 while(strcmp(dcm_sop[j].uid,
"unknown")!=0) {
412 if(i==j)
return(dcm_sop[j].uid);
415 return(dcm_sop[j].uid);
428 if(s==NULL ||
strnlen(s, 3)<3)
return(dcm_sop[0].name);
432 while(strcmp(dcm_sop[i].uid,
"unknown")!=0) {
433 if(strcmp(dcm_sop[i].uid, s)==0)
return(dcm_sop[i].name);
436 return(dcm_sop[i].name);
452 unsigned short int i=1;
454 if(strcmp(dcm_truid[i].uid, s)==0)
return(dcm_truid[i].
id);
470 unsigned short int i=0;
472 if(
id==dcm_truid[i].
id)
return(dcm_truid[i].descr);
488 unsigned short int i=0;
490 if(
id==dcm_truid[i].
id)
return(dcm_truid[i].uid);
515 while(!tag_found && !feof(fp)) {
517 if(tag.
group==0x0002 && tag.
element==0x0010) {tag_found=1;
break;}
524 if(vl==0xFFFFFFFF)
break;
526 if(fread(buf, 1, vl, fp)!=vl)
break;
561 if(fp==NULL || feof(fp))
return(1);
562 unsigned short int buf[2];
563 size_t n=fread(&buf, 2, 2, fp);
564 if(n!=2)
return(2+n);
589 if(fp==NULL || tag==NULL)
return(1);
590 unsigned short int buf[2];
594 if(fwrite(&buf, 2, 2, fp)!=2)
return(2);
613 if(fp==NULL)
return(1);
638 if(fp==NULL)
return(1);
662 if(vrstr!=NULL) vrstr[0]=(char)0;
674 else strcpy(vrstr, buf);
699 if(fp==NULL || (n!=2 && n!=4))
return(vl);
703 unsigned short int si;
704 if(fread(&si, 2, 1, fp)!=1)
return(vl);
709 if(fread(&li, 4, 1, fp)!=1)
return(vl);
737 if(fp==NULL)
return(1);
741 if(fread(&buf, 1, 2, fp)!=2)
return(2);
else if(n!=NULL) *n+=2;
746 if(vr!=NULL) *vr=lvr;
753 if(fread(&buf, 1, 2, fp)!=2)
return(2);
760 unsigned short int si;
761 if(fread(&si, 2, 1, fp)!=1)
return(2);
766 if(fread(&li, 4, 1, fp)!=1)
return(2);
770 if(n!=NULL) *n+=bsize;
771 if(vl!=NULL) *vl=lvl;
804 memcpy(buf,
dcmVRName(vr), 2); buf[2]=buf[3]=(char)0;
805 if(fwrite(buf, bsize, 1, fp)!=1)
return(2);
806 if(n!=NULL) *n+=bsize;
809 memcpy(buf, &vl, bsize);
810 if(bsize==2) buf[2]=buf[3]=(char)0;
812 if(fwrite(buf, bsize, 1, fp)!=1)
return(2);
813 if(n!=NULL) *n+=bsize;
856 free(ip->
rd); free(ip); ip=NULL;
889 unsigned short int m=0, n=0;
907 if(df==NULL || df->
item==NULL)
return(0);
908 unsigned short int m=0, n=0;
927 if(d==NULL)
return(0);
928 unsigned short int n=0;
946 if(d==NULL)
return((
char*)NULL);
950 char *s=malloc(3); strcpy(s,
"na");
957 char *s=malloc(6); strcpy(s,
"empty");
959 }
else if(d->
rd==NULL) {
960 char *s=malloc(3); strcpy(s,
"na");
972 char *s=malloc(len+1);
973 memcpy(s, d->
rd, len); s[len]=(char)0;
983 char *s=malloc(len+1);
984 memcpy(s, d->
rd, len); s[len]=(char)0;
1005 memcpy(&f, d->
rd, 4);
1008 sprintf(s,
"%g", f);
1016 memcpy(&f, d->
rd, 8);
1018 sprintf(s,
"%g", f);
1025 memcpy(&i, d->
rd, 4);
1028 sprintf(s,
"%u", i);
1034 unsigned short int i;
1035 memcpy(&i, d->
rd, 2);
1038 sprintf(s,
"%u", i);
1045 memcpy(&i, d->
rd, 4);
1048 sprintf(s,
"%d", i);
1055 memcpy(&i, d->
rd, 2);
1058 sprintf(s,
"%d", i);
1072 char *s=malloc(3); strcpy(s,
"na");
1088 if(d==NULL || d->
rd==NULL)
return(0);
1095 unsigned short int i;
1124 if(d==NULL || d->
rd==NULL)
return(0);
1141 unsigned short int i;
1153 r=(double)atol(d->
rd);
1167 const short int omit,
1173 if(d==NULL || tag==NULL)
return(NULL);
1174 if(verbose>0) printf(
"%s(%04X,%04X)\n", __func__, tag->
group, tag->
element);
1176 if(omit==0) iptr=d;
else iptr=d->
next_item;
1181 if(verbose>2) printf(
" found!\n");
1186 if(verbose>2) printf(
" going to search inside children...\n");
1188 if(rptr!=NULL)
return(rptr);
1189 if(verbose>3) printf(
" nothing found in any of the children\n");
1194 if(iptr!=NULL)
return(iptr);
1198 if(verbose>2) printf(
" going to search inside parent...\n");
1209 if(d==NULL) {printf(
"(null)\n"); fflush(stdout);
return;}
1211 printf(
" VR=%s",
dcmVRName(d->
vr)); fflush(stdout);
1212 if(d->
vl==0xFFFFFFFF) printf(
" VL=%08X", d->
vl);
else printf(
" VL=%u", d->
vl);
1215 printf(
"\n"); fflush(stdout);
1225 unsigned short int group,
1227 unsigned short int element
1259 printf(
"%s(dcm, (%04X,%04X))", __func__, tag.
group, tag.
element);
1260 if(d==NULL) printf(
", null");
else printf(
", ptr");
1261 printf(
", %d, %s, 0x%08X, rd", aschild,
dcmVRName(vr), vl);
1264 if(dcm==NULL)
return(1);
1268 if(d!=NULL && dcm->
item==NULL)
return(3);
1270 if(d!=NULL && aschild && d->
child_item!=NULL)
return(4);
1277 if(verbose>1) printf(
" allocating memory for the item\n");
1279 if(item==NULL)
return(11);
1282 item->
rd=(
char*)NULL;
1285 if(verbose>1) printf(
" setting item contents\n");
1294 if(item->
vl==0xFFFFFFFF) item->
vl=(
unsigned int)s;
1295 if(verbose>1) printf(
" allocating %u bytes for the item value\n", (
unsigned int)s);
1296 item->
rd=(
char*)calloc(s,
sizeof(
char));
1297 if(item->
rd==NULL) {free(item);
return(21);}
1299 if(verbose>1) printf(
"zero size for item value\n");
1301 if(verbose>1) printf(
"... which is ok since value is empty, too.\n");
1303 if(verbose>0) printf(
"... which is not ok because we have value to store.\n");
1304 if(item->
rd==NULL) {free(item);
return(22);}
1308 if(rd!=NULL && s>0) {
1309 if(verbose>1) printf(
" copying the item value\n");
1313 unsigned int len=
strnlen(rd, s);
1315 else memcpy(item->
rd, rd, s);
1318 unsigned int len=
strnlen(rd, s);
1320 else memcpy(item->
rd, rd, s);
1322 memcpy(item->
rd, rd, s);
1328 if(verbose>1) printf(
" link the item.\n");
1345 }
else if(dcm->
item==NULL) {
1359 if(verbose>1) printf(
" all done.\n");
1378 const short int sub,
1380 const short int headerOnly,
1384 if(verbose>0) printf(
"%s(DCMFILE*, DCMITEM*, DCMITEM*, %d, %d)\n", __func__, sub, headerOnly);
1385 if(dcm==NULL || dcm->
fp==NULL)
return(1);
1386 if(sub!=0 && parent_item==NULL)
return(1);
1387 if(feof(dcm->
fp))
return(-1);
1393 if(dcm->
item==NULL) printf(
" will add first element\n");
1394 else if(sub==0) printf(
" will add next element\n");
1395 else printf(
" will add subelement\n");
1400 if(parent_item!=NULL && parent_item->
vr==
DCM_VR_SQ) {sq_child=1;}
1401 if(verbose>10 && sq_child!=0) printf(
" we're a child to a sequence element\n");
1405 if(item==NULL)
return(4);
1410 item->
rd=(
char*)NULL;
1413 if(fgetpos(dcm->
fp, &item->
pos)) {
1414 free(item);
return(2);
1419 long int tagpos=ftell(dcm->
fp);
1420 printf(
" reading tag at %ld\n", tagpos);
1423 if(verbose>1 && !feof(dcm->
fp)) printf(
" error in reading the tag.\n");
1425 if(feof(dcm->
fp))
return(-1);
1430 printf(
" tag(%04x,%04x) with %u parents\n",
1437 printf(
" item delimitation tag(%04x,%04x) found, reading VL\n",
1440 if(verbose>1) printf(
" item delimitation tag VL := %lu (0x%08lx)\n", vl, vl);
1442 if(verbose>1) printf(
" error: VL should have been 0\n");
1451 if(verbose>10) printf(
" reading VR and VL\n");
1456 if(verbose>1) printf(
" invalid VR or VL\n");
1457 free(item);
return(ret);
1461 printf(
" VL := %u (0x%08x) (%d bytes field)\n", item->
vl, item->
vl, n/2);
1468 if(ftell(dcm->
fp)<0)
return(2);
1469 unsigned long int sqPos=(
unsigned long int)ftell(dcm->
fp);
1470 if(verbose>10) {printf(
" sequence... at %ld\n", sqPos); fflush(stdout);}
1471 unsigned long int sqContentLength=item->
vl;
1472 if(verbose>12) printf(
" sequence contents length is %lu\n", sqContentLength);
1476 if(sq_child!=0 && parent_item->
child_item==NULL) {
1481 if(prev_item==NULL) {
1482 if(dcm->
item==NULL) {
1495 long int tagpos=ftell(dcm->
fp);
1496 printf(
" reading first item tag at %ld\n", tagpos);
1501 if(verbose>1) printf(
" error %d in reading the tag.\n", ret);
1504 if(verbose>1) printf(
" item tag(%04x,%04x)\n", itemtag.
group, itemtag.
element);
1509 printf(
" sequence delimitation item tag(%04x,%04x) found, reading VL\n",
1512 if(verbose>1) printf(
" item tag VL := %lu (0x%08lx)\n", vl, vl);
1514 if(verbose>1) printf(
" error: VL should have been 0\n");
1517 if(verbose>3) printf(
" ending sequence before it really started.\n");
1522 if(verbose>1) printf(
" invalid sequence item tag(%04x,%04x)\n", itemtag.
group, itemtag.
element);
1527 if(verbose>3) {printf(
" item_VL := %lu (0x%08lx)\n", itemvl, itemvl);}
1528 if(ftell(dcm->
fp)<0)
return(2);
1529 unsigned long int sqItemPos=(
unsigned long int)ftell(dcm->
fp);
1531 if((sqItemPos-sqPos)>=sqContentLength) {
1532 if(verbose>3) printf(
" ending sequence since it was found to be empty.\n");
1535 if(verbose>12) printf(
" sequence content start position at %ld\n", sqItemPos);
1539 if(verbose>1) printf(
" error in reading the first item value dataset\n");
1543 while(!feof(dcm->
fp)) {
1545 if(ftell(dcm->
fp)<0)
return(2);
1546 unsigned long int cPos=(
unsigned long int)ftell(dcm->
fp);
1547 if(sqContentLength>0 && (cPos-sqPos)>=sqContentLength) {
1548 if(verbose>3) printf(
" we reached the end of sequence VL %lu\n", sqContentLength);
1554 long int tagpos=ftell(dcm->
fp);
1555 printf(
" reading next sequence item tag at %ld, %ld after start\n", tagpos, tagpos-sqItemPos);
1558 if(verbose>1) printf(
" next item tag(%04x,%04x)\n", itemtag.
group, itemtag.
element);
1560 if(verbose>3) {printf(
" item_VL := %lu (0x%08lx)\n", itemvl, itemvl);}
1564 if(verbose>3) printf(
" we got sequence delimitation tag\n");
1570 if(verbose>3) printf(
" we got item delimitation tag\n");
1572 if(verbose>1) printf(
" error: VL should have been 0\n");
1579 if(verbose>3) printf(
" not sequence item tag, move file position back 2x4 bytes\n");
1580 fseek(dcm->
fp, -8, SEEK_CUR);
1585 if(verbose>1) printf(
" error had happened in adding the child element\n");
1591 if(verbose>1) printf(
" error in reading item value dataset\n");
1599 printf(
" invalid sequence delimitation item tag(%04x,%04x)\n", itemtag.
group, itemtag.
element);
1603 if(verbose>10) {printf(
" end of sequence.\n"); fflush(stdout);}
1604 }
else if(item->
vl!=0xFFFFFFFF) {
1605 if(verbose>10) {printf(
" reading value of %u bytes...\n", item->
vl); fflush(stdout);}
1608 buf=(
char*)calloc(item->
vl+1,
sizeof(
char));
1609 if(buf==NULL) {free(item);
return(4);}
1610 if(fread(buf, 1, item->
vl, item->
fp)!=item->
vl) {
1611 free(item); free(buf);
return(3);
1617 if(verbose>5) {printf(
" ...not storing pixel data\n"); fflush(stdout);}
1618 free(buf); buf=(
char*)NULL;
1622 }
else if(verbose>4) {
1627 if(prev_item==NULL) {
1628 if(dcm->
item==NULL) {
1647 if(verbose>0) printf(
" Unknown VL!!\n");
1651 if(verbose>4) printf(
" VR_based_VL=%u\n", (
unsigned int)s);
1652 char *buf=(
char*)calloc(s+1,
sizeof(
char));
1653 if(buf==NULL) {free(item);
return(4);}
1654 if(fread(buf, 1, s, item->
fp)!=s) {
1655 free(item); free(buf);
return(3);
1660 if(prev_item==NULL) {
1661 if(dcm->
item==NULL) {
1689 const char *filename,
1693 const short int headerOnly,
1697 if(filename==NULL ||
strnlen(filename, 10)<1 || dcm==NULL)
return(1);
1698 if(verbose>1) printf(
"%s('%s', %d)\n", __func__, filename, headerOnly);
1711 if(verbose>2) printf(
"checking DICOM magic number\n");
1718 if(verbose>2) printf(
"checking Transfer Syntax UID\n");
1741 }
while(ret==0 && !feof(dcm->
fp));
1746 if(verbose>1) printf(
" eof\n");
1760 const char *filename,
1766 if(filename==NULL ||
strnlen(filename, 10)<1 || dcm==NULL)
return(1);
1767 if(verbose>1) {printf(
"%s('%s')\n", __func__, filename); fflush(stdout);}
1770 if(dcm->
item==NULL) {
1781 if(verbose>1) printf(
"opening the file for writing\n");
1783 fp=fopen(filename,
"wb");
1784 if(fp==NULL)
return(3);
1788 if(verbose>1) printf(
"writing preamble\n");
1789 char buf1[128], buf2[5];
1790 for(
int i=0; i<128; i++) buf1[i]=(
char)0;
1791 strcpy(buf2,
"DICM");
1792 if(fwrite(buf1, 128, 1, fp)<1 || fwrite(buf2, 4, 1, fp)<1) {
1800 if(verbose>1) printf(
"writing DICOM contents\n");
1817 if(iptr->
vl==0xFFFFFFFF) {
1819 if(verbose>30) printf(
" value_len1 := %u\n", (
unsigned int)len);
1823 if(verbose>30) printf(
" value_len3 := %u\n", (
unsigned int)len);
1824 n=fwrite(iptr->
rd, iptr->
vl, 1, fp);
1826 if(verbose>30) printf(
" value_len := %u\n", (
unsigned int)len);
1827 if(n!=1) {ret=4;
break;}
1829 if(verbose>1) printf(
"SQ, but no contents to write!\n");
1840 unsigned int d2counter=0;
1854 unsigned int d2il=0;
1856 if(fgetpos(fp, &d2ilpos)) {ret=12;
break;}
1859 if(fwrite(&ibuf, 4, 1, fp)!=1) {ret=13;
break;}
1875 if(iptr->
vl==0xFFFFFFFF) {
1877 if(verbose>30) printf(
" value_len1 := %u\n", (
unsigned int)len);
1882 if(verbose>30) printf(
" value_len3 := %u\n", (
unsigned int)len);
1883 n=fwrite(iptr->
rd, iptr->
vl, 1, fp);
1886 if(verbose>30) printf(
" value_len := %u\n", (
unsigned int)len);
1887 if(n!=1) {ret=17;
break;}
1889 if(verbose>1) printf(
"SQ, but no contents to write!\n");
1898 unsigned int d3counter=0;
1914 unsigned int d3il=0;
1917 if(fgetpos(fp, &d3ilpos)) {ret=32;
break;}
1919 if(fwrite(&ibuf, 4, 1, fp)!=1) {ret=33;
break;}
1936 if(iptr->
vl==0xFFFFFFFF) {
1938 if(verbose>30) printf(
" value_len1 := %u\n", (
unsigned int)len);
1940 d3il+=len; d2il+=len;
1943 if(verbose>30) printf(
" value_len3 := %u\n", (
unsigned int)len);
1944 n=fwrite(iptr->
rd, iptr->
vl, 1, fp);
1945 d3il+=iptr->
vl; d2il+=iptr->
vl;
1947 if(verbose>30) printf(
" value_len := %u\n", (
unsigned int)len);
1948 if(n!=1) {ret=37;
break;}
1950 if(verbose>1) printf(
"SQ, but no contents to write!\n");
1960 if(verbose>0) fprintf(stderr,
"Warning: 4th level items not written.\n");
1966 if(fgetpos(fp, &opos)) {ret=40;
break;}
1967 fsetpos(fp, &d3ilpos);
1969 memcpy(buf, &d3il, 4);
1971 if(fwrite(&buf, 4, 1, fp)!=1) {ret=41;
break;}
1990 if(fgetpos(fp, &opos)) {ret=18;
break;}
1991 fsetpos(fp, &d2ilpos);
1993 memcpy(buf, &d2il, 4);
1995 if(fwrite(&buf, 4, 1, fp)!=1) {ret=19;
break;}
2013 if(verbose>0) fprintf(stderr,
" ret := %d\n", ret);
int isdatetime(char *str, char *intdate)
int dcmAddItem(DCMFILE *dcm, DCMITEM *d, short int aschild, DCMTAG tag, dcmvr vr, unsigned int vl, char *rd, const int verbose)
dcmtruid dcmReadTransferSyntaxUID(FILE *fp)
long int dcmitemGetInt(DCMITEM *d)
unsigned short int dcmitemMaxDepth(DCMITEM *d)
unsigned char dcmVRReserved(dcmvr id)
unsigned int dcmSOPIdentify(const char *s)
int dcmWriteFileVRVL(FILE *fp, dcmvr vr, unsigned int vl, unsigned int *n)
char * dcmTrUIDDescr(dcmtruid id)
int dcmFileRead(const char *filename, DCMFILE *dcm, const short int headerOnly, int verbose)
size_t dcmVRVLength(dcmvr id)
void dcmfileInit(DCMFILE *d)
void dcmTagSet(DCMTAG *tag, unsigned short int group, unsigned short int element)
dcmvr dcmVRId(const char *s)
DCMITEM * dcmFindTag(DCMITEM *d, const short int omit, DCMTAG *tag, const int verbose)
int dcmFileWrite(const char *filename, DCMFILE *dcm, int verbose)
char * dcmDT2intl(const char *orig, char *intl)
void dcmfileFree(DCMFILE *d)
char * dcmDA2intl(const char *orig, char *intl)
void dcmitemFree(DCMITEM *d)
char * dcmTM2intl(const char *orig, char *intl)
char * dcmVRName(dcmvr id)
dcmvr dcmReadFileVR(FILE *fp, char *vrstr)
void dcmitemPrint(DCMITEM *d)
int dcmReadFileTag(FILE *fp, DCMTAG *tag)
double dcmitemGetReal(DCMITEM *d)
int dcmReadFileVRVL(FILE *fp, dcmvr *vr, unsigned int *vl, unsigned int *n)
char * dcmSOPUIDName(const char *s)
int dcmFileReadNextElement(DCMFILE *dcm, DCMITEM *prev_item, DCMITEM *parent_item, const short int sub, const short int headerOnly, int verbose)
int dcmWriteFileSQItemDelimTag(FILE *fp)
unsigned short int dcmfileMaxDepth(DCMFILE *df)
unsigned int dcmReadFileVL(FILE *fp, unsigned int n)
char * dcmTrUIDString(dcmtruid id)
unsigned short int dcmitemParentNr(DCMITEM *d)
char * dcmValueString(DCMITEM *d)
char * dcmVRDescr(dcmvr id)
char * dcmSOPUID(unsigned int i)
dcmtruid dcmTrUID(const char *s)
int dcmWriteFileTag(FILE *fp, DCMTAG *tag)
int dcmVerifyMagic(const char *filename, FILE *fp)
char * dcmSOPName(unsigned int i)
int dcmWriteFileSQDelimItem(FILE *fp)
Header file for libtpcimgio.
@ DCM_VR_INVALID
Invalid DICOM value representation.
@ DCM_VR_DT
DICOM date time, max 26 bytes.
@ DCM_VR_UI
DICOM unique identifier (UID), max 64 bytes.
@ DCM_VR_FD
DICOM floating point double precision, 8 bytes fixed.
@ DCM_VR_UC
DICOM unlimited characters.
@ DCM_VR_PN
DICOM person name, max 64 chars per component group.
@ DCM_VR_CS
DICOM code (control) string, max 16 bytes.
@ DCM_VR_SS
DICOM signed short (16-bit integer), 2 bytes fixed.
@ DCM_VR_SH
DICOM short string, max 16 chars.
@ DCM_VR_OF
DICOM other float (32-bit) stream, endian sensitive.
@ DCM_VR_UT
DICOM unlimited text, character string.
@ DCM_VR_US
DICOM unsigned short (16-bit) integer, 2 bytes fixed.
@ DCM_VR_TM
DICOM time HHMMSS.FFFFFF, max 14 bytes.
@ DCM_VR_OB
DICOM other byte string, even bytes, endian insensitive.
@ DCM_VR_AS
DICOM age string, 4 bytes fixed.
@ DCM_VR_ST
DICOM short text, max 1024 chars.
@ DCM_VR_AT
DICOM attribute tag, 4 bytes fixed.
@ DCM_VR_LT
DICOM long text, max 10240 chars.
@ DCM_VR_DA
DICOM date in format YYYYMMDD, 8 bytes fixed.
@ DCM_VR_UL
DICOM unsigned long (32-bit) integer, 4 bytes fixed.
@ DCM_VR_UN
DICOM unknown, any valid length of another VR.
@ DCM_VR_DS
DICOM decimal string, max 16 bytes.
@ DCM_VR_OW
DICOM other word (16-bit) stream, even bytes, endian sensitive.
@ DCM_VR_IS
DICOM integer string, max 12 bytes.
@ DCM_VR_AE
DICOM application entity, max 16 bytes.
@ DCM_VR_UR
DICOM URI or URL, string of characters.
@ DCM_VR_LO
DICOM long string, max 64 chars.
@ DCM_VR_SQ
DICOM sequence of zero or more elements (used for nested data).
@ DCM_VR_FL
DICOM floating point single precision, 4 bytes fixed.
@ DCM_VR_SL
DICOM signed long (32-bit integer), 4 bytes fixed.
@ DCM_VR_OL
DICOM other long (32-bit) stream, endian sensitive.
@ DCM_VR_OD
DICOM other double (64-bit) stream, endian sensitive.
@ DCM_TRUID_LEI
Little Endian Implicit VR (DICOM default)
@ DCM_TRUID_JPEG81
Lossy JPEG-LS.
@ DCM_TRUID_JPEG93
Multicomponent JPEG 2000.
@ DCM_TRUID_MPEG100
MPEG-2.
@ DCM_TRUID_JPEG92
Lossless multicomponent JPEG 2000.
@ DCM_TRUID_JPEG91
JPEG 2000.
@ DCM_TRUID_JPEG70
Lossless JPEG.
@ DCM_TRUID_XML
XML encoding.
@ DCM_TRUID_INVALID
Invalid Transfer Syntax UID.
@ DCM_TRUID_MPEG103
MPEG-4 BD-compatible.
@ DCM_TRUID_JPEG80
Lossless JPEG-LS.
@ DCM_TRUID_UNKNOWN
Unknown Transfer Syntax UID
@ DCM_TRUID_BEE
Big Endian Explicit VR.
@ DCM_TRUID_JPEG51
Lossy JPEG 12-bit compression.
@ DCM_TRUID_RLE
Lossless RLE.
@ DCM_TRUID_LEE
Little Endian Explicit VR.
@ DCM_TRUID_JPEG90
Lossless JPEG 2000.
@ DCM_TRUID_JPEG50
Lossy JPEG 8-bit compression.
@ DCM_TRUID_MPEG102
MPEG-4.
void swabip(void *buf, long long int size)
size_t strnlen(const char *s, size_t n)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
void swap(void *orig, void *new, int size)
char filename[FILENAME_MAX]
struct DCMITEM * child_item
struct DCMITEM * next_item
struct DCMITEM * prev_item
struct DCMITEM * parent_item
unsigned short int element