DICOM dicomdir - eiichiromomma/CVMLAB GitHub Wiki
(DICOM) dicomdir
DICOM画像のスライス順等が入ったファイルを読む
上の階層の関連リンク参照。 タグごとにサイズが変わりかなり面倒。
遥か昔にスライス順にファイル名を取得するために作成。ひたすら力技。
#define DEBUG
とするとタグを全て出力する。 タグの網羅は諦めた。
使い方は
DicomdirRead dicomdirファイル
とするだけ。
初めにスライス数を数えて入れ物を用意してと、無駄なことをしているが特に需要も無いので直す予定は無し。 バックアップ代わりに掲載。
//DicomdirRead.cpp Eiichiro Momma 遥か昔に作成
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *fp;
typedef struct _ImageProperty
{
int height;
int width;
long min;
long max;
}iproperty;
iproperty ip;
typedef struct _Tag{
unsigned short group;
unsigned short element;
}tag;
typedef enum
{
unknown=0,
StudyDate,
ImageTime,
Manufacturer,
InstitutionName,
PatientsName,
PatientsSize,
PatientsWeight,
SliceThickness,
Gantry,
SliceLocation,
Rows,
Columns,
PixelSpacing,
PixelAspectRatio,
BitsAllocated,
BitsStored,
HighBit,
PixelRepresentation,
SmallestImagePixelValue,
LargestImagePixelValue,
WindowCenter,
WindowWidth,
PixelData,
GroupLength,
FilesetID,
FilesetDescriptorFileID,
SpecificCharacterSetOfFilesetDescriptorFile,
OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity,
OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity,
FilesetConsistencyFlag,
DirectoryRecordSequence,
OffsetOfTheNextDirectoryRecord,
RecordInuseFlag,
OffsetOfReferencedLowerLevelDirectoryEntry,
DirectoryRecordType,
PrivateRecordUID,
ReferencedFileID,
MRDRDirectoryRecordOffset,
ReferencedSOPClassUIDInFile,
ReferencedSOPInstanceUIDInFile,
ReferencedTransferSyntaxUIDInFile,
NumberOfReferences
}datatype;
typedef enum
{
i16=0,
i32,
other
}datasize;
static int fileNo;
char **fileList;
int
myfputs(const char *str, FILE *stream)
{
#ifdef DEBUG
return fputs(str,stream);
#endif
;
}
int
readSQ(char** fl)
{
int Count;
tag t;
datatype dt;
datasize sz;
short size16;
short data16;
long data32;
long size32;
size_t size;
char VR[3];
char *Value;
VR[0]=VR[1]=VR[2]=0;
FILE *fpcp;
if (fl == 0){
Count=1;
}else{
Count=0;
}
if (0 == fread(&t,sizeof(_Tag),1,fp)){
return 1;
}
fpcp = fp;
#ifdef DEBUG
fprintf(stderr,"%X,%X,",t.group,t.element);
#endif
switch (t.group){
case 0xFFFE:
switch(t.element){
case 0xE000:
myfputs("---------------start--------------\n", stderr);
fseek(fp,4,SEEK_CUR);
return 0;
break;
case 0xE00D:
myfputs("-----------------end--------------\n",stderr);
return 0;
}
break;
case 0x0004:
switch(t.element){
case 0x0000:
dt=GroupLength;
myfputs("GroupLength,",stderr);
break;
case 0x1130:
dt=FilesetID;
myfputs("FilesetID,",stderr);
break;
case 0x1141:
dt=FilesetDescriptorFileID;
myfputs("FilesetDescriptorFileID,",stderr);
break;
case 0x1142:
dt=SpecificCharacterSetOfFilesetDescriptorFile;
myfputs("SpecificCharacterSetOfFilesetDescriptorFile,",stderr);
break;
case 0x1200:
dt=OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity;
myfputs("OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity,",stderr);
break;
case 0x1202:
dt=OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity;
myfputs("OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity,",stderr);
break;
case 0x1212:
dt=FilesetConsistencyFlag;
myfputs("FilesetConsistencyFlag,",stderr);
break;
case 0x1220:
dt=DirectoryRecordSequence;
myfputs("DirectoryRecordSequence,",stderr);
break;
case 0x1400:
dt=OffsetOfTheNextDirectoryRecord;
myfputs("OffsetOfTheNextDirectoryRecord,",stderr);
break;
case 0x1410:
dt=RecordInuseFlag;
myfputs("RecordInuseFlag,",stderr);
break;
case 0x1420:
dt=OffsetOfReferencedLowerLevelDirectoryEntry;
myfputs("OffsetOfReferencedLowerLevelDirectoryEntry,",stderr);
break;
case 0x1430:
dt=DirectoryRecordType;
myfputs("DirectoryRecordType,",stderr);
break;
case 0x1432:
dt=PrivateRecordUID;
myfputs("PrivateRecordUID,",stderr);
break;
case 0x1500:
dt=ReferencedFileID;
myfputs("ReferencedFileID,",stderr);
break;
case 0x1504:
dt=MRDRDirectoryRecordOffset;
myfputs("MRDRDirectoryRecordOffset,",stderr);
break;
case 0x1510:
dt=ReferencedSOPClassUIDInFile;
myfputs("ReferencedSOPClassUIDInFile,",stderr);
break;
case 0x1511:
dt=ReferencedSOPInstanceUIDInFile;
myfputs("ReferencedSOPInstanceUIDInFile,",stderr);
break;
case 0x1512:
dt=ReferencedTransferSyntaxUIDInFile;
myfputs("ReferencedTransferSyntaxUIDInFile,",stderr);
break;
case 0x1600:
dt=NumberOfReferences;
myfputs("NumberOfReferences,",stderr);
break;
default:
dt=unknown;
myfputs("Unknown element,",stderr);
break;
}
break;
case 0x0008:
switch(t.element){
case 0x0020:
dt=StudyDate;
myfputs("Study Date,",stderr);
break;
case 0x0033:
dt=ImageTime;
myfputs("Image Time,",stderr);
break;
case 0x0070:
dt=Manufacturer;
myfputs("Manufacturer,",stderr);
break;
case 0x0080:
dt=InstitutionName;
myfputs("Institution Name,",stderr);
break;
default:
dt=unknown;
myfputs("Unknown element,",stderr);
break;
}
break;
case 0x0010:
switch(t.element){
case 0x0010:
dt=PatientsName;
myfputs("Patient's Name,",stderr);
break;
case 0x1020:
dt=PatientsSize;
myfputs("Patient's Size,",stderr);
break;
case 0x1030:
dt=PatientsWeight;
myfputs("Patient's Weight,",stderr);
break;
default:
dt=unknown;
myfputs("Unknown element,",stderr);
break;
}
break;
case 0x0018:
switch(t.element){
case 0x0050:
dt=SliceThickness;
myfputs("Slice Thickness,",stderr);
break;
case 0x1120:
dt=Gantry;
myfputs("Gantry,",stderr);
break;
default:
dt=unknown;
myfputs("Unknown element,",stderr);
break;
}
break;
case 0x0028:
switch(t.element){
case 0x0010:
dt=Rows;
myfputs("Rows,",stderr);
break;
case 0x0011:
dt=Columns;
myfputs("Columns,",stderr);
break;
case 0x0030:
dt=PixelSpacing;
myfputs("Pixel Spacing,",stderr);
break;
case 0x0034:
dt=PixelAspectRatio;
myfputs("PixelAspectRatio,",stderr);
break;
case 0x0100:
dt=BitsAllocated;
myfputs("Bits Allocated,",stderr);
break;
case 0x0101:
dt=BitsStored;
myfputs("BitsStored,",stderr);
break;
case 0x0102:
dt=HighBit;
myfputs("High Bit,",stderr);
break;
case 0x0103:
dt=PixelRepresentation;
myfputs("Pixel Representation,",stderr);
break;
case 0x0106:
dt=SmallestImagePixelValue;
myfputs("Smallest Image Pixel Value,",stderr);
break;
case 0x0107:
dt=LargestImagePixelValue;
myfputs("Largest Image Pixel Value,",stderr);
break;
case 0x1050:
dt=WindowCenter;
myfputs("Window Center,",stderr);
break;
case 0x1051:
dt=WindowWidth;
myfputs("Window Width,",stderr);
break;
default:
dt=unknown;
myfputs("Unknown element,",stderr);
break;
}
break;
case 0x7FE0:
switch(t.element){
case 0x0010:
dt=PixelData;
myfputs("PixelData,",stderr);
break;
}
break;
default:
dt=unknown;
myfputs("Unknown Tag,",stderr);
break;
}
fread(VR,2,1,fp);
switch((int)VR[0]){
case 'A':
switch((int)VR[1]){
case 'E':
case 'S':
case 'T':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
case 'C':
if (VR[1] == 'S'){
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
}
break;
case 'D':
switch((int)VR[1]){
case 'A':
case 'S':
case 'T':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
case 'F':
switch((int)VR[1]){
case 'L':
case 'D':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
case 'I':
if ((int)VR[1] == 'S'){
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
}
break;
case 'L':
switch((int)VR[1]){
case 'O':
case 'T':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
case 'O':
switch((int)VR[1]){
case 'B':
case 'W':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i32;
fseek(fp,2,SEEK_CUR);
break;
}
break;
case 'P':
if ((int)VR[1] == 'N'){
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
}
break;
case 'S':
switch((int)VR[1]){
case 'Q':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i32;
fseek(fp,2,SEEK_CUR);
break;
case 'H':
case 'L':
case 'S':
case 'T':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
case 'T':
if ((int)VR[1] == 'M'){
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
}
break;
case 'U':
switch((int)VR[1]){
case 'N':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i32;
fseek(fp,2,SEEK_CUR);
break;
case 'I':
case 'L':
case 'S':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
default:
myfputs("No VR.,",stderr);
fseek(fp,-2,SEEK_CUR);
// fp = fpcp;
sz=i32;
break;
}
switch(sz){
case i16:
fread(&size16,2,1,fp);
size=size16;
break;
case i32:
fread(&size32,4,1,fp);
size= size32;
break;
}
#ifdef DEBUG
fprintf(stderr,"%d,",size);
#endif
if (VR[0] == 'U' && VR[1] == 'S'){
fread(&data16,2,1,fp);
#ifdef DEBUG
fprintf(stderr,"%d\n",data16);
#endif
}else if(VR[0] == 'U' && VR[1] == 'L'){
fread(&data32,4,1,fp);
#ifdef DEBUG
fprintf(stderr,"%d\n",data32);
#endif
}else{
Value = (char *)malloc(size);
fread(Value,size,1,fp);
if (dt==ReferencedFileID){
if (!Count){
strcpy(*(fl+fileNo),Value);
// printf("%d,%s\n",fileNo,*(fl+fileNo));
}
fileNo++;
}else{
myfputs(Value,stderr);
myfputs("\n",stderr);
}
}
return 0;
}
int
readTag(char** fl)
{
tag t;
FILE *fpcp;
datatype dt;
datasize sz;
short size16;
short data16;
long data32;
long size32;
size_t size;
char VR[3];
char *Value;
VR[0]=VR[1]=VR[2]=0;
if (0 == fread(&t,sizeof(_Tag),1,fp)){
return 1;
}
fpcp=fp;
#ifdef DEBUG
fprintf(stderr,"%X,%X,",t.group,t.element);
#endif
switch (t.group){
case 0x0004:
switch(t.element){
case 0x0000:
dt=GroupLength;
myfputs("GroupLength,",stderr);
break;
case 0x1130:
dt=FilesetID;
myfputs("FilesetID,",stderr);
break;
case 0x1141:
dt=FilesetDescriptorFileID;
myfputs("FilesetDescriptorFileID,",stderr);
break;
case 0x1142:
dt=SpecificCharacterSetOfFilesetDescriptorFile;
myfputs("SpecificCharacterSetOfFilesetDescriptorFile,",stderr);
break;
case 0x1200:
dt=OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity;
myfputs("OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity,",stderr);
break;
case 0x1202:
dt=OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity;
myfputs("OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity,",stderr);
break;
case 0x1212:
dt=FilesetConsistencyFlag;
myfputs("FilesetConsistencyFlag,",stderr);
break;
case 0x1220:
dt=DirectoryRecordSequence;
myfputs("DirectoryRecordSequence,",stderr);
break;
case 0x1400:
dt=OffsetOfTheNextDirectoryRecord;
myfputs("OffsetOfTheNextDirectoryRecord,",stderr);
break;
case 0x1410:
dt=RecordInuseFlag;
myfputs("RecordInuseFlag,",stderr);
break;
case 0x1420:
dt=OffsetOfReferencedLowerLevelDirectoryEntry;
myfputs("OffsetOfReferencedLowerLevelDirectoryEntry,",stderr);
break;
case 0x1430:
dt=DirectoryRecordType;
myfputs("DirectoryRecordType,",stderr);
break;
case 0x1432:
dt=PrivateRecordUID;
myfputs("PrivateRecordUID,",stderr);
break;
case 0x1500:
dt=ReferencedFileID;
myfputs("ReferencedFileID,",stderr);
break;
case 0x1504:
dt=MRDRDirectoryRecordOffset;
myfputs("MRDRDirectoryRecordOffset,",stderr);
break;
case 0x1510:
dt=ReferencedSOPClassUIDInFile;
myfputs("ReferencedSOPClassUIDInFile,",stderr);
break;
case 0x1511:
dt=ReferencedSOPInstanceUIDInFile;
myfputs("ReferencedSOPInstanceUIDInFile,",stderr);
break;
case 0x1512:
dt=ReferencedTransferSyntaxUIDInFile;
myfputs("ReferencedTransferSyntaxUIDInFile,",stderr);
break;
case 0x1600:
dt=NumberOfReferences;
myfputs("NumberOfReferences,",stderr);
break;
default:
dt=unknown;
myfputs("Unknown element,",stderr);
break;
}
break;
case 0x0008:
switch(t.element){
case 0x0020:
dt=StudyDate;
myfputs("Study Date,",stderr);
break;
case 0x0033:
dt=ImageTime;
myfputs("Image Time,",stderr);
break;
case 0x0070:
dt=Manufacturer;
myfputs("Manufacturer,",stderr);
break;
case 0x0080:
dt=InstitutionName;
myfputs("Institution Name,",stderr);
break;
default:
dt=unknown;
myfputs("Unknown element,",stderr);
break;
}
break;
case 0x0010:
switch(t.element){
case 0x0010:
dt=PatientsName;
myfputs("Patient's Name,",stderr);
break;
case 0x1020:
dt=PatientsSize;
myfputs("Patient's Size,",stderr);
break;
case 0x1030:
dt=PatientsWeight;
myfputs("Patient's Weight,",stderr);
break;
default:
dt=unknown;
myfputs("Unknown element,",stderr);
break;
}
break;
case 0x0018:
switch(t.element){
case 0x0050:
dt=SliceThickness;
myfputs("Slice Thickness,",stderr);
break;
case 0x1120:
dt=Gantry;
myfputs("Gantry,",stderr);
break;
default:
dt=unknown;
myfputs("Unknown element,",stderr);
break;
}
break;
case 0x0028:
switch(t.element){
case 0x0010:
dt=Rows;
myfputs("Rows,",stderr);
break;
case 0x0011:
dt=Columns;
myfputs("Columns,",stderr);
break;
case 0x0030:
dt=PixelSpacing;
myfputs("Pixel Spacing,",stderr);
break;
case 0x0034:
dt=PixelAspectRatio;
myfputs("PixelAspectRatio,",stderr);
break;
case 0x0100:
dt=BitsAllocated;
myfputs("Bits Allocated,",stderr);
break;
case 0x0101:
dt=BitsStored;
myfputs("BitsStored,",stderr);
break;
case 0x0102:
dt=HighBit;
myfputs("High Bit,",stderr);
break;
case 0x0103:
dt=PixelRepresentation;
myfputs("Pixel Representation,",stderr);
break;
case 0x0106:
dt=SmallestImagePixelValue;
myfputs("Smallest Image Pixel Value,",stderr);
break;
case 0x0107:
dt=LargestImagePixelValue;
myfputs("Largest Image Pixel Value,",stderr);
break;
case 0x1050:
dt=WindowCenter;
myfputs("Window Center,",stderr);
break;
case 0x1051:
dt=WindowWidth;
myfputs("Window Width,",stderr);
break;
default:
dt=unknown;
myfputs("Unknown element,",stderr);
break;
}
break;
case 0x7FE0:
switch(t.element){
case 0x0010:
dt=PixelData;
myfputs("PixelData,",stderr);
break;
}
break;
default:
dt=unknown;
myfputs("Unknown Tag,",stderr);
break;
}
fread(VR,2,1,fp);
switch((int)VR[0]){
case 'A':
switch((int)VR[1]){
case 'E':
case 'S':
case 'T':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
case 'C':
if (VR[1] == 'S'){
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
}
break;
case 'D':
switch((int)VR[1]){
case 'A':
case 'S':
case 'T':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
case 'F':
switch((int)VR[1]){
case 'L':
case 'D':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
case 'I':
if ((int)VR[1] == 'S'){
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
}
break;
case 'L':
switch((int)VR[1]){
case 'O':
case 'T':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
case 'O':
switch((int)VR[1]){
case 'B':
case 'W':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i32;
fseek(fp,2,SEEK_CUR);
break;
}
break;
case 'P':
if ((int)VR[1] == 'N'){
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
}
break;
case 'S':
switch((int)VR[1]){
case 'Q':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i32;
fseek(fp,2,SEEK_CUR);
break;
case 'H':
case 'L':
case 'S':
case 'T':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
case 'T':
if ((int)VR[1] == 'M'){
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
}
break;
case 'U':
switch((int)VR[1]){
case 'N':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i32;
fseek(fp,2,SEEK_CUR);
break;
case 'I':
case 'L':
case 'S':
myfputs(VR,stderr);
myfputs(",",stderr);
sz=i16;
break;
}
break;
default:
myfputs("No VR.,",stderr);
fseek(fp,-2,SEEK_CUR);
// fp = fpcp;
sz=i32;
break;
}
switch(sz){
case i16:
fread(&size16,2,1,fp);
size=size16;
break;
case i32:
fread(&size32,4,1,fp);
size= size32;
if (dt == DirectoryRecordSequence){
myfputs("\n",stderr);
while(0==readSQ(fl));
return 0;
}
break;
}
#ifdef DEBUG
fprintf(stderr,"%d,",size);
#endif
if (VR[0] == 'U' && VR[1] == 'S'){
fread(&data16,2,1,fp);
#ifdef DEBUG
fprintf(stderr,"%d\n",data16);
#endif
}else if(VR[0] == 'U' && VR[1] == 'L'){
fread(&data32,4,1,fp);
#ifdef DEBUG
fprintf(stderr,"%d\n",data32);
#endif
}else{
Value = (char *)malloc(size);
fread(Value,size,1,fp);
myfputs(Value,stderr);
myfputs("\n",stderr);
}
switch(dt){
case Rows:
ip.width = data16;
break;
case Columns:
ip.height = data16;
break;
case SmallestImagePixelValue:
ip.min = data16;
break;
case LargestImagePixelValue:
ip.max = data16;
break;
default:
break;
}
return 0;
}
int
main (int argc, char **argv)
{
unsigned char c;
int i;
long place;
fileNo=0;
if ((fp=fopen(argv[1],"rb")) == NULL){
myfputs("Can't open file\n",stderr);
return 1;
}
while ((c=fgetc(fp)) == 0x0);
if ( c != 'D' ||
(c=fgetc(fp)) != 'I' ||
(c=fgetc(fp)) != 'C' ||
(c=fgetc(fp)) != 'M'){
myfputs("Not DICOM File\n",stderr);
return 1;
}
myfputs("DICOM File\n",stderr);
place = ftell(fp);
while(0 == readTag(0));
fileList = (char **)malloc((fileNo+1)*sizeof(char*));
for (i=0; i<fileNo; i++){
*(fileList+i) = (char *)malloc(256*sizeof(char));
**(fileList+i)=0;
}
fileNo=0;
fseek(fp,place,SEEK_SET);
while(0 == readTag(fileList));
for (i=0; i<fileNo; i++){
fputs(*(fileList+i),stderr);
fputs("\n",stderr);
}
return 0;
}