ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 DICOM tags XML
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

spetric

Croatia
308 Posts

Posted - Jul 04 2011 :  12:08:07  Show Profile  Reply
I've created a simple XML file with DICOM tags. Every element contains DICOM group, element pair. You can download the file here:

http://www.sigmapi-design.com/archive/DICOM_tags_full.xml

Here is a code snippet that reads data from TIEDICOMTags according to XML elements data and shows DICOM data in string grid. So, if someone is interested, you can translate it to Delphi code.
I wrote this code long time ago (in a hurry)...but it works:


//---------------------------------------
void __fastcall TfrmDICOM::FormShow(TObject *Sender)
{
TGmXML *XMLDoc = new TGmXML(NULL); // some simple XML component.
try
{
XMLDoc->LoadFromFile(ExtractFileDir(Application->ExeName) + "\\DICOM_tags_full.xml");
}
catch (...)
{
// TODO: report error
}
TGmXmlNode *root = XMLDoc->Nodes->Root;
AnsiString DICOM_name, DICOM_address, DICOM_group, DICOM_element;
TGmXmlNode *element, *subelement;
TGmXmlNodeList *node_list;
TIEDICOMTags *DICOM_tags = PxIOS->DICOM_tags; //PaintView->IO->Params->DICOM_Tags;
TIEDICOMTag *tag;
int jj, del_pos, cRow;
char D_group[2], D_element[2];
Word W_group, W_element;
try
{
// read project nodes
node_list = XMLDoc->Nodes;
element = node_list->Node[0]; // Body
node_list = element->Children; // DICOM tags
//skip description and go to DICOM tags
for (int jj = 1; jj < node_list->Count; jj++)
{
element = node_list->Node[jj];
DICOM_name = element->Name;
DICOM_address = element->AsString;
if (DICOM_address.Pos("x") > 0) // tag not yet implemented
continue;
del_pos = DICOM_address.Pos(",");
if (del_pos < 0)
break;
if (DICOM_name == "PixelData")
continue;
DICOM_group = DICOM_address.SubString(1, del_pos-1);
DICOM_element = DICOM_address.SubString(del_pos+1, 100);
HexToBin(DICOM_group.c_str(), D_group, 2);
HexToBin(DICOM_element.c_str(), D_element, 2);
D_group[0] = D_group[0]^D_group[1];
D_group[1] = D_group[0]^D_group[1];
D_group[0] = D_group[0]^D_group[1];
D_element[0] = D_element[0]^D_element[1];
D_element[1] = D_element[0]^D_element[1];
D_element[0] = D_element[0]^D_element[1];
W_group = *((Word *)D_group);
W_element = *((Word *)D_element);
tag = DICOM_tags->GetTag(DICOM_tags->IndexOf(W_group, W_element));
if (tag == NULL)
continue;
if (tag->Data == NULL)
continue;
if (jj != 1)
advDICOM->AddRow(); // TMS TAdvStringGrid component...can be any string grid component.
cRow = advDICOM->RowCount - 1;
advDICOM->Cells[0][cRow] = cRow;
advDICOM->Cells[1][cRow] = DICOM_group;
advDICOM->Cells[2][cRow] = DICOM_element;
advDICOM->Cells[3][cRow] = DICOM_name;
advDICOM->Cells[4][cRow] = pxf_GetDICOMString(tag);
}
}
catch (...)
{
advDICOM->AutoSizeColumns(true, 10);
return;
}
advDICOM->AutoSizeColumns(true, 10);
delete XMLDoc;
}
//
//---------------------------------------------------------------------------
AnsiString __fastcall pxf_GetDICOMString(TIEDICOMTag *tag)
{
/* DICOM data types
0. AE Application Entity
1. AS Age String
2. AT Attribute Tag
3. CS Code String
4. DA Date
5. DS Decimal String
6. DT Date/Time
7. FL Floating Point Single (4 bytes)
8. FD Floating Point Double (8 bytes)
9. IS Integer String
10. LO Long String
11. LT Long Text
12. OB Other Byte
13. OW Other Word
14. PN Patient Name
15. SH Short String
16. SL Signed Long
17. SQ Sequence of Items
18. SS Signed Short
19. ST Short Text
20. TM Time
21. UI Unique Identifier
22. UL Unsigned Long
23. UN Unknown
24. US Unsigned Short
25. UT Unlimited Text
px_DICOM_types are specified in header file, in this manner:
const AnsiString px_DICOM_types[27] = {"AE", "AS", "AT", "CS", "DA", "DS", "DT", "FL", "FD", "IS",
"LO", "LT", "OB", "OW", "PN", "SH", "SL", "SQ", "SS", "ST",
"TM", "UI", "UL", "UN", "US", "UT", "XS"};
*/
AnsiString out_str, data_type;
char buffer[32];
if (tag->Data == NULL)
return "";
else
{
data_type = AnsiString(tag->DataType, 2).UpperCase();
if (data_type == px_DICOM_types[7]) //FL Floating Point Single (4 bytes)
out_str = FloatToStr(*(float *)(tag->Data));
else if (data_type == px_DICOM_types) //FD Floating Point Double (8 bytes)
out_str = FloatToStr(*(double *)(tag->Data));
else if (data_type == px_DICOM_types[16]) //SL Signed Long
out_str = IntToStr(*(long *)(tag->Data));
else if (data_type == px_DICOM_types[18]) //SS Signed Short
out_str = IntToStr(*(short *)(tag->Data));
else if (data_type == px_DICOM_types[22]) //UL Unsigned Long
out_str = IntToStr(*(unsigned long *)(tag->Data));
else if (data_type == px_DICOM_types[24]) //US Unsigned Short
out_str = IntToStr(*(unsigned short *)(tag->Data));
else if (data_type == px_DICOM_types[12]) //OB Other Byte
{
if (tag->DataLen != 2)
return "DICOM tag read error";
BinToHex((char *)(tag->Data) + 1, buffer, 1);
out_str = "0x" + AnsiString(buffer, 2).Trim();
}
else if (data_type == px_DICOM_types[13]) //OW Other Word
out_str = IntToStr(*(unsigned short *)(tag->Data));
else if (data_type == px_DICOM_types[26]) //XS Byte string
{
if (tag->DataLen < 6)
{
BinToHex((char *)(tag->Data), buffer, tag->DataLen - 1);
out_str = "0x" + AnsiString(buffer, 2*(tag->DataLen - 1)).Trim();
}
else
out_str = AnsiString((char *)tag->Data, tag->DataLen).Trim();
}
else // let's assume it's string
out_str = AnsiString((char *)tag->Data, tag->DataLen).Trim();
//out_str = Dtags->GetTagString(Dtags->IndexOf(group, element));
}
return out_str;
}



xequte

38517 Posts

Posted - Jul 06 2011 :  03:23:31  Show Profile  Reply
Hi Sinisa

Thanks for posting


Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: