+2004-06-10 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
+ * src/gdcmHeader.[cxx|h]:
+ - Predicates on the Transfer syntax (of the form Is[JPEF|RLE]*)
+ and related, moved away to gdcmDocument.
+ - Accessors (on the form [Get|Set]Entry*) set up to expose publicly
+ the corresponding protected accessors of inherited class
+ gdcmDocument, removed ! As a consequence gdcmFile had to be
+ declared friend of class gdcmDocument (see below).
+ - operator< moved to gdcmDocument (in fact it belongs to gdcmDicomDir).
+ - Clean up of undefined or unused methods.
+ * src/gdcmFile.[cxx|h]: added SetEntryByNumber (in order to take into
+ account the changes to gdcmHeader.h).
+ * src/gdcmDocument.h:
+ - gdcmFile is now a friend class (in order to take into account the
+ changes to gdcmHeader.h).
+ - Predicates on the Transfer syntax (of the form Is[JPEF|RLE]*) added
+ (see changes to gdcmHeader.h).
+ - Accessors (reading on the form GetEntry*) are now public.
+ - Clean up of undefined or unused methods.
+ * src/gdcmDocument.cxx:
+ - adaptation to changes to gdcmDocument.h
+ - ::OpenFile now writes a verbose message when file cannot be opened.
+ - some std::string properly set to VRKey
+ * src/gdcmDicomDir.h: historical references to gdcmHeader changed to
+ references to gdcmDocument.
+ * Test/TestFindTags.cxx: changed accordingly to above changes.
+ * gdcmPython/testSuite.py: adapted to renaming of acr files in
+ cvs repository gdcmData.
+
2004-06-09 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
* src/gdcmValEntry.h: member voidArea type changed from char* to void*.
* src/gdcmBinEntry.h: member voidArea commented out, since it potentially
["Manufacturer", "FUJI"],
["Pixel Data", "gdcm::NotLoaded. Address:796 Length:262144 x(40000)"]
] ],
- ["CT-MONO2-12-lomb-an2.acr2",
+ ["CT-MONO2-12-lomb-an2.acr",
[ ["Modality", "CT"],
#"Transfer Syntax UID" and "Photometric Interpretation" are absent.
["Rows", "512"],
####################################
### MR modality examples:
####################################
- ["MR-MONO2-12-angio-an1.acr1",
+ ["MR-MONO2-12-angio-an1.acr",
[ ["Recognition Code (RET)", "ACR-NEMA 1.0"],
["Modality", "MR"],
#"Transfer Syntax UID" and "Photometric Interpretation" are absent.
# Note: 256*256*12/8 = 98304
["Pixel Data", "gdcm::NotLoaded. Address:650 Length:98304 x(18000)"]
] ],
- ["MR-MONO2-12-an2.acr2",
+ ["MR-MONO2-12-an2.acr",
[ ["Modality", "MR"],
["Photometric Interpretation", "MONOCHROME2"],
["Rows", "256"],
]
GdcmFiles = [
- ["gdcm-MR-SIEMENS-16.acr1",
+ ["gdcm-MR-SIEMENS-16-1.acr",
# Interest: good old Acr-Nema Version 1, see also Oddities below
[ ["Recognition Code (RET)", "ACR-NEMA 1.0"],
["Modality", "MR"],
["Study ID", ""],
["Series Number", ""] ] ],
# Oddities: "Study" and "Serie Instance UID" are not present
- ["gdcm-MR-SIEMENS-16.acr2",
+ ["gdcm-MR-SIEMENS-16-2.acr",
# Interest: Acr-Nema Version 2
[ ["Recognition Code (RET)", "ACR-NEMA 2.0"],
["Modality", "MR"],
#ifndef GDCM_H
#define GDCM_H
-//-----------------------------------------------------------------------------
-// Tag based hash tables.
-// We shall use as keys the strings (as the C++ type) obtained by
-// concatenating the group value and the element value (both of type
-// unsigned 16 bit integers in Dicom) expressed in hexadecimal.
-// Example: consider the tag given as (group, element) = (0x0010, 0x0010).
-// Then the corresponding TagKey shall be the string 0010|0010 (where
-// the | (pipe symbol) acts as a separator).
-// Refer to gdcmDictEntry::TranslateToKey for this conversion function.
+// General purpose include file. This file should be included by
+// external users of gdcm. It exposes the necessary API.
#include "gdcmException.h"
#include "gdcmCommon.h"
#include "gdcmDict.h"
#include "gdcmDictSet.h"
-//#include "gdcmParser.h"
#include "gdcmDocument.h"
-//#include "gdcmHeaderEntry.h"
-//#include "gdcmDocEntry.h"
#include "gdcmHeader.h"
#include "gdcmHeaderHelper.h"
#include "gdcmFile.h"
#include "gdcmUtil.h"
-//-----------------------------------------------------------------------------
#endif
#include "gdcmUtil.h"
#include "gdcmDebug.h"
#include "gdcmGlobal.h"
+#include "gdcmHeader.h"
#include "gdcmSeqEntry.h"
#include "gdcmSQItem.h"
gdcmDirList fileList(path,1); // gets recursively the file list
unsigned int count=0;
- ListHeader list;
+ VectDocument list;
gdcmHeader *header;
tagHT.clear();
* @param type gdcmObject type to create (GDCM_DICOMDIR_PATIENT, GDCM_DICOMDIR_STUDY, GDCM_DICOMDIR_SERIE ...)
* @param header gdcmHeader of the current file
*/
-void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,gdcmHeader *header)
+void gdcmDicomDir::SetElement(std::string &path,gdcmDicomDirType type,
+ gdcmDocument *header)
{
std::list<gdcmElement> elemList;
std::list<gdcmElement>::iterator it;
* @param path path of the root directory
* @param list chained list of Headers
*/
-void gdcmDicomDir::SetElements(std::string &path, ListHeader &list)
+void gdcmDicomDir::SetElements(std::string &path, VectDocument &list)
{
std::string patPrevName="", patPrevID="";
std::string studPrevInstanceUID="", studPrevID="";
SetElement(path,GDCM_DICOMDIR_META,NULL);
- for(ListHeader::iterator it=list.begin();it!=list.end();++it)
+ for(VectDocument::iterator it=list.begin();it!=list.end();++it)
{
// get the current file characteristics
patCurName= (*it)->GetEntryByNumber(0x0010,0x0010);
* \ingroup gdcmDicomDir
* \brief compares two dgcmHeaders
*/
-bool gdcmDicomDir::HeaderLessThan(gdcmHeader *header1,gdcmHeader *header2)
+bool gdcmDicomDir::HeaderLessThan(gdcmDocument *header1,gdcmDocument *header2)
{
return(*header1<*header2);
}
#ifndef GDCMDICOMDIR_H
#define GDCMDICOMDIR_H
-#include "gdcmHeader.h"
+//#include "gdcmHeader.h"
#include "gdcmCommon.h"
+#include "gdcmDocument.h"
#include "gdcmDicomDirPatient.h"
#include "gdcmDicomDirMeta.h"
#include "gdcmDicomDirElement.h"
//-----------------------------------------------------------------------------
typedef std::list<gdcmDicomDirPatient *> ListDicomDirPatient;
-typedef std::vector<gdcmHeader *> ListHeader;
+typedef std::vector<gdcmDocument *> VectDocument;
typedef GDCM_EXPORT void(gdcmMethod)(void * = NULL);
//-----------------------------------------------------------------------------
void AddDicomDirSerieToEnd (gdcmSQItem *s);
void AddDicomDirImageToEnd (gdcmSQItem *s);
- void SetElements(std::string &path,ListHeader &list);
- void SetElement (std::string &path,gdcmDicomDirType type,gdcmHeader *header);
+ void SetElements(std::string &path, VectDocument &list);
+ void SetElement (std::string &path,gdcmDicomDirType type,
+ gdcmDocument *header);
void UpdateDirectoryRecordSequenceLength(void);
- static bool HeaderLessThan(gdcmHeader *header1,gdcmHeader *header2);
+ static bool HeaderLessThan(gdcmDocument *header1,gdcmDocument *header2);
// Variables
*/
bool gdcmDocument::IsReadable(void) {
if(filetype==gdcmUnknown) {
- std::cout << "wrong filetype" <<std::endl;
+ dbg.Verbose(0, "gdcmDocument::IsReadable: wrong filetype");
return(false);
}
if(!tagHT.empty()<=0) {
- std::cout << "wrong tagHT size "<< tagHT.size() <<std::endl;
+ std::cout << "gdcmDocument::IsReadable: wrong tagHT size : "
+ << tagHT.size()
+ <<std::endl;
return(false);
}
return false;
}
+/**
+ * \brief Determines if the Transfer Syntax was already encountered
+ * and if it corresponds to a JPEGBaseLineProcess1 one.
+ * @return True when JPEGBaseLineProcess1found. False in all other cases.
+ */
+bool gdcmDocument::IsJPEGBaseLineProcess1TransferSyntax(void) {
+ gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
+ if ( !Element )
+ return false;
+ LoadDocEntrySafe(Element);
+
+ std::string Transfer = ((gdcmValEntry *)Element)->GetValue();
+ if ( Transfer == "1.2.840.10008.1.2.4.50" )
+ return true;
+ return false;
+}
+
+/**
+ * \brief Determines if the Transfer Syntax was already encountered
+ * and if it corresponds to a JPEGExtendedProcess2-4 one.
+ * @return True when JPEGExtendedProcess2-4 found. False in all other cases.
+ */
+bool gdcmDocument::IsJPEGExtendedProcess2_4TransferSyntax(void) {
+ gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
+ if ( !Element )
+ return false;
+ LoadDocEntrySafe(Element);
+ return ( ((gdcmValEntry *)Element)->GetValue() == "1.2.840.10008.1.2.4.51"
+);}
+
+/**
+ * \brief Determines if the Transfer Syntax was already encountered
+ * and if it corresponds to a JPEGExtendeProcess3-5 one.
+ * @return True when JPEGExtendedProcess3-5 found. False in all other cases.
+ */
+bool gdcmDocument::IsJPEGExtendedProcess3_5TransferSyntax(void) {
+ gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
+ if ( !Element )
+ return false;
+ LoadDocEntrySafe(Element);
+
+ std::string Transfer = ((gdcmValEntry *)Element)->GetValue();
+ if ( Transfer == "1.2.840.10008.1.2.4.52" )
+ return true;
+ return false;
+}
+
+/**
+ * \brief Determines if the Transfer Syntax was already encountered
+ * and if it corresponds to a JPEGSpectralSelectionProcess6-8 one.
+ * @return True when JPEGSpectralSelectionProcess6-8 found. False in all
+ * other cases.
+ */
+bool gdcmDocument::IsJPEGSpectralSelectionProcess6_8TransferSyntax(void) {
+ gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
+ if ( !Element )
+ return false;
+ LoadDocEntrySafe(Element);
+
+ std::string Transfer = ((gdcmValEntry *)Element)->GetValue();
+ if ( Transfer == "1.2.840.10008.1.2.4.53" )
+ return true;
+ return false;
+}
+
+/**
+ * \brief Determines if the Transfer Syntax was already encountered
+ * and if it corresponds to a RLE Lossless one.
+ * @return True when RLE Lossless found. False in all
+ * other cases.
+ */
+bool gdcmDocument::IsRLELossLessTransferSyntax(void) {
+ gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
+ if ( !Element )
+ return false;
+ LoadDocEntrySafe(Element);
+
+ std::string Transfer = ((gdcmValEntry *)Element)->GetValue();
+ if ( Transfer == "1.2.840.10008.1.2.5" ) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * \brief Determines if Transfer Syntax was already encountered
+ * and if it corresponds to a JPEG Lossless one.
+ * @return True when RLE Lossless found. False in all
+ * other cases.
+ */
+bool gdcmDocument::IsJPEGLossless(void) {
+ gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
+ // faire qq chose d'intelligent a la place de ça
+ if ( !Element )
+ return false;
+ LoadDocEntrySafe(Element);
+
+ const char * Transfert = ((gdcmValEntry *)Element)->GetValue().c_str();
+
+ if ( memcmp(Transfert+strlen(Transfert)-2 ,"70",2)==0) return true;
+ if ( memcmp(Transfert+strlen(Transfert)-2 ,"55",2)==0) return true;
+
+ if (((gdcmValEntry *)Element)->GetValue() == "1.2.840.10008.1.2.4.57")
+return true;
+
+ return false;
+}
+
+/**
+ * \brief Determines if the Transfer Syntax was already encountered
+ * and if it corresponds to a JPEG2000 one
+ * @return True when JPEG2000 (Lossly or LossLess) found. False in all
+ * other cases.
+ */
+bool gdcmDocument::IsJPEG2000(void) {
+ gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
+ if ( !Element )
+ return false;
+ LoadDocEntrySafe(Element);
+
+ std::string Transfer = ((gdcmValEntry *)Element)->GetValue();
+ if ( (Transfer == "1.2.840.10008.1.2.4.90")
+ || (Transfer == "1.2.840.10008.1.2.4.91") )
+ return true;
+ return false;
+}
+
+/**
+ * \brief Predicate for dicom version 3 file.
+ * @return True when the file is a dicom version 3.
+ */
+bool gdcmDocument::IsDicomV3(void) {
+ // Checking if Transfert Syntax exists is enough
+ // Anyway, it's to late check if the 'Preamble' was found ...
+ // And ... would it be a rich idea to check ?
+ // (some 'no Preamble' DICOM images exist !)
+ return (GetDocEntryByNumber(0x0002, 0x0010) != NULL);
+}
+
/**
* \brief returns the File Type
* (ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown)
throw(gdcmFileError)
{
fp=fopen(filename.c_str(),"rb");
- if(exception_on_error)
+
+ if(!fp)
{
- if(!fp)
- throw gdcmFileError("gdcmDocument::gdcmDocument(const char *, bool)");
+ if(exception_on_error)
+ throw gdcmFileError("gdcmDocument::gdcmDocument(const char *, bool)");
+ else
+ {
+ dbg.Verbose(0, "gdcmDocument::OpenFile cannot open file: ",
+ filename.c_str());
+ return (NULL);
+ }
}
if ( fp )
((gdcmValEntry*)a)->SetValue(content);
- std::string vr = a->GetVR();
+ VRKey vr = a->GetVR();
guint32 lgr;
if( (vr == "US") || (vr == "SS") )
FileType type)
{
guint16 group = tag->GetGroup();
- std::string vr = tag->GetVR();
+ VRKey vr = tag->GetVR();
guint16 el = tag->GetElement();
guint32 lgr = tag->GetReadLength();
{
(void)type;
guint16 group = tag->GetGroup();
- std::string vr = tag->GetVR();
+ VRKey vr = tag->GetVR();
guint32 lgr = tag->GetReadLength();
if (vr == "SQ")
return NewEntry;
}
-/// \todo Never used; commented out, waiting for removal.
-/**
- * \brief Small utility function that creates a new manually crafted
- * (as opposed as read from the file) gdcmDocEntry with user
- * specified name and adds it to the public tag hash table.
- * \note A fake TagKey is generated so the PubDict can keep it's coherence.
- * @param NewTagName The name to be given to this new tag.
- * @param VR The Value Representation to be given to this new tag.
- * @return The newly hand crafted Element Value.
- */
-//gdcmDocEntry *gdcmDocument::NewManualDocEntryToPubDict(std::string NewTagName,
-// std::string VR)
-//{
-// gdcmDocEntry *NewEntry = NULL;
-// guint32 StuffGroup = 0xffff; // Group to be stuffed with additional info
-// guint32 FreeElem = 0;
-// gdcmDictEntry *DictEntry = NULL;
-//
-// FreeElem = GenerateFreeTagKeyInGroup(StuffGroup);
-// if (FreeElem == UINT32_MAX)
-// {
-// dbg.Verbose(1, "gdcmHeader::NewManualDocEntryToPubDict",
-// "Group 0xffff in Public Dict is full");
-// return NULL;
-// }
-//
-// DictEntry = NewVirtualDictEntry(StuffGroup, FreeElem,
-// VR, "GDCM", NewTagName);
-// NewEntry = new gdcmDocEntry(DictEntry);
-// AddEntry(NewEntry);
-// return NewEntry;
-//}
-
/**
* \brief Generate a free TagKey i.e. a TagKey that is not present
* in the TagHt dictionary.
return;
}
+/**
+ * \brief Compares two documents, according to \ref gdcmDicomDir rules
+ * \warning Does NOT work with ACR-NEMA files
+ * \todo Find a trick to solve the pb (use RET fields ?)
+ * @param document
+ * @return true if 'smaller'
+ */
+ bool gdcmDocument::operator<(gdcmDocument &document){
+ std::string s1,s2;
+
+ // Patient Name
+ s1=this->GetEntryByNumber(0x0010,0x0010);
+ s2=document.GetEntryByNumber(0x0010,0x0010);
+ if(s1 < s2)
+ return(true);
+ else if(s1 > s2)
+ return(false);
+ else
+ {
+ // Patient ID
+ s1=this->GetEntryByNumber(0x0010,0x0020);
+ s2=document.GetEntryByNumber(0x0010,0x0020);
+ if (s1 < s2)
+ return(true);
+ else if (s1 > s2)
+ return(1);
+ else
+ {
+ // Study Instance UID
+ s1=this->GetEntryByNumber(0x0020,0x000d);
+ s2=document.GetEntryByNumber(0x0020,0x000d);
+ if (s1 < s2)
+ return(true);
+ else if(s1 > s2)
+ return(false);
+ else
+ {
+ // Serie Instance UID
+ s1=this->GetEntryByNumber(0x0020,0x000e);
+ s2=document.GetEntryByNumber(0x0020,0x000e);
+ if (s1 < s2)
+ return(true);
+ else if(s1 > s2)
+ return(false);
+ }
+ }
+ }
+ return(false);
+}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/**
- * \brief used by both gdcmHeader and gdcmDicomDir
+ * \brief Derived by both gdcmHeader and gdcmDicomDir
*/
class GDCM_EXPORT gdcmDocument : public gdcmElementSet
{
+friend class gdcmFile;
private:
/// Public dictionary used to parse this header
gdcmDict *RefPubDict;
int printLevel;
public:
-
-
-// Print
- // Canonical Printing method (see also gdcmDocument::SetPrintLevel)
- // virtual void Print (std::ostream &os = std::cout);
- // {PrintEntry(os);};
-
- // no more Print method for gdcmDocument (inherits from gdcmElementSet
- // virtual void PrintEntry (std::ostream &os = std::cout)
- // { return Print(os);};
-
- // the 2 following will be merged
+// the 2 following will be merged
virtual void PrintPubDict (std::ostream &os = std::cout);
virtual void PrintShaDict (std::ostream &os = std::cout);
bool IsExplicitVRLittleEndianTransferSyntax(void);
bool IsDeflatedExplicitVRLittleEndianTransferSyntax(void);
bool IsExplicitVRBigEndianTransferSyntax(void);
+ bool IsJPEGBaseLineProcess1TransferSyntax(void);
+ bool IsJPEGExtendedProcess2_4TransferSyntax(void);
+ bool IsJPEGExtendedProcess3_5TransferSyntax(void);
+ bool IsJPEGSpectralSelectionProcess6_8TransferSyntax(void);
+ bool IsRLELossLessTransferSyntax(void);
+ bool IsJPEGLossless(void);
+ bool IsJPEG2000(void);
+ bool IsDicomV3(void);
+
FileType GetFileType(void);
// Read (used in gdcmFile, gdcmDicomDir)
// gdcmDicomDir are meaningfull).
gdcmDocument(bool exception_on_error = false);
gdcmDocument(const char *inFilename,
- bool exception_on_error = false,
- bool enable_sequences = false,
- bool ignore_shadow = false);
+ bool exception_on_error = false,
+ bool enable_sequences = false,
+ bool ignore_shadow = false);
virtual ~gdcmDocument(void);
void gdcmDocument::Parse7FE0 (void);
// Entry
int CheckIfEntryExistByNumber(guint16 Group, guint16 Elem ); // int !
+public:
virtual std::string GetEntryByName (std::string tagName);
virtual std::string GetEntryVRByName (std::string tagName);
virtual std::string GetEntryByNumber (guint16 group, guint16 element);
virtual std::string GetEntryVRByNumber(guint16 group, guint16 element);
virtual int GetEntryLengthByNumber(guint16 group, guint16 element);
-
+protected:
virtual bool SetEntryByName (std::string content, std::string tagName);
virtual bool SetEntryByNumber(std::string content,
guint16 group, guint16 element);
void LoadDocEntrySafe(gdcmDocEntry *);
- // Probabely useless
- //void UpdateGroupLength(bool SkipSequence = false,
- // FileType type = ImplicitVR);
-
- //void AddDocEntry (gdcmDocEntry *);
-
-
private:
- // Read
- //bool LoadHeaderEntries(bool exception_on_error = false) throw(gdcmFormatError);
- // remplacé par ParseDES.
- // What about exception_on_error ?
-
- long ParseDES(gdcmDocEntrySet *set, long offset, long l_max, bool delim_mode);
- // long ParseSQ(gdcmDocEntrySet *set, long offset, long l_max, bool delim_mode);
- long ParseSQ(gdcmSeqEntry *seq, long offset, long l_max, bool delim_mode);
+// Read
+ long ParseDES(gdcmDocEntrySet *set, long offset, long l_max,bool delim_mode);
+ long ParseSQ(gdcmSeqEntry *seq, long offset, long l_max, bool delim_mode);
void LoadDocEntry (gdcmDocEntry *);
void FindDocEntryLength(gdcmDocEntry *);
std::string vr = "unkn",
std::string fourth = "unkn",
std::string name = "unkn");
- //gdcmDictEntry *NewVirtualDictEntry(gdcmDocEntry *); // never defined
-
// DocEntry related utilities
-
gdcmDocEntry *ReadNextDocEntry (void);
gdcmDocEntry *NewDocEntryByNumber(guint16 group,
guint16 element);
gdcmDocEntry *NewDocEntryByName (std::string Name);
- // Deprecated (Not used) --> commented out
- //gdcmDocEntry *NewManualDocEntryToPubDict(std::string NewTagName,
- // std::string VR);
-
guint32 GenerateFreeTagKeyInGroup(guint16 group);
public:
/// Accessor to \ref gdcmElementSet::tagHT
inline TagDocEntryHT &GetEntry(void) { return tagHT; };
- /// Accessor to \ref gdcmDocument::listEntries
- //inline ListTag &GetListEntry(void) { return listEntries; };
-
/// 'Swap code' accessor (see \ref sw )
inline int GetSwapCode(void) { return sw; }
/// File pointer
inline FILE * GetFP(void) { return fp; }
+ bool operator<(gdcmDocument &document);
+
};
//-----------------------------------------------------------------------------
// Body in file gdcmParse.cxx
bool ParsePixelData(void);
+
+ inline virtual bool SetEntryByNumber(std::string content,
+ guint16 group, guint16 element)
+ { GetHeader()->SetEntryByNumber(content,group,element); }
+
protected:
bool WriteBase(std::string FileName, FileType type);
/// \brief Header to use to load the file
gdcmHeader *Header;
- /// \brief Oops ! Eric : help me
+ /// \brief Whether the underlying \ref gdcmHeader was loaded by
+ /// the constructor or passed to the constructor. When false
+ /// the destructor is in charge of deletion.
bool SelfHeader;
/// \brief to hold the Pixels (when read)
}
/**
- * \ingroup gdcmHeader
- * \brief Determines if the Transfer Syntax was already encountered
- * and if it corresponds to a JPEGBaseLineProcess1 one.
- * @return True when JPEGBaseLineProcess1found. False in all other cases.
- */
-bool gdcmHeader::IsJPEGBaseLineProcess1TransferSyntax(void) {
- gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
- if ( !Element )
- return false;
- LoadDocEntrySafe(Element);
-
- std::string Transfer = ((gdcmValEntry *)Element)->GetValue();
- if ( Transfer == "1.2.840.10008.1.2.4.50" )
- return true;
- return false;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Determines if the Transfer Syntax was already encountered
- * and if it corresponds to a JPEGExtendedProcess2-4 one.
- * @return True when JPEGExtendedProcess2-4 found. False in all other cases.
- */
-bool gdcmHeader::IsJPEGExtendedProcess2_4TransferSyntax(void) {
- gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
- if ( !Element )
- return false;
- LoadDocEntrySafe(Element);
- return ( ((gdcmValEntry *)Element)->GetValue() == "1.2.840.10008.1.2.4.51" );
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Determines if the Transfer Syntax was already encountered
- * and if it corresponds to a JPEGExtendeProcess3-5 one.
- * @return True when JPEGExtendedProcess3-5 found. False in all other cases.
- */
-bool gdcmHeader::IsJPEGExtendedProcess3_5TransferSyntax(void) {
- gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
- if ( !Element )
- return false;
- LoadDocEntrySafe(Element);
-
- std::string Transfer = ((gdcmValEntry *)Element)->GetValue();
- if ( Transfer == "1.2.840.10008.1.2.4.52" )
- return true;
- return false;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Determines if the Transfer Syntax was already encountered
- * and if it corresponds to a JPEGSpectralSelectionProcess6-8 one.
- * @return True when JPEGSpectralSelectionProcess6-8 found. False in all
- * other cases.
- */
-bool gdcmHeader::IsJPEGSpectralSelectionProcess6_8TransferSyntax(void) {
- gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
- if ( !Element )
- return false;
- LoadDocEntrySafe(Element);
-
- std::string Transfer = ((gdcmValEntry *)Element)->GetValue();
- if ( Transfer == "1.2.840.10008.1.2.4.53" )
- return true;
- return false;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Determines if the Transfer Syntax was already encountered
- * and if it corresponds to a RLE Lossless one.
- * @return True when RLE Lossless found. False in all
- * other cases.
- */
-bool gdcmHeader::IsRLELossLessTransferSyntax(void) {
- gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
- if ( !Element )
- return false;
- LoadDocEntrySafe(Element);
-
- std::string Transfer = ((gdcmValEntry *)Element)->GetValue();
- if ( Transfer == "1.2.840.10008.1.2.5" ) {
- return true;
- }
- return false;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Determines if Transfer Syntax was already encountered
- * and if it corresponds to a JPEG Lossless one.
- * @return True when RLE Lossless found. False in all
- * other cases.
- */
-bool gdcmHeader::IsJPEGLossless(void) {
- gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
- // faire qq chose d'intelligent a la place de ça
- if ( !Element )
- return false;
- LoadDocEntrySafe(Element);
-
- const char * Transfert = ((gdcmValEntry *)Element)->GetValue().c_str();
-
- if ( memcmp(Transfert+strlen(Transfert)-2 ,"70",2)==0) return true;
- if ( memcmp(Transfert+strlen(Transfert)-2 ,"55",2)==0) return true;
-
- if (((gdcmValEntry *)Element)->GetValue() == "1.2.840.10008.1.2.4.57") return true;
-
- return false;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Determines if the Transfer Syntax was already encountered
- * and if it corresponds to a JPEG2000 one
- * @return True when JPEG2000 (Lossly or LossLess) found. False in all
- * other cases.
- */
-bool gdcmHeader::IsJPEG2000(void) {
- gdcmDocEntry* Element = GetDocEntryByNumber(0x0002, 0x0010);
- if ( !Element )
- return false;
- LoadDocEntrySafe(Element);
-
- std::string Transfer = ((gdcmValEntry *)Element)->GetValue();
- if ( (Transfer == "1.2.840.10008.1.2.4.90")
- || (Transfer == "1.2.840.10008.1.2.4.91") )
- return true;
- return false;
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief Predicate for dicom version 3 file.
- * @return True when the file is a dicom version 3.
- */
-bool gdcmHeader::IsDicomV3(void) {
- // Checking if Transfert Syntax exists is enough
- // Anyway, it's to late check if the 'Preamble' was found ...
- // And ... would it be a rich idea to check ?
- // (some 'no Preamble' DICOM images exist !)
- return (GetDocEntryByNumber(0x0002, 0x0010) != NULL);
-}
-
-/**
- * \ingroup gdcmHeader
* \brief Retrieve the number of columns of image.
* @return The encountered size when found, 0 by default.
* 0 means the file is NOT USABLE. The caller will have to check
}
/**
- * \ingroup gdcmHeader
- * \brief gets the info from 0002,0010 : Transfert Syntax and gdcmTS
+ * \brief Accesses the info from 0002,0010 : Transfert Syntax and gdcmTS
* else 1.
- * @return the full Transfert Syntax Name (as oposite to Transfert Syntax UID)
+ * @return The full Transfert Syntax Name (as opposed to Transfert Syntax UID)
*/
std::string gdcmHeader::GetTransfertSyntaxName(void) {
// use the gdcmTS (TS : Transfert Syntax)
std::string TransfertSyntax = GetEntryByNumber(0x0002,0x0010);
if (TransfertSyntax == GDCM_UNFOUND) {
- dbg.Verbose(0, "gdcmHeader::GetTransfertSyntaxName: unfound Transfert Syntax (0002,0010)");
+ dbg.Verbose(0, "gdcmHeader::GetTransfertSyntaxName:"
+ " unfound Transfert Syntax (0002,0010)");
return "Uncompressed ACR-NEMA";
}
// we do it only when we need it
gdcmTS * ts = gdcmGlobal::GetTS();
std::string tsName=ts->GetValue(TransfertSyntax);
- //delete ts; // Seg Fault when deleted ?!
+ //delete ts; /// \todo Seg Fault when deleted ?!
return tsName;
}
/**
- * \ingroup gdcmHeader
* \brief Sets the Pixel Area size in the Header
* --> not-for-rats function
* @param ImageDataSize new Pixel Area Size
std::string content1;
char car[20];
- // Assumes DocEntry (GrPixel, NumPixel) is unique ...
- //\todo deal with multiplicity (see gdcmData/icone.dcm)
sprintf(car,"%d",ImageDataSize);
gdcmDocEntry *a = GetDocEntryByNumber(GrPixel, NumPixel);
SetEntryByNumber(content1, GrPixel, NumPixel);
}
-
-/**
- * \ingroup gdcmHeader
- * \brief compares 2 Headers, according to DICOMDIR rules
- * --> not-for-rats function
- * \warning does NOT work with ACR-NEMA files
- * \todo find a trick to solve the pb (use RET fields ?)
- * @param header
- * @return true if 'smaller'
- */
- bool gdcmHeader::operator<(gdcmHeader &header){
- std::string s1,s2;
-
- // Patient Name
- s1=this->GetEntryByNumber(0x0010,0x0010);
- s2=header.GetEntryByNumber(0x0010,0x0010);
- if(s1 < s2)
- return(true);
- else if(s1 > s2)
- return(false);
- else
- {
- // Patient ID
- s1=this->GetEntryByNumber(0x0010,0x0020);
- s2=header.GetEntryByNumber(0x0010,0x0020);
- if (s1 < s2)
- return(true);
- else if (s1 > s2)
- return(1);
- else
- {
- // Study Instance UID
- s1=this->GetEntryByNumber(0x0020,0x000d);
- s2=header.GetEntryByNumber(0x0020,0x000d);
- if (s1 < s2)
- return(true);
- else if(s1 > s2)
- return(false);
- else
- {
- // Serie Instance UID
- s1=this->GetEntryByNumber(0x0020,0x000e);
- s2=header.GetEntryByNumber(0x0020,0x000e);
- if (s1 < s2)
- return(true);
- else if(s1 > s2)
- return(false);
- }
- }
- }
- return(false);
-}
-// Replaced by gdcmDocument::WriteEntry
-/*
-bool gdcmHeader::WriteEntry(gdcmDocEntry *tag, FILE *_fp,FileType type)
-{
-cout << " gdcmHeader::WriteEntry : entree " << endl;
- guint32 length = tag->GetLength();
-
- // The value of a tag MUST (see the DICOM norm) be an odd number of
- // bytes. When this is not the case, pad with an additional byte:
- if(length%2==1)
- {
- // tag->SetValue(tag->GetValue()+"\0"); // to go on compiling
- tag->SetLength(tag->GetReadLength()+1);
- }
-
- WriteEntryTagVRLength(tag, _fp, type);
-
- // Pixels are never loaded in the element !
- // we stop writting when Pixel are processed
- // FIX : we loose trailing elements (RAB, right now)
- guint16 el = tag->GetElement();
- guint16 group = tag->GetGroup();
- WriteEntryValue(tag, _fp, type);
- return true;
-}
-*/
//-----------------------------------------------------------------------------
// Protected
/**
- * \ingroup gdcmHeader
* \brief anonymize a Header (removes Patient's personal info)
* (read the code to see which ones ...)
*/
bool gdcmHeader::anonymizeHeader() {
gdcmDocEntry *patientNameHE = GetDocEntryByNumber (0x0010, 0x0010);
- // gdcmDocEntry *patientIDHE = GetDocEntryByNumber (0x0010, 0x0020);
ReplaceIfExistByNumber (" ",0x0010, 0x2154); // Telephone
ReplaceIfExistByNumber (" ",0x0010, 0x1040); // Adress
// Standard values and informations contained in the header
virtual bool IsReadable(void);
- bool IsJPEGBaseLineProcess1TransferSyntax(void);
- bool IsJPEGExtendedProcess2_4TransferSyntax(void);
- bool IsJPEGExtendedProcess3_5TransferSyntax(void);
- bool IsJPEGSpectralSelectionProcess6_8TransferSyntax(void);
- bool IsRLELossLessTransferSyntax(void);
- bool IsJPEGLossless(void);
- bool IsJPEG2000(void);
- bool IsDicomV3(void);
// Some heuristic based accessors, end user intended
// (to be moved to gdcmHeaderHelper?)
std::string GetTransfertSyntaxName(void);
- // When some proprietary shadow groups are disclosed, we can set up
- // an additional specific dictionary to access extra information.
-
- // OK : we still have *ONE* HeaderEntrySet,
- // with both Public and Shadow Elements
- // parsed against THE Public Dictionary and A (single) Shadow Dictionary
-
- // TODO Swig int SetShaDict(std::string filename);
- // TODO Swig int SetPubDict(std::string filename);
-
/// Accessor to \ref gdcmHeader::GrPixel
guint16 GetGrPixel(void) {return GrPixel;}
/// Accessor to \ref gdcmHeader::NumPixel
guint16 GetNumPixel(void) {return NumPixel;}
-// Entry
-
-// These functions are necessary for Python because
-// there are protected in the parent class
-
- inline virtual std::string GetEntryByNumber (guint16 group, guint16 element)
- { return(gdcmDocument::GetEntryByNumber(group,element)); }
-
- inline virtual std::string GetEntryVRByNumber(guint16 group, guint16 element)
- { return(gdcmDocument::GetEntryVRByNumber(group,element)); }
-
- inline virtual int GetEntryLengthByNumber(guint16 group, guint16 element)
- { return(gdcmDocument::GetEntryLengthByNumber(group,element)); }
-
- inline virtual std::string GetEntryByName (std::string tagName)
- { return(gdcmDocument::GetEntryByName(tagName)); }
-
- inline virtual std::string GetEntryVRByName (std::string tagName)
- { return(gdcmDocument::GetEntryVRByName(tagName)); }
-
- inline virtual bool SetEntryByNumber(std::string content,
- guint16 group, guint16 element)
- { return(gdcmDocument::SetEntryByNumber(content,group,element)); }
-
- inline virtual bool SetEntryByName(std::string content,std::string tagName)
- { return(gdcmDocument::SetEntryByName(content,tagName)); }
-
- inline virtual bool SetEntryLengthByNumber(guint32 l,
- guint16 group, guint16 element)
- { return(gdcmDocument::SetEntryLengthByNumber(l,group,element)); }
-
- inline virtual void UpdateShaEntries(void)
- { gdcmDocument::UpdateShaEntries(); }
-
/// Read (used in gdcmFile)
void SetImageDataSize(size_t ExpectedSize);
- bool operator<(gdcmHeader &header);
-
-// bool WriteEntry(gdcmDocEntry *tag,FILE *_fp,FileType type);
-
protected:
- //CLEANME int write(std::ostream&);
- //CLEANME int anonymize(std::ostream&);//FIXME: anonymize should be a friend
bool anonymizeHeader(void);
private: