spetric |
Posted - Jul 04 2011 : 12:08:07 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; }
|