From eebb428694422967cab7559646df139d790afded Mon Sep 17 00:00:00 2001 From: jpr Date: Tue, 7 Sep 2004 13:57:04 +0000 Subject: [PATCH] ADD : gdcmGlobal::CountSubstring method ADD : Example/TestChangeHeader.cxx (Mathieu's one) FIX : now gdcmDocument::SetEntryByNumber deals properly with 'multivaluated' integer entries (US, SS, etc ) (e.g. : Aquisition Matrix) --- Example/CMakeLists.txt | 3 +++ Example/TestChangeHeader.cxx | 47 ++++++++++++++++++++++++++++++++++++ Testing/TestChangeHeader.cxx | 22 ++++++++--------- src/gdcmDocEntrySet.cxx | 9 ++++--- src/gdcmDocument.cxx | 12 +++++---- src/gdcmUtil.cxx | 27 +++++++++++++++++++-- src/gdcmUtil.h | 10 +++++--- 7 files changed, 103 insertions(+), 27 deletions(-) create mode 100644 Example/TestChangeHeader.cxx diff --git a/Example/CMakeLists.txt b/Example/CMakeLists.txt index 07ed443b..b6ac6f45 100644 --- a/Example/CMakeLists.txt +++ b/Example/CMakeLists.txt @@ -49,3 +49,6 @@ TARGET_LINK_LIBRARIES(BuildUpDicomDir gdcm) ADD_EXECUTABLE(TestCopyDicom TestCopyDicom.cxx) TARGET_LINK_LIBRARIES(TestCopyDicom gdcm) + +ADD_EXECUTABLE(TestChangeHeader TestChangeHeader.cxx) +TARGET_LINK_LIBRARIES(TestChangeHeader gdcm) diff --git a/Example/TestChangeHeader.cxx b/Example/TestChangeHeader.cxx new file mode 100644 index 00000000..c0982e6d --- /dev/null +++ b/Example/TestChangeHeader.cxx @@ -0,0 +1,47 @@ +#include "gdcmHeader.h" +#include "gdcmFile.h" + +// This examples read two images (could be the same). Try to modify +// Acquisition Matrix and then write the image again + +int main(int argc, char* argv[]) +{ + if (argc < 3) + { + std::cerr << "usage :" << std::endl << + argv[0] << " nomFichierPourEntete nomFichierPourDonnées" << +std::endl; + return 1; + } + + gdcmHeader *h1 = new gdcmHeader( argv[1] ); + gdcmFile *f1 = new gdcmFile( h1 ); + gdcmFile *f2 = new gdcmFile( argv[2] ); + + // 0018 1310 US ACQ Acquisition Matrix + gdcmDictEntry *dictEntry = + f2->GetHeader()->GetPubDict()->GetDictEntryByName( "Acquisition Matrix" ); + std::cerr << std::hex << dictEntry->GetGroup() << "," << dictEntry->GetElement() << std::endl; + + // std::string matrix = f2->GetHeader()->GetEntryByNumber(0x0018, 0x1310); + // Or, strictly equivalent (a little bit longer at run-time !): + std::string matrix = f2->GetHeader()->GetEntryByName("Acquisition Matrix"); + if(matrix != "gdcm::Unfound") + { + std::cerr << "Aquisition Matrix:" << matrix << std::endl; + f1->GetHeader()->ReplaceOrCreateByNumber( matrix, 0x0018, 0x1310); + + //f1->GetHeader()->ReplaceOrCreateByNumber( matrix, dictEntry->GetGroup(), + // dictEntry->GetElement()); + } + + f1->GetImageData(); + + h1->Print(); + + f1->WriteDcmExplVR("output-matrix.dcm"); + + return 0; +} + + diff --git a/Testing/TestChangeHeader.cxx b/Testing/TestChangeHeader.cxx index 819d70b7..399829c4 100644 --- a/Testing/TestChangeHeader.cxx +++ b/Testing/TestChangeHeader.cxx @@ -2,9 +2,8 @@ #include "gdcmFile.h" #include - -// ecriture d'un fichier DICOM à partir d'un dcmHeader correct. -// et des pixels d'une autre image +// Writting of a DICOM file, using a correct gdcmHeader. +// and pixels of an other image int TestChangeHeader(int argc, char* argv[]) @@ -12,7 +11,7 @@ int TestChangeHeader(int argc, char* argv[]) if (argc < 3) { std::cerr << "usage :" << std::endl << - argv[0] << " nomFichierPourEntete nomFichierPourDonnées" << std::endl; + argv[0] << " FileForHeader FileForPixels" << std::endl; return 1; } @@ -24,7 +23,7 @@ int TestChangeHeader(int argc, char* argv[]) //f1->PrintPubElVal(); - // On suppose que les champs DICOM du 2ieme fichier existent *effectivement* + // We suppose the DICOM Entries of the second file *do* exist ! std::string nbFrames = f2->GetHeader()->GetEntryByNumber(0x0028, 0x0008); if(nbFrames != "gdcm::Unfound") @@ -37,19 +36,18 @@ int TestChangeHeader(int argc, char* argv[]) f1->GetHeader()->ReplaceOrCreateByNumber( f2->GetHeader()->GetEntryByNumber(0x0028, 0x0011), 0x0028, 0x0011);// nbCol +// Probabely some more to update (?) -// sans doute d'autres à mettre à jour... - -// TODO : rajouter une valeur par defaut. -// TODO : une routine qui recoit une liste de couples (gr,el), -// et qui fasse le boulot. - +// TODO : add a default value +// TODO : add a method that receives a list of pairs (gr,el), +// and that does the work. int dataSize = f2->GetImageDataSize(); printf ("dataSize %d\n",dataSize); void* imageData= f2->GetImageData(); -// TODO : ne devrait-on pas fusionner ces 2 fonctions ? +// TODO : Why don't we merge theese 2 functions ? + f1->SetImageData(imageData,dataSize); f1->GetHeader()->SetImageDataSize(dataSize); diff --git a/src/gdcmDocEntrySet.cxx b/src/gdcmDocEntrySet.cxx index abc0885e..9a42d3c9 100644 --- a/src/gdcmDocEntrySet.cxx +++ b/src/gdcmDocEntrySet.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocEntrySet.cxx,v $ Language: C++ - Date: $Date: 2004/08/31 15:39:48 $ - Version: $Revision: 1.18 $ + Date: $Date: 2004/09/07 13:57:04 $ + Version: $Revision: 1.19 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -192,8 +192,9 @@ gdcmDictEntry* gdcmDocEntrySet::NewVirtualDictEntry(uint16_t group, } /** \brief - * Probabely move, as is, to gdcmDocEntrySet, as a non virtual method - * an remove gdcmDocument::NewDocEntryByNumber + * Creates a new DocEntry (without any 'value' ...) + * @param group group number of the underlying DictEntry + * @param element element number of the underlying DictEntry */ gdcmDocEntry* gdcmDocEntrySet::NewDocEntryByNumber(uint16_t group, uint16_t elem) diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 7ab750ec..71312ce5 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.cxx,v $ Language: C++ - Date: $Date: 2004/09/03 15:11:35 $ - Version: $Revision: 1.70 $ + Date: $Date: 2004/09/07 13:57:04 $ + Version: $Revision: 1.71 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -588,8 +588,8 @@ gdcmValEntry * gdcmDocument::ReplaceOrCreateByNumber( uint16_t elem ) { gdcmValEntry* valEntry = 0; - gdcmDocEntry* currentEntry = GetDocEntryByNumber( group, elem); + if (!currentEntry) { // The entry wasn't present and we simply create the required ValEntry: @@ -887,11 +887,13 @@ bool gdcmDocument::SetEntryByNumber(std::string const & content, gdcmVRKey vr = valEntry->GetVR(); if( vr == "US" || vr == "SS" ) { - valEntry->SetLength(2); + int c = CountSubstring(content, "\\"); // for multivaluated items + valEntry->SetLength((c+1)*2); } else if( vr == "UL" || vr == "SL" ) { - valEntry->SetLength(4); + int c = CountSubstring(content, "\\"); // for multivaluated items + valEntry->SetLength((c+1)*4); } else { diff --git a/src/gdcmUtil.cxx b/src/gdcmUtil.cxx index 4c053864..de171105 100644 --- a/src/gdcmUtil.cxx +++ b/src/gdcmUtil.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmUtil.cxx,v $ Language: C++ - Date: $Date: 2004/07/17 22:47:01 $ - Version: $Revision: 1.47 $ + Date: $Date: 2004/09/07 13:57:05 $ + Version: $Revision: 1.48 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -54,6 +54,29 @@ void Tokenize (const std::string& str, } } +/** + * \ingroup Globals + * \brief Because not available in C++ (?) + * Counts the number of occurences of a substring within a string + */ + + int CountSubstring (const std::string& str, + const std::string& subStr) { + int count = 0; // counts how many times it appears + int x = 0; // The index position in the string + + do + { x = str.find(subStr,x); // Find the substring + if (x != std::string::npos) // If present + { count++; // increase the count + x += subStr.length(); // Skip this word + } + } + while (x != std::string::npos); // Carry on until not present + + return count; +} + /** * \ingroup Globals * \brief Weed out a string from the non-printable characters (in order diff --git a/src/gdcmUtil.h b/src/gdcmUtil.h index ae4f23f4..9ea02aa5 100644 --- a/src/gdcmUtil.h +++ b/src/gdcmUtil.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmUtil.h,v $ Language: C++ - Date: $Date: 2004/06/20 18:08:48 $ - Version: $Revision: 1.29 $ + Date: $Date: 2004/09/07 13:57:05 $ + Version: $Revision: 1.30 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -35,8 +35,10 @@ GDCM_EXPORT std::istream & eatwhite(std::istream & is); GDCM_EXPORT void Tokenize (const std::string& str, - std::vector& tokens, - const std::string& delimiters = " "); + std::vector& tokens, + const std::string& delimiters = " "); +GDCM_EXPORT int CountSubstring (const std::string& str, + const std::string& subStr); GDCM_EXPORT std::string CreateCleanString(std::string s); GDCM_EXPORT void NormalizePath(std::string &name); -- 2.48.1