From f5c24f2018ff4775ff6ae006de753a394d8cae0f Mon Sep 17 00:00:00 2001 From: jpr Date: Sun, 6 Feb 2005 14:39:35 +0000 Subject: [PATCH] * Add method File::AnonymizeNoLoad, to allow anomymizing files even when the pixels are not gdcm Readable * Add methods File::AddAnonymizeElement and File::ClearAnonymizeList to allow user to choose the elements whose value he wants to white out / replace --- src/gdcmDocument.cxx | 5 +- src/gdcmDocument.h | 22 ++++--- src/gdcmFile.cxx | 138 +++++++++++++++++++++++++++++++++++-------- src/gdcmFile.h | 13 +++- src/gdcmFileHelper.h | 10 ++-- 5 files changed, 145 insertions(+), 43 deletions(-) diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 38595140..bc70151d 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.cxx,v $ Language: C++ - Date: $Date: 2005/02/05 01:37:08 $ - Version: $Revision: 1.223 $ + Date: $Date: 2005/02/06 14:39:35 $ + Version: $Revision: 1.224 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -30,6 +30,7 @@ #include #include +#include // For nthos: #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) diff --git a/src/gdcmDocument.h b/src/gdcmDocument.h index 727d049d..0ced6be7 100644 --- a/src/gdcmDocument.h +++ b/src/gdcmDocument.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.h,v $ Language: C++ - Date: $Date: 2005/02/02 16:18:48 $ - Version: $Revision: 1.104 $ + Date: $Date: 2005/02/06 14:39:35 $ + Version: $Revision: 1.105 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -23,6 +23,7 @@ #include "gdcmDict.h" #include "gdcmElementSet.h" #include "gdcmException.h" +//#include "gdcmCommon.h" #include #include @@ -43,10 +44,12 @@ class GDCM_EXPORT Document : public ElementSet { public: +typedef std::list ListElements; + // Dictionaries - Dict* GetPubDict(); - Dict* GetShaDict(); - bool SetShaDict(Dict* dict); + Dict *GetPubDict(); + Dict *GetShaDict(); + bool SetShaDict(Dict *dict); bool SetShaDict(DictKey const &dictName); // Informations contained in the gdcm::Document @@ -67,7 +70,7 @@ public: /// \brief Unswaps back the bytes of 2-bytes long integer /// so they agree with the processor order. uint16_t UnswapShort(uint16_t a) { return SwapShort(a);} - /// \brief Unswaps back the bytes of 4-byte long integer + /// \brief Unswaps back the bytes of 4-byte long integer /// so they agree with the processor order. uint32_t UnswapLong(uint32_t a) { return SwapLong(a);} @@ -86,7 +89,7 @@ public: virtual void LoadEntryBinArea(BinEntry *entry); void LoadDocEntrySafe(DocEntry *entry); - + // Ordering of Documents bool operator<(Document &document); @@ -143,6 +146,9 @@ protected: /// are NOT printed. static const unsigned int MAX_SIZE_PRINT_ELEMENT_VALUE; + /// List of element to Anonymize + ListElements AnonymizeList; + private: // Methods void Initialize(); @@ -195,9 +201,11 @@ private: /// is fixed to 64 bytes. uint32_t MaxSizePrintEntry; + // uint32_t GenerateFreeTagKeyInGroup(uint16_t group); // void BuildFlatHashTableRecurse( TagDocEntryHT &builtHT, // DocEntrySet *set ); + }; } // end namespace gdcm diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index d0d166b4..0644f920 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFile.cxx,v $ Language: C++ - Date: $Date: 2005/02/05 01:37:08 $ - Version: $Revision: 1.212 $ + Date: $Date: 2005/02/06 14:39:35 $ + Version: $Revision: 1.213 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -23,7 +23,7 @@ // If not found (ACR_NEMA) we try Image Position (0020,0030) // If not found (ACR-NEMA), we consider Slice Location (0020,1041) // or Location (0020,0050) -// as the Z coordinate, +// as the Z coordinate, // 0. for all the coordinates if nothing is found // // --------------------------------------------------------------- @@ -35,6 +35,7 @@ #include "gdcmTS.h" #include "gdcmValEntry.h" #include "gdcmBinEntry.h" +#include "gdcmSeqEntry.h" #include "gdcmRLEFramesInfo.h" #include "gdcmJPEGFragmentsInfo.h" @@ -643,7 +644,7 @@ void File::GetImageOrientationPatient( float iop[6] ) /** * \brief Retrieve the number of Bits Stored (actually used) - * (as opposite to number of Bits Allocated) + * (as opposed to number of Bits Allocated) * @return The encountered number of Bits Stored, 0 by default. * 0 means the file is NOT USABLE. The caller has to check it ! */ @@ -1130,34 +1131,119 @@ size_t File::GetPixelAreaLength() } } + /** - * \brief anonymize a File (removes Patient's personal info) - * (read the code to see which ones ...) + * \brief Adds the characteristics of a new element we want to anonymize + * */ -bool File::AnonymizeFile() -{ - // If exist, replace by spaces - SetValEntry (" ",0x0010, 0x2154); // Telephone - SetValEntry (" ",0x0010, 0x1040); // Adress - SetValEntry (" ",0x0010, 0x0020); // Patient ID +void File::AddAnonymizeElement (uint16_t group, uint16_t elem, + std::string const &value) + +{ + Element el; + el.Group = group; + el.Elem = elem; + el.Value = value; + AnonymizeList.push_back(el); +} - DocEntry* patientNameHE = GetDocEntry (0x0010, 0x0010); - - if ( patientNameHE ) // we replace it by Study Instance UID (why not) - { - std::string studyInstanceUID = GetEntryValue (0x0020, 0x000d); - if ( studyInstanceUID != GDCM_UNFOUND ) +/** + * \brief Overwrites in the file the values of the DicomElements + * held in the list + */ +void File::AnonymizeNoLoad() +{ + std::fstream *fp = new std::fstream(Filename.c_str(), + std::ios::in | std::ios::out | std::ios::binary); + // TODO : FIXME + // how to white out disk space if longer than 50 ? + char spaces[50] = " "; + + gdcm::DocEntry *d; + uint32_t offset; + uint32_t lgth; + uint32_t lgtToWrite; + for (ListElements::iterator it = AnonymizeList.begin(); + it != AnonymizeList.end(); + ++it) + { + d = GetDocEntry( (*it).Group, (*it).Elem); + + if ( dynamic_cast(d) + || dynamic_cast(d) ) + continue; + + offset = d->GetOffset(); + lgth = d->GetLength(); + fp->seekp( offset, std::ios::beg ); + + if ( (*it).Value == "" ) { - InsertValEntry(studyInstanceUID, 0x0010, 0x0010); + lgtToWrite = lgth > 50 ? 50 : lgth; + fp->write( spaces, lgtToWrite ); } else { - InsertValEntry("anonymised", 0x0010, 0x0010); + // TODO : FIXME + // how to white out disk space if longer than 50 ? + (*it).Value = (*it).Value + spaces; + lgtToWrite = lgth > (*it).Value.length() ? (*it).Value.length() : lgth; + fp->write( (char *)(*it).Value.c_str(), lgtToWrite ); + + } + fp->close(); + delete fp; + } +} + +/** + * \brief anonymize a File (removes Patient's personal info passed with + * AddAnonymizeElement() + */ +bool File::AnonymizeFile() +{ + // If Anonymisation list is empty, let's perform some basic anonymisation + if ( AnonymizeList.begin() == AnonymizeList.end() ) + { + // If exist, replace by spaces + SetValEntry (" ",0x0010, 0x2154); // Telephone + SetValEntry (" ",0x0010, 0x1040); // Adress + SetValEntry (" ",0x0010, 0x0020); // Patient ID + + DocEntry* patientNameHE = GetDocEntry (0x0010, 0x0010); + + if ( patientNameHE ) // we replace it by Study Instance UID (why not ?) + { + std::string studyInstanceUID = GetEntryValue (0x0020, 0x000d); + if ( studyInstanceUID != GDCM_UNFOUND ) + { + SetValEntry(studyInstanceUID, 0x0010, 0x0010); + } + else + { + SetValEntry("anonymised", 0x0010, 0x0010); + } } } + else + { + gdcm::DocEntry *d; + for (ListElements::iterator it = AnonymizeList.begin(); + it != AnonymizeList.end(); + ++it) + { + d = GetDocEntry( (*it).Group, (*it).Elem); + + if ( dynamic_cast(d) + || dynamic_cast(d) ) + continue; + + SetValEntry ((*it).Value, (*it).Group, (*it).Elem); + } +} - // Just for fun :-( - // (if any) remove or replace all the stuff that contains a Date + // In order to make definitively impossible any further identification + // remove or replace all the stuff that contains a Date //0008 0012 DA ID Instance Creation Date //0008 0020 DA ID Study Date @@ -1303,8 +1389,8 @@ bool File::Write(std::string fileName, FileType filetype) if ( GetPixelSize() == 16 ) { uint16_t *im16 = (uint16_t *)b->GetBinArea(); - int lgr = b->GetLength(); - for( int i = 0; i < lgr / 2; i++ ) + int lgth = b->GetLength(); + for( int i = 0; i < lgth / 2; i++ ) { im16[i]= (im16[i] >> 8) | (im16[i] << 8 ); } @@ -1320,8 +1406,8 @@ bool File::Write(std::string fileName, FileType filetype) if ( GetPixelSize() == 16 ) { uint16_t *im16 = (uint16_t*)b->GetBinArea(); - int lgr = b->GetLength(); - for( int i = 0; i < lgr / 2; i++ ) + int lgth = b->GetLength(); + for( int i = 0; i < lgth / 2; i++ ) { im16[i]= (im16[i] >> 8) | (im16[i] << 8 ); } diff --git a/src/gdcmFile.h b/src/gdcmFile.h index b8275b03..dd48d1c5 100644 --- a/src/gdcmFile.h +++ b/src/gdcmFile.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFile.h,v $ Language: C++ - Date: $Date: 2005/02/02 16:18:48 $ - Version: $Revision: 1.102 $ + Date: $Date: 2005/02/06 14:39:35 $ + Version: $Revision: 1.103 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -155,7 +155,13 @@ public: /// Returns the JPEG Fragments info JPEGFragmentsInfo *GetJPEGInfo() { return JPEGInfo; } - /// Replace patient's specific information by 'anonymous' +// Anonymization process + void AddAnonymizeElement (uint16_t group, uint16_t elem, + std::string const &value); + /// Clears the list of elements to be anonymized + void ClearAnonymizeList() { AnonymizeList.clear(); } + void AnonymizeNoLoad(); + /// Replace patient's own information by info from the Anonymization list bool AnonymizeFile(); bool Write(std::string fileName, FileType filetype); @@ -186,6 +192,7 @@ private: bool ReadTag(uint16_t, uint16_t); uint32_t ReadTagLength(uint16_t, uint16_t); void ReadAndSkipEncapsulatedBasicOffsetTable(); + }; } // end namespace gdcm diff --git a/src/gdcmFileHelper.h b/src/gdcmFileHelper.h index 18ab4bb9..1fefb4d3 100644 --- a/src/gdcmFileHelper.h +++ b/src/gdcmFileHelper.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFileHelper.h,v $ Language: C++ - Date: $Date: 2005/02/04 14:49:01 $ - Version: $Revision: 1.10 $ + Date: $Date: 2005/02/06 14:39:35 $ + Version: $Revision: 1.11 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -82,13 +82,13 @@ public: // User data void SetUserData(uint8_t *data, size_t expectedSize); - uint8_t* GetUserData(); + uint8_t *GetUserData(); size_t GetUserDataSize(); // RBG data (from file) - uint8_t* GetRGBData(); + uint8_t *GetRGBData(); size_t GetRGBDataSize(); // RAW data (from file) - uint8_t* GetRawData(); + uint8_t *GetRawData(); size_t GetRawDataSize(); // LUT -- 2.45.1