1. Get rid of gdcmHeaderHelper, the class was only gdcmHeader with nice default values, no big deal
2. Left a legacy mode where you can still use the class gdcmHeaderHelper
3. Some minor clean up, but all the tests are passing
vtkCommonPython
vtkIOPython)
ENDIF (GDCM_WRAP_PYTHON)
-
+ENDIF(GDCM_VTK)
+
# generate a setup.py according to VTK installation
# put it in subdir in order to not override old one
${GDCM_SOURCE_DIR}/gdcmPython/setup.py.in
${GDCM_BINARY_DIR}/setup.py
)
-ENDIF(GDCM_VTK)
#-----------------------------------------------------------------------------
# Install stuff:
Program: gdcm
Module: $RCSfile: gdcmDocument.cxx,v $
Language: C++
- Date: $Date: 2004/06/20 18:08:47 $
- Version: $Revision: 1.19 $
+ Date: $Date: 2004/06/21 04:18:25 $
+ Version: $Revision: 1.20 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
* with a FALSE value for the 'enable_sequence' param.
* ('public elements' may be embedded in 'shadow Sequences')
*/
-gdcmDocument::gdcmDocument(const char *inFilename,
- bool exception_on_error,
- bool enable_sequences,
- bool ignore_shadow)
+gdcmDocument::gdcmDocument(std::string const & inFilename,
+ bool exception_on_error,
+ bool enable_sequences,
+ bool ignore_shadow)
: gdcmElementSet(-1) {
enableSequences=enable_sequences;
- ignoreShadow =ignore_shadow;
+ IgnoreShadow =ignore_shadow;
SetMaxSizeLoadEntry(MAX_SIZE_LOAD_ELEMENT_VALUE);
- filename = inFilename;
+ Filename = inFilename;
Initialise();
if ( !OpenFile(exception_on_error))
return;
dbg.Verbose(0, "gdcmDocument::gdcmDocument: starting parsing of file: ",
- filename.c_str());
+ Filename.c_str());
rewind(fp);
fseek(fp,0L,SEEK_END);
SQDepthLevel=0;
long l=ParseDES( this, beg, lgt, false); // le Load sera fait a la volee
+ (void)l; //is l used anywhere ?
CloseFile();
// --------------------------------------------------------------
RecCode == "CANRME_AILIBOD1_1." ) // for brain-damaged softwares
// with "little-endian strings"
{
- filetype = gdcmACR_LIBIDO;
+ Filetype = gdcmACR_LIBIDO;
std::string rows = GetEntryByNumber(0x0028, 0x0010);
std::string columns = GetEntryByNumber(0x0028, 0x0011);
SetEntryByNumber(columns, 0x0028, 0x0010);
* false otherwise.
*/
bool gdcmDocument::IsReadable(void) {
- if(filetype==gdcmUnknown) {
+ if(Filetype==gdcmUnknown) {
dbg.Verbose(0, "gdcmDocument::IsReadable: wrong filetype");
return(false);
}
* @return the FileType code
*/
FileType gdcmDocument::GetFileType(void) {
- return(filetype);
+ return Filetype;
}
/**
FILE *gdcmDocument::OpenFile(bool exception_on_error)
throw(gdcmFileError)
{
- fp=fopen(filename.c_str(),"rb");
+ fp=fopen(Filename.c_str(),"rb");
if(!fp)
{
throw gdcmFileError("gdcmDocument::gdcmDocument(const char *, bool)");
else
{
- std::cout <<"gdcmDocument::OpenFile cannot open file: "
- << filename.c_str() << std::endl;
dbg.Verbose(0, "gdcmDocument::OpenFile cannot open file: ",
- filename.c_str());
- return (NULL);
+ Filename.c_str());
+ return NULL;
}
}
//ACR -- or DICOM with no Preamble --
if( zero == 0x0008 || zero == 0x0800 || zero == 0x0002 || zero == 0x0200)
- return(fp);
+ return fp;
//DICOM
fseek(fp, 126L, SEEK_CUR);
char dicm[4];
fread(dicm, (size_t)4, (size_t)1, fp);
if( memcmp(dicm, "DICM", 4) == 0 )
- return(fp);
+ return fp;
fclose(fp);
- dbg.Verbose(0, "gdcmDocument::OpenFile not DICOM/ACR", filename.c_str());
+ dbg.Verbose(0, "gdcmDocument::OpenFile not DICOM/ACR", Filename.c_str());
}
else {
- dbg.Verbose(0, "gdcmDocument::OpenFile cannot open file", filename.c_str());
+ dbg.Verbose(0, "gdcmDocument::OpenFile cannot open file", Filename.c_str());
}
- return(NULL);
+ return NULL;
}
/**
*/
WriteEntries(fp,type);
- return(true);
+ return true;
}
/**
gdcmValEntry * gdcmDocument::ReplaceOrCreateByNumber(
std::string Value,
guint16 Group,
- guint16 Elem ){
+ guint16 Elem )
+{
gdcmDocEntry* CurrentEntry;
gdcmValEntry* ValEntry;
{
dbg.Verbose(0, "gdcmDocument::ReplaceOrCreateByNumber: call to"
" NewDocEntryByNumber failed.");
- return (gdcmValEntry *)0;
+ return NULL;
}
ValEntry = new gdcmValEntry(CurrentEntry);
if ( !AddEntry(ValEntry))
{
dbg.Verbose(0, "gdcmDocument::ReplaceOrCreateByNumber: removal"
" of previous DocEntry failed.");
- return (gdcmValEntry *)0;
+ return NULL;
}
if ( !AddEntry(ValEntry))
{
dbg.Verbose(0, "gdcmDocument::ReplaceOrCreateByNumber: adding"
" promoted ValEntry failed.");
- return (gdcmValEntry *)0;
+ return NULL;
}
}
}
a =NewBinEntryByNumber(Group, Elem);
if (a == NULL)
return NULL;
+
b = new gdcmBinEntry(a);
AddEntry(b);
}
SetEntryByNumber(voidArea, lgth, Group, Elem);
b->SetVoidArea(voidArea);
- return (gdcmBinEntry*)b;
+
+ return b;
}
*/
int gdcmDocument::CheckIfEntryExistByNumber(guint16 group, guint16 element ) {
std::string key = gdcmDictEntry::TranslateToKey(group, element );
- return (tagHT.count(key));
+ return tagHT.count(key);
}
/**
if( dictEntry == NULL)
return GDCM_UNFOUND;
- return(GetEntryByNumber(dictEntry->GetGroup(),dictEntry->GetElement()));
+ return GetEntryByNumber(dictEntry->GetGroup(),dictEntry->GetElement());
}
/**
if( dictEntry == NULL)
return false;
- return(SetEntryByNumber(content,dictEntry->GetGroup(),
- dictEntry->GetElement()));
+ return SetEntryByNumber(content,dictEntry->GetGroup(),
+ dictEntry->GetElement());
}
/**
guint16 group,
guint16 element)
{
+ (void)lgth; //not used
TagKey key = gdcmDictEntry::TranslateToKey(group, element);
if ( ! tagHT.count(key))
return false;
return NULL;
size_t o =(size_t)Element->GetOffset();
fseek(fp, o, SEEK_SET);
- size_t l=Element->GetLength();
+ size_t l = Element->GetLength();
char* a = new char[l];
- if(!a)
+ if(!a) {
+ dbg.Verbose(0, "gdcmDocument::LoadEntryVoidArea cannot allocate a");
return NULL;
-
+ }
SetEntryVoidAreaByNumber(a, Group, Elem);
/// \todo check the result
size_t l2 = fread(a, 1, l ,fp);
* Only non even entries are analyzed
*/
void gdcmDocument::UpdateShaEntries(void) {
- gdcmDictEntry *entry;
+ //gdcmDictEntry *entry;
std::string vr;
/// \todo TODO : still any use to explore recursively the whole structure?
if (gdcmBinEntry* BinEntry = dynamic_cast< gdcmBinEntry* >(tag) )
{
+ (void)BinEntry; //not used
/// \todo FIXME : when voidArea belong to gdcmBinEntry only, fix
/// voidArea length
//
WriteEntryValue(tag, _fp, type);
return true;
}
+
+ return false; //default behavior ?
}
/**
gdcmBinEntry *bn;
gdcmSeqEntry *sq;
VRKey vr;
- long l;
+ unsigned long l;
int depth;
depth = set->GetDepthLevel();
long lgt = ParseSQ( sq,
NewDocEntry->GetOffset(),
l, delim_mode);
+ (void)lgt; //not used...
}
// FIXME : on en fait quoi, de lgt ?
set->AddEntry(sq);
gdcmDocEntry *NewDocEntry = (gdcmDocEntry *)0;
gdcmSQItem *itemSQ;
bool dlm_mod;
- int lgr, l, lgth;
+ int lgr, lgth;
+ unsigned int l;
int depth = set->GetDepthLevel();
+ (void)depth; //not used
while (true) {
NewDocEntry = ReadNextDocEntry();
guint16 length16;
- if ( (filetype == gdcmExplicitVR) && (! Entry->IsImplicitVR()) )
+ if ( (Filetype == gdcmExplicitVR) && (! Entry->IsImplicitVR()) )
{
if ( (vr=="OB") || (vr=="OW") || (vr=="SQ") || (vr=="UN") )
{
*/
void gdcmDocument::FindDocEntryVR( gdcmDocEntry *Entry)
{
- if (filetype != gdcmExplicitVR)
+ if (Filetype != gdcmExplicitVR)
return;
char VR[3];
* (swaps it depending on processor endianity)
* @return read value
*/
-guint16 gdcmDocument::ReadInt16(void) {
+guint16 gdcmDocument::ReadInt16() {
guint16 g;
size_t item_read;
item_read = fread (&g, (size_t)2,(size_t)1, fp);
* (swaps it depending on processor endianity)
* @return read value
*/
-guint32 gdcmDocument::ReadInt32(void) {
+guint32 gdcmDocument::ReadInt32() {
guint32 g;
size_t item_read;
item_read = fread (&g, (size_t)4,(size_t)1, fp);
void gdcmDocument::Initialise(void)
{
RefPubDict = gdcmGlobal::GetDicts()->GetDefaultPubDict();
- RefShaDict = (gdcmDict*)0;
+ RefShaDict = NULL;
}
/**
// Use gdcmDocument::dicom_vr to test all the possibilities
// instead of just checking for UL, OB and UI !? group 0000
{
- filetype = gdcmExplicitVR;
+ Filetype = gdcmExplicitVR;
dbg.Verbose(1, "gdcmDocument::CheckSwap:",
"explicit Value Representation");
}
else
{
- filetype = gdcmImplicitVR;
+ Filetype = gdcmImplicitVR;
dbg.Verbose(1, "gdcmDocument::CheckSwap:",
"not an explicit Value Representation");
}
switch (s32) {
case 0x00040000 :
sw = 3412;
- filetype = gdcmACR;
+ Filetype = gdcmACR;
return true;
case 0x04000000 :
sw = 4321;
- filetype = gdcmACR;
+ Filetype = gdcmACR;
return true;
case 0x00000400 :
sw = 2143;
- filetype = gdcmACR;
+ Filetype = gdcmACR;
return true;
case 0x00000004 :
sw = 0;
- filetype = gdcmACR;
+ Filetype = gdcmACR;
return true;
default :
case 0x0004 :
case 0x0008 :
sw = 0;
- filetype = gdcmACR;
+ Filetype = gdcmACR;
return true;
case 0x0200 :
case 0x0400 :
case 0x0800 :
sw = 4321;
- filetype = gdcmACR;
+ Filetype = gdcmACR;
return true;
default :
dbg.Verbose(0, "gdcmDocument::CheckSwap:",
"ACR/NEMA unfound swap info (Really hopeless !)");
- filetype = gdcmUnknown;
+ Filetype = gdcmUnknown;
return false;
}
// BTW, what is the purpous of those length anyhow !?
char * BasicOffsetTableItemValue = new char[ItemLength + 1];
fread(BasicOffsetTableItemValue, ItemLength, 1, fp);
- for (int i=0; i < ItemLength; i += 4){
+ for (unsigned int i=0; i < ItemLength; i += 4){
guint32 IndividualLength;
IndividualLength = str2num(&BasicOffsetTableItemValue[i],guint32);
std::ostringstream s;
// JPEG Image
//// We then skip (not reading them) all the fragments of images:
- while ( ItemLength = ReadItemTagLength() )
+ while ( (ItemLength = ReadItemTagLength()) )
{
SkipBytes(ItemLength);
}
long RleSegmentLength[15], fragmentLength;
// while 'Sequence Delimiter Item' (fffe,e0dd) not found
- while ( fragmentLength = ReadSequenceDelimiterTagLength() )
+ while ( (fragmentLength = ReadSequenceDelimiterTagLength()) )
{
// Parse fragments of the current Fragment (Frame)
//------------------ scanning (not reading) fragment pixels
SkipBytes(RleSegmentLength[nbRleSegments]);
}
}
- return;
}
/**
* @param document
* @return true if 'smaller'
*/
- bool gdcmDocument::operator<(gdcmDocument &document){
+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);
+ return true;
else if(s1 > s2)
- return(false);
+ return false;
else
{
// Patient ID
s1=this->GetEntryByNumber(0x0010,0x0020);
s2=document.GetEntryByNumber(0x0010,0x0020);
if (s1 < s2)
- return(true);
+ return true;
else if (s1 > s2)
- return(1);
+ return true;
else
{
// Study Instance UID
s1=this->GetEntryByNumber(0x0020,0x000d);
s2=document.GetEntryByNumber(0x0020,0x000d);
if (s1 < s2)
- return(true);
+ return true;
else if(s1 > s2)
- return(false);
+ return false;
else
{
// Serie Instance UID
s1=this->GetEntryByNumber(0x0020,0x000e);
s2=document.GetEntryByNumber(0x0020,0x000e);
if (s1 < s2)
- return(true);
+ return true;
else if(s1 > s2)
- return(false);
+ return false;
}
}
}
- return(false);
+
+ return false;
}
Program: gdcm
Module: $RCSfile: gdcmDocument.h,v $
Language: C++
- Date: $Date: 2004/06/18 12:26:54 $
- Version: $Revision: 1.11 $
+ Date: $Date: 2004/06/21 04:18:25 $
+ Version: $Revision: 1.12 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
/// \brief Equals =1 if user wants to skip shadow groups while parsing
/// (to save space)
- int ignoreShadow;
+ int IgnoreShadow;
/// \brief Size threshold above which an element value will NOT be loaded
/// in memory (to avoid loading the image/volume itself). By default,
protected:
/// Refering underlying filename.
- std::string filename;
+ std::string Filename;
/// \brief SWap code (e.g. Big Endian, Little Endian, Bad Big Endian,
/// Bad Little Endian) according to the processor Endianity and
FILE *fp;
/// ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown
- FileType filetype;
+ FileType Filetype;
/// After opening the file, we read HEADER_LENGTH_TO_READ bytes.
static const unsigned int HEADER_LENGTH_TO_READ;
virtual void *LoadEntryVoidArea (guint16 Group, guint16 Element);
void LoadVLEntry (gdcmDocEntry *entry);
-// System access
+ // System access
guint16 SwapShort(guint16); // needed by gdcmFile
guint32 SwapLong(guint32); // needed by gdcmFile
guint16 UnswapShort(guint16); // needed by gdcmFile
// to instanciate from this class gdcmDocument (only gdcmHeader and
// gdcmDicomDir are meaningfull).
gdcmDocument(bool exception_on_error = false);
- gdcmDocument(const char *inFilename,
+ gdcmDocument(std::string const & inFilename,
bool exception_on_error = false,
bool enable_sequences = false,
bool ignore_shadow = false);
virtual ~gdcmDocument(void);
void gdcmDocument::Parse7FE0 (void);
-// Entry
+ // Entry
int CheckIfEntryExistByNumber(guint16 Group, guint16 Elem ); // int !
public:
virtual std::string GetEntryByName (std::string tagName);
virtual void *GetEntryVoidAreaByNumber(guint16 Group, guint16 Elem);
virtual bool SetEntryVoidAreaByNumber(void *a, guint16 Group, guint16 Elem);
- virtual void UpdateShaEntries(void);
+ virtual void UpdateShaEntries();
-// Header entry
+ // Header entry
gdcmDocEntry *GetDocEntryByNumber (guint16 group, guint16 element);
gdcmDocEntry *GetDocEntryByName (std::string Name);
void LoadDocEntrySafe(gdcmDocEntry *);
private:
-// Read
+ // 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 FixDocEntryFoundLength(gdcmDocEntry *, guint32);
bool IsDocEntryAnInteger (gdcmDocEntry *);
- guint32 FindDocEntryLengthOB(void);
+ guint32 FindDocEntryLengthOB();
- guint16 ReadInt16(void);
- guint32 ReadInt32(void);
+ guint16 ReadInt16();
+ guint32 ReadInt32();
void SkipBytes(guint32);
guint32 ReadTagLength(guint16, guint16);
- guint32 ReadItemTagLength(void);
- guint32 ReadSequenceDelimiterTagLength(void);
+ guint32 ReadItemTagLength();
+ guint32 ReadSequenceDelimiterTagLength();
- void Initialise(void);
- bool CheckSwap(void);
- void SwitchSwapToBigEndian(void);
+ void Initialise();
+ bool CheckSwap();
+ void SwitchSwapToBigEndian();
void SetMaxSizeLoadEntry(long);
void SetMaxSizePrintEntry(long);
std::string fourth = "unkn",
std::string name = "unkn");
// DocEntry related utilities
- gdcmDocEntry *ReadNextDocEntry (void);
+ gdcmDocEntry *ReadNextDocEntry ();
gdcmDocEntry *NewDocEntryByNumber(guint16 group,
guint16 element);
gdcmDocEntry *NewDocEntryByName (std::string Name);
public:
// Accessors:
/// Accessor to \ref printLevel
- void SetPrintLevel(int level) { printLevel = level; };
+ inline void SetPrintLevel(int level) { printLevel = level; }
/// Accessor to \ref filename
- inline std::string GetFileName(void) {return filename;}
+ inline std::string &GetFileName() { return Filename; }
/// Accessor to \ref filename
- inline void SetFileName(char* fileName) {filename = fileName;}
+ inline void SetFileName(const char* fileName) { Filename = fileName; }
/// Accessor to \ref gdcmElementSet::tagHT
- inline TagDocEntryHT &GetEntry(void) { return tagHT; };
+ inline TagDocEntryHT &GetEntry() { return tagHT; };
/// 'Swap code' accessor (see \ref sw )
- inline int GetSwapCode(void) { return sw; }
+ inline int GetSwapCode() { return sw; }
/// File pointer
- inline FILE * GetFP(void) { return fp; }
+ inline FILE * GetFP() { return fp; }
bool operator<(gdcmDocument &document);
Program: gdcm
Module: $RCSfile: gdcmHeader.cxx,v $
Language: C++
- Date: $Date: 2004/06/20 18:08:47 $
- Version: $Revision: 1.165 $
+ Date: $Date: 2004/06/21 04:18:25 $
+ Version: $Revision: 1.166 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
* @param ignore_shadow = true if user wants to skip shadow groups
* during parsing, to save memory space
*/
-gdcmHeader::gdcmHeader(const char *InFilename,
+gdcmHeader::gdcmHeader(std::string const & filename,
bool exception_on_error,
bool enable_sequences,
bool ignore_shadow):
- gdcmDocument(InFilename,exception_on_error,enable_sequences,ignore_shadow)
+ gdcmDocument(filename,exception_on_error,enable_sequences,ignore_shadow)
{
/*
typedef struct {
if (GrPixel == 0xe07f) // sometimes Image Location value doesn't follow
GrPixel = 0x7fe0; // the supposed processor endianity.
// see gdcmData/cr172241.dcm
- if (GrPixel != 0x7fe0)
+ if (GrPixel != 0x7fe0) {
// This is a kludge for old dirty Philips imager.
NumPixel = 0x1010;
- else
+ } else {
NumPixel = 0x0010;
-
+ }
}
/**
*/
bool gdcmHeader::IsReadable(void) {
if(!gdcmDocument::IsReadable()) {
- return(false);
+ return false;
}
std::string res = GetEntryByNumber(0x0028, 0x0005);
if ( res != GDCM_UNFOUND && atoi(res.c_str()) > 4 )
return 1;
}
+/**
+ * \ingroup gdcmHeader
+ * \brief gets the info from 0028,0030 : Pixel Spacing
+ * else 1.0
+ * @return X dimension of a pixel
+ */
+float gdcmHeader::GetXSpacing() {
+ float xspacing, yspacing;
+ std::string StrSpacing = GetEntryByNumber(0x0028,0x0030);
+
+ if (StrSpacing == GDCM_UNFOUND) {
+ dbg.Verbose(0, "gdcmHeader::GetXSpacing: unfound Pixel Spacing (0028,0030)");
+ return 1.;
+ }
+ int nbValues;
+ if( (nbValues = sscanf( StrSpacing.c_str(), "%f\\%f", &yspacing, &xspacing)) != 2) {
+ if (nbValues==1) // if single value is found, xspacing is defaulted to yspacing
+ return yspacing;
+ }
+ if (xspacing == 0.) {
+ dbg.Verbose(0, "gdcmHeader::GetYSpacing: gdcmData/CT-MONO2-8-abdo.dcm problem");
+ // seems to be a bug in the header ...
+ sscanf( StrSpacing.c_str(), "%f\\0\\%f", &yspacing, &xspacing);
+ }
+ return xspacing;
+}
+
+/**
+ * \ingroup gdcmHeader
+ * \brief gets the info from 0028,0030 : Pixel Spacing
+ * else 1.0
+ * @return Y dimension of a pixel
+ */
+float gdcmHeader::GetYSpacing() {
+ float yspacing;
+ std::string StrSpacing = GetEntryByNumber(0x0028,0x0030);
+
+ if (StrSpacing == GDCM_UNFOUND) {
+ dbg.Verbose(0, "gdcmHeader::GetYSpacing: unfound Pixel Spacing (0028,0030)");
+ return 1.;
+ }
+ sscanf( StrSpacing.c_str(), "%f", &yspacing);
+ return yspacing;
+}
+
+/**
+ *\ingroup gdcmHeader
+ *\brief gets the info from 0018,0088 : Space Between Slices
+ * else from 0018,0050 : Slice Thickness
+ * else 1.0
+ * @return Z dimension of a voxel-to be
+ */
+float gdcmHeader::GetZSpacing() {
+ // Spacing Between Slices : distance entre le milieu de chaque coupe
+ // Les coupes peuvent etre :
+ // jointives (Spacing between Slices = Slice Thickness)
+ // chevauchantes (Spacing between Slices < Slice Thickness)
+ // disjointes (Spacing between Slices > Slice Thickness)
+ // Slice Thickness : epaisseur de tissus sur laquelle est acquis le signal
+ // ca interesse le physicien de l'IRM, pas le visualisateur de volumes ...
+ // Si le Spacing Between Slices est absent,
+ // on suppose que les coupes sont jointives
+
+ std::string StrSpacingBSlices = GetEntryByNumber(0x0018,0x0088);
+
+ if (StrSpacingBSlices == GDCM_UNFOUND) {
+ dbg.Verbose(0, "gdcmHeader::GetZSpacing: unfound StrSpacingBSlices");
+ std::string StrSliceThickness = GetEntryByNumber(0x0018,0x0050);
+ if (StrSliceThickness == GDCM_UNFOUND)
+ return 1.;
+ else
+ // if no 'Spacing Between Slices' is found,
+ // we assume slices join together
+ // (no overlapping, no interslice gap)
+ // if they don't, we're fucked up
+ return atof(StrSliceThickness.c_str());
+ } else {
+ return atof(StrSpacingBSlices.c_str());
+ }
+}
+
+/**
+ *\ingroup gdcmHeader
+ *\brief gets the info from 0028,1052 : Rescale Intercept
+ * @return Rescale Intercept
+ */
+float gdcmHeader::GetRescaleIntercept() {
+ float resInter = 0.;
+ std::string StrRescInter = GetEntryByNumber(0x0028,0x1052); //0028 1052 DS IMG Rescale Intercept
+ if (StrRescInter != GDCM_UNFOUND) {
+ if( sscanf( StrRescInter.c_str(), "%f", &resInter) != 1) {
+ dbg.Verbose(0, "gdcmHeader::GetRescaleIntercept: Rescale Slope is empty");
+ // bug in the element 0x0028,0x1052
+ }
+ }
+ return resInter;
+}
+
+/**
+ *\ingroup gdcmHeader
+ *\brief gets the info from 0028,1053 : Rescale Slope
+ * @return Rescale Slope
+ */
+ float gdcmHeader::GetRescaleSlope() {
+ float resSlope = 1.;
+ std::string StrRescSlope = GetEntryByNumber(0x0028,0x1053); //0028 1053 DS IMG Rescale Slope
+ if (StrRescSlope != GDCM_UNFOUND) {
+ if( sscanf( StrRescSlope.c_str(), "%f", &resSlope) != 1) {
+ dbg.Verbose(0, "gdcmHeader::GetRescaleSlope: Rescale Slope is empty");
+ // bug in the element 0x0028,0x1053
+ }
+ }
+ return resSlope;
+}
+
+/**
+ * \ingroup gdcmHeader
+ * \brief This function is intended to user who doesn't want
+ * to have to manage a LUT and expects to get an RBG Pixel image
+ * (or a monochrome one ...)
+ * \warning to be used with GetImagePixels()
+ * @return 1 if Gray level, 3 if Color (RGB, YBR or PALETTE COLOR)
+ */
+int gdcmHeader::GetNumberOfScalarComponents() {
+ if (GetSamplesPerPixel() ==3)
+ return 3;
+
+ // 0028 0100 US IMG Bits Allocated
+ // (in order no to be messed up by old RGB images)
+ if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
+ return 3;
+
+ std::string PhotometricInterpretation =
+ gdcmHeader::GetEntryByNumber(0x0028,0x0004);
+
+ if ( ( PhotometricInterpretation == "PALETTE COLOR ") ) {
+ if (HasLUT()) // PALETTE COLOR is NOT enough
+ return 3;
+ else
+ return 1;
+ }
+
+ //beware of trailing space at end of string
+ if (PhotometricInterpretation.find(GDCM_UNFOUND) <
+ PhotometricInterpretation.length() ||
+ PhotometricInterpretation.find("MONOCHROME1") <
+ PhotometricInterpretation.length() ||
+ PhotometricInterpretation.find("MONOCHROME2") <
+ PhotometricInterpretation.length() )
+ return 1;
+ else
+ // we assume that *all* kinds of YBR are dealt with
+ return 3;
+}
+
+/**
+ * \ingroup gdcmHeader
+ * \brief This function is intended to user that DOESN'T want
+ * to get RGB pixels image when it's stored as a PALETTE COLOR image
+ * - the (vtk) user is supposed to know how deal with LUTs -
+ * \warning to be used with GetImagePixelsRaw()
+ * @return 1 if Gray level, 3 if Color (RGB or YBR - NOT 'PALETTE COLOR' -)
+ */
+int gdcmHeader::GetNumberOfScalarComponentsRaw() {
+
+ // 0028 0100 US IMG Bits Allocated
+ // (in order no to be messed up by old RGB images)
+ if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
+ return 3;
+
+ // we assume that *all* kinds of YBR are dealt with
+ return GetSamplesPerPixel();
+}
+
+/**
+ *\ingroup gdcmHeader
+ *\brief gets the info from 0020,000d : Study Instance UID
+ *\todo ? : return the ACR-NEMA element value if DICOM one is not found
+ * @return Study Instance UID
+ */
+//std::string gdcmHeader::GetStudyUID(){
+// return GetEntryByNumber(0x0020,0x000d); //0020 000d UI REL Study Instance UID
+//}
+
+/**
+ *\ingroup gdcmHeader
+ *\brief gets the info from 0020,000e : Series Instance UID
+ *\todo ? : return the ACR-NEMA element value if DICOM one is not found
+ * @return Series Instance UID
+ */
+//std::string gdcmHeader::GetSeriesUID(){
+// return GetEntryByNumber(0x0020,0x000e); //0020 000e UI REL Series Instance UID
+//}
+
+/**
+ *\ingroup gdcmHeader
+ *\brief gets the info from 0008,0016 : SOP Class UID
+ *\todo ? : return the ACR-NEMA element value if DICOM one is not found
+ * @return SOP Class UID
+ */
+//std::string gdcmHeader::GetClassUID(){
+// return GetEntryByNumber(0x0008,0x0016); //0008 0016 UI ID SOP Class UID
+//}
+
+/**
+ *\brief gets the info from 0008,0018 : SOP Instance UID
+ *\todo ? : return the ACR-NEMA element value if DICOM one is not found
+ * @return SOP Instance UID
+ */
+//std::string gdcmHeader::GetInstanceUID(){
+// return GetEntryByNumber(0x0008,0x0018); //0008 0018 UI ID SOP Instance UID
+//}
+//
+// -------------- Remember ! ----------------------------------
+//
+// Image Position Patient (0020,0032):
+// 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,
+// 0. for all the coordinates if nothing is found
+
+// \todo find a way to inform the caller nothing was found
+// \todo How to tell the caller a wrong number of values was found?
+//
+// ---------------------------------------------------------------
+//
+
+/**
+ * \brief gets the info from 0020,0032 : Image Position Patient
+ * else from 0020,0030 : Image Position (RET)
+ * else 0.
+ * @return up-left image corner X position
+ */
+
+float gdcmHeader::GetXOrigin() {
+ float xImPos, yImPos, zImPos;
+ std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
+
+ if (StrImPos == GDCM_UNFOUND) {
+ dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position Patient (0020,0032)");
+ StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images
+ if (StrImPos == GDCM_UNFOUND) {
+ dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position (RET) (0020,0030)");
+ /// \todo How to tell the caller nothing was found ?
+ return 0.;
+ }
+ }
+ if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3)
+ return 0.;
+ return xImPos;
+}
+
+/**
+ * \brief gets the info from 0020,0032 : Image Position Patient
+ * else from 0020,0030 : Image Position (RET)
+ * else 0.
+ * @return up-left image corner Y position
+ */
+float gdcmHeader::GetYOrigin() {
+ float xImPos, yImPos, zImPos;
+ std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
+
+ if (StrImPos == GDCM_UNFOUND) {
+ dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position Patient (0020,0032)");
+ StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images
+ if (StrImPos == GDCM_UNFOUND) {
+ dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position (RET) (0020,0030)");
+ /// \todo How to tell the caller nothing was found ?
+ return 0.;
+ }
+ }
+ if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3)
+ return 0.;
+ return yImPos;
+}
+
+/**
+ * \brief gets the info from 0020,0032 : Image Position Patient
+ * \ else from 0020,0030 : Image Position (RET)
+ * \ else from 0020,1041 : Slice Location
+ * \ else from 0020,0050 : Location
+ * \ else 0.
+ * @return up-left image corner Z position
+ */
+float gdcmHeader::GetZOrigin() {
+ float xImPos, yImPos, zImPos;
+ std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
+ if (StrImPos != GDCM_UNFOUND) {
+ if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) {
+ dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position Patient (0020,0032)");
+ return 0.; // bug in the element 0x0020,0x0032
+ } else {
+ return zImPos;
+ }
+ }
+ StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images
+ if (StrImPos != GDCM_UNFOUND) {
+ if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) {
+ dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position (RET) (0020,0030)");
+ return 0.; // bug in the element 0x0020,0x0032
+ } else {
+ return zImPos;
+ }
+ }
+ std::string StrSliceLocation = GetEntryByNumber(0x0020,0x1041);// for *very* old ACR-NEMA images
+ if (StrSliceLocation != GDCM_UNFOUND) {
+ if( sscanf( StrSliceLocation.c_str(), "%f", &zImPos) !=1) {
+ dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Slice Location (0020,1041)");
+ return 0.; // bug in the element 0x0020,0x1041
+ } else {
+ return zImPos;
+ }
+ }
+ dbg.Verbose(0, "gdcmHeader::GetZImagePosition: unfound Slice Location (0020,1041)");
+ std::string StrLocation = GetEntryByNumber(0x0020,0x0050);
+ if (StrLocation != GDCM_UNFOUND) {
+ if( sscanf( StrLocation.c_str(), "%f", &zImPos) !=1) {
+ dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Location (0020,0050)");
+ return 0.; // bug in the element 0x0020,0x0050
+ } else {
+ return zImPos;
+ }
+ }
+ dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Location (0020,0050)");
+ return 0.; // Hopeless
+}
+
+/**
+ * \brief gets the info from 0020,0013 : Image Number
+ * \ else 0.
+ * @return image number
+ */
+int gdcmHeader::GetImageNumber() {
+ // The function i atoi() takes the address of an area of memory as
+ // parameter and converts the string stored at that location to an integer
+ // using the external decimal to internal binary conversion rules. This may
+ // be preferable to sscanf() since atoi() is a much smaller, simpler and
+ // faster function. sscanf() can do all possible conversions whereas
+ // atoi() can only do single decimal integer conversions.
+ std::string StrImNumber = GetEntryByNumber(0x0020,0x0013); //0020 0013 IS REL Image Number
+ if (StrImNumber != GDCM_UNFOUND) {
+ return atoi( StrImNumber.c_str() );
+ }
+ return 0; //Hopeless
+}
+
+/**
+ * \brief gets the info from 0008,0060 : Modality
+ * @return Modality Type
+ */
+ModalityType gdcmHeader::GetModality(void) {
+ // 0008 0060 CS ID Modality
+ std::string StrModality = GetEntryByNumber(0x0008,0x0060);
+ if (StrModality != GDCM_UNFOUND) {
+ if ( StrModality.find("AU") < StrModality.length()) return AU;
+ else if ( StrModality.find("AS") < StrModality.length()) return AS;
+ else if ( StrModality.find("BI") < StrModality.length()) return BI;
+ else if ( StrModality.find("CF") < StrModality.length()) return CF;
+ else if ( StrModality.find("CP") < StrModality.length()) return CP;
+ else if ( StrModality.find("CR") < StrModality.length()) return CR;
+ else if ( StrModality.find("CT") < StrModality.length()) return CT;
+ else if ( StrModality.find("CS") < StrModality.length()) return CS;
+ else if ( StrModality.find("DD") < StrModality.length()) return DD;
+ else if ( StrModality.find("DF") < StrModality.length()) return DF;
+ else if ( StrModality.find("DG") < StrModality.length()) return DG;
+ else if ( StrModality.find("DM") < StrModality.length()) return DM;
+ else if ( StrModality.find("DS") < StrModality.length()) return DS;
+ else if ( StrModality.find("DX") < StrModality.length()) return DX;
+ else if ( StrModality.find("ECG") < StrModality.length()) return ECG;
+ else if ( StrModality.find("EPS") < StrModality.length()) return EPS;
+ else if ( StrModality.find("FA") < StrModality.length()) return FA;
+ else if ( StrModality.find("FS") < StrModality.length()) return FS;
+ else if ( StrModality.find("HC") < StrModality.length()) return HC;
+ else if ( StrModality.find("HD") < StrModality.length()) return HD;
+ else if ( StrModality.find("LP") < StrModality.length()) return LP;
+ else if ( StrModality.find("LS") < StrModality.length()) return LS;
+ else if ( StrModality.find("MA") < StrModality.length()) return MA;
+ else if ( StrModality.find("MR") < StrModality.length()) return MR;
+ else if ( StrModality.find("NM") < StrModality.length()) return NM;
+ else if ( StrModality.find("OT") < StrModality.length()) return OT;
+ else if ( StrModality.find("PT") < StrModality.length()) return PT;
+ else if ( StrModality.find("RF") < StrModality.length()) return RF;
+ else if ( StrModality.find("RG") < StrModality.length()) return RG;
+ else if ( StrModality.find("RTDOSE") < StrModality.length()) return RTDOSE;
+ else if ( StrModality.find("RTIMAGE") < StrModality.length()) return RTIMAGE;
+ else if ( StrModality.find("RTPLAN") < StrModality.length()) return RTPLAN;
+ else if ( StrModality.find("RTSTRUCT")< StrModality.length()) return RTSTRUCT;
+ else if ( StrModality.find("SM") < StrModality.length()) return SM;
+ else if ( StrModality.find("ST") < StrModality.length()) return ST;
+ else if ( StrModality.find("TG") < StrModality.length()) return TG;
+ else if ( StrModality.find("US") < StrModality.length()) return US;
+ else if ( StrModality.find("VF") < StrModality.length()) return VF;
+ else if ( StrModality.find("XA") < StrModality.length()) return XA;
+ else if ( StrModality.find("XC") < StrModality.length()) return XC;
+
+ else
+ {
+ /// \todo throw error return value ???
+ /// specified <> unknow in our database
+ return Unknow;
+ }
+ }
+ return Unknow;
+}
+
/**
* \ingroup gdcmHeader
* \brief Retrieve the number of Bits Stored (actually used)
* @return The encountered number of Bits Stored, 0 by default.
* 0 means the file is NOT USABLE. The caller has to check it !
*/
-int gdcmHeader::GetBitsStored(void) {
+int gdcmHeader::GetBitsStored() {
std::string StrSize = GetEntryByNumber(0x0028,0x0101);
if (StrSize == GDCM_UNFOUND)
return 0; // It's supposed to be mandatory
* @return The size in bytes of a single pixel of data; 0 by default
* 0 means the file is NOT USABLE; the caller will have to check
*/
-int gdcmHeader::GetPixelSize(void) {
+int gdcmHeader::GetPixelSize() {
+ // 0028 0100 US IMG Bits Allocated
+ // (in order no to be messed up by old RGB images)
+// if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
+// return 3;
+
std::string PixelType = GetPixelType();
if (PixelType == "8U" || PixelType == "8S")
return 1;
* 24 bit images appear as 8 bit
* @return 0S if nothing found. NOT USABLE file. The caller has to check
*/
-std::string gdcmHeader::GetPixelType(void) {
+std::string gdcmHeader::GetPixelType() {
std::string BitsAlloc = GetEntryByNumber(0x0028, 0x0100); // Bits Allocated
if (BitsAlloc == GDCM_UNFOUND) {
dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated");
* Please warn me if you know sbdy that *does* know ... jprx
* @return true if LUT Descriptors and LUT Tables were found
*/
-bool gdcmHeader::HasLUT(void) {
+bool gdcmHeader::HasLUT() {
// Check the presence of the LUT Descriptors, and LUT Tables
// LutDescriptorRed
* \brief anonymize a Header (removes Patient's personal info)
* (read the code to see which ones ...)
*/
-bool gdcmHeader::anonymizeHeader() {
+bool gdcmHeader::AnonymizeHeader() {
gdcmDocEntry *patientNameHE = GetDocEntryByNumber (0x0010, 0x0010);
ReplaceIfExistByNumber (" ",0x0010, 0x0020); // Patient ID
if (patientNameHE) {
- std::string StudyInstanceUID = GetEntryByNumber (0x0020, 0x000d);
- if (StudyInstanceUID !=GDCM_UNFOUND)
- ReplaceOrCreateByNumber(StudyInstanceUID, 0x0010, 0x0010);
+ std::string studyInstanceUID = GetEntryByNumber (0x0020, 0x000d);
+ if (studyInstanceUID !=GDCM_UNFOUND)
+ ReplaceOrCreateByNumber(studyInstanceUID, 0x0010, 0x0010);
else
ReplaceOrCreateByNumber(std::string("anonymised"), 0x0010, 0x0010);
}
//300e 0004 DA RT Review Date
return true;
}
+
+/**
+ * \brief gets the info from 0020,0037 : Image Orientation Patient
+ * @param iop adress of the (6)float aray to receive values
+ * @return cosines of image orientation patient
+ */
+void gdcmHeader::GetImageOrientationPatient( float* iop ) {
+
+ //iop is supposed to be float[6]
+ iop[0] = iop[1] = iop[2] = iop[3] = iop[4] = iop[5] = 0;
+
+ // 0020 0037 DS REL Image Orientation (Patient)
+ std::string StrImOriPat = GetEntryByNumber(0x0020,0x0037);
+ if (StrImOriPat != GDCM_UNFOUND) {
+ if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f",
+ &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) {
+ dbg.Verbose(0, "gdcmHeader::GetImageOrientationPatient: wrong Image Orientation Patient (0020,0037)");
+ return ; // bug in the element 0x0020,0x0037
+ }
+ else
+ return ;
+ }
+
+ //For ACR-NEMA
+ // 0020 0035 DS REL Image Orientation (RET)
+ StrImOriPat = GetEntryByNumber(0x0020,0x0035);
+ if (StrImOriPat != GDCM_UNFOUND) {
+ if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f",
+ &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) {
+ dbg.Verbose(0, "gdcmHeader::GetImageOrientationPatient: wrong Image Orientation Patient (0020,0035)");
+ return ; // bug in the element 0x0020,0x0035
+ }
+ else
+ return ;
+ }
+}
+
//-----------------------------------------------------------------------------
// Private
Program: gdcm
Module: $RCSfile: gdcmHeader.h,v $
Language: C++
- Date: $Date: 2004/06/20 18:08:48 $
- Version: $Revision: 1.74 $
+ Date: $Date: 2004/06/21 04:18:26 $
+ Version: $Revision: 1.75 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
* protected due to Swig limitations for as Has_a dependency between
* gdcmFile and gdcmHeader.
*/
+
+//-----------------------------------------------------------------------------
+// Dicom Part 3.3 Compliant
+enum ModalityType {
+ Unknow,
+ AU, // Voice Audio
+ AS, // Angioscopy
+ BI, // Biomagnetic Imaging
+ CF, // Cinefluorography
+ CP, // Culposcopy
+ CR, // Computed Radiography
+ CS, // Cystoscopy
+ CT, // Computed Tomography
+ DD, // Duplex Dopler
+ DF, // Digital Fluoroscopy
+ DG, // Diaphanography
+ DM, // Digital Microscopy
+ DS, // Digital Substraction Angiography
+ DX, // Digital Radiography
+ ECG, // Echocardiography
+ EPS, // Basic Cardiac EP
+ ES, // Endoscopy
+ FA, // Fluorescein Angiography
+ FS, // Fundoscopy
+ HC, // Hard Copy
+ HD, // Hemodynamic
+ LP, // Laparoscopy
+ LS, // Laser Surface Scan
+ MA, // Magnetic Resonance Angiography
+ MR, // Magnetic Resonance
+ NM, // Nuclear Medicine
+ OT, // Other
+ PT, // Positron Emission Tomography
+ RF, // Radio Fluoroscopy
+ RG, // Radiographic Imaging
+ RTDOSE, // Radiotherapy Dose
+ RTIMAGE, // Radiotherapy Image
+ RTPLAN, // Radiotherapy Plan
+ RTSTRUCT, // Radiotherapy Structure Set
+ SM, // Microscopic Imaging
+ ST, // Single-photon Emission Computed Tomography
+ TG, // Thermography
+ US, // Ultrasound
+ VF, // Videofluorography
+ XA, // X-Ray Angiography
+ XC // Photographic Imaging
+};
+//-----------------------------------------------------------------------------
+
class GDCM_EXPORT gdcmHeader : public gdcmDocument
{
protected:
public:
gdcmHeader(bool exception_on_error = false);
- gdcmHeader(const char *filename,
+ gdcmHeader(std::string const & filename,
bool exception_on_error = false,
bool enable_sequences = false,
bool skip_shadow = false);
virtual ~gdcmHeader();
// Standard values and informations contained in the header
- virtual bool IsReadable(void);
+ virtual bool IsReadable();
// Some heuristic based accessors, end user intended
- // (to be moved to gdcmHeaderHelper?)
- int GetXSize(void);
- int GetYSize(void);
- int GetZSize(void);
- int GetBitsStored(void);
- int GetBitsAllocated(void);
- int GetSamplesPerPixel(void);
- int GetPlanarConfiguration(void);
-
- int GetPixelSize(void);
- std::string GetPixelType(void);
- size_t GetPixelOffset(void);
- size_t GetPixelAreaLength(void);
-
- bool HasLUT(void);
- int GetLUTNbits(void);
- unsigned char * GetLUTRGBA(void);
-
- std::string GetTransfertSyntaxName(void);
+ int GetBitsStored();
+ int GetBitsAllocated();
+ int GetSamplesPerPixel();
+ int GetPlanarConfiguration();
+ int GetPixelSize();
+
+ int GetPixelSizeGetPixelType();
+ std::string GetPixelType();
+ size_t GetPixelOffset();
+ size_t GetPixelAreaLength();
+
+ //Some image informations needed for third package imaging library
+ int GetXSize();
+ int GetYSize();
+ int GetZSize();
+
+ float GetXSpacing();
+ float GetYSpacing();
+ float GetZSpacing();
+ //void GetSpacing(float &x, float &y, float &z);
+
+ // Useful for rescaling graylevel:
+ float GetRescaleIntercept();
+ float GetRescaleSlope();
+
+ int GetNumberOfScalarComponents();
+ int GetNumberOfScalarComponentsRaw();
+
+ // This is usefull for strategy of ordering study / series
+ // Marking them as deprecated since I believe this is achieve in the
+ // gdcmDocument operator<
+ //std::string GetStudyUID();
+ //std::string GetSeriesUID();
+ //std::string GetClassUID();
+ //std::string GetInstanceUID();
+
+ int GetImageNumber();
+ ModalityType GetModality();
+
+ /**
+ * change GetXImagePosition -> GetXOrigin in order not to confuse reader
+ * -# GetXOrigin can return default value (=0) if it was not ImagePosition
+ * -# Image Position is different in dicomV3 <> ACR NEMA -> better use generic
+ * name
+ */
+ float GetXOrigin();
+ float GetYOrigin();
+ float GetZOrigin();
+ //void GetOrigin(float &x, float &y, float &z);
+
+ bool HasLUT();
+ int GetLUTNbits();
+ unsigned char * GetLUTRGBA();
+
+ std::string GetTransfertSyntaxName();
/// Accessor to \ref gdcmHeader::GrPixel
- guint16 GetGrPixel(void) {return GrPixel;}
+ guint16 GetGrPixel() {return GrPixel;}
/// Accessor to \ref gdcmHeader::NumPixel
- guint16 GetNumPixel(void) {return NumPixel;}
+ guint16 GetNumPixel() {return NumPixel;}
/// Read (used in gdcmFile)
- void SetImageDataSize(size_t ExpectedSize);
+ void SetImageDataSize(size_t expectedSize);
protected:
- bool anonymizeHeader(void);
-private:
+ bool AnonymizeHeader();
+ void GetImageOrientationPatient( float* iop );
+private:
+ friend class gdcmSerieHeader;
};
//-----------------------------------------------------------------------------
Program: gdcm
Module: $RCSfile: gdcmHeaderHelper.cxx,v $
Language: C++
- Date: $Date: 2004/06/20 18:08:48 $
- Version: $Revision: 1.37 $
+ Date: $Date: 2004/06/21 04:18:26 $
+ Version: $Revision: 1.38 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
#include <algorithm>
#include <vector>
-//-----------------------------------------------------------------------------
-/**
- * \brief constructor
- */
-gdcmHeaderHelper::gdcmHeaderHelper() : gdcmHeader( ) {
-
-}
-
-/**
- * \brief constructor
- * @param InFilename Name of the file to deal with
- * @param exception_on_error
- * @param enable_sequences = true to allow the header
- * to be parsed *inside* the SeQuences,
- * when they have an actual length
- * @param ignore_shadow = true if user wants to skip shadow groups
- * during parsing, to save memory space
- */
-gdcmHeaderHelper::gdcmHeaderHelper(const char *InFilename,
- bool exception_on_error,
- bool enable_sequences,
- bool ignore_shadow)
- : gdcmHeader( InFilename,
- exception_on_error,
- enable_sequences,
- ignore_shadow)
-{
-}
-
-//-----------------------------------------------------------------------------
-// Print
-
-//-----------------------------------------------------------------------------
-// Public
-/**
- * \brief Returns the size (in bytes) of a single pixel of data.
- * @return The size in bytes of a single pixel of data.
- *
- */
-int gdcmHeaderHelper::GetPixelSize() {
-
- // 0028 0100 US IMG Bits Allocated
- // (in order no to be messed up by old RGB images)
- if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
- return 3;
-
- std::string PixelType = GetPixelType();
- if (PixelType == "8U" || PixelType == "8S")
- return 1;
- if (PixelType == "16U" || PixelType == "16S")
- return 2;
- if (PixelType == "32U" || PixelType == "32S")
- return 4;
- if (PixelType == "FD") // to help unfortunate users to manage DOUBLE
- return 8;
- dbg.Verbose(0, "gdcmHeader::GetPixelSize: Unknown pixel type");
- return 0;
-}
-
-/**
- * \ingroup gdcmHeaderHelper
- * \brief Build the Pixel Type of the image.
- * Possible values are:
- * - 8U unsigned 8 bit,
- * - 8S signed 8 bit,
- * - 16U unsigned 16 bit,
- * - 16S signed 16 bit,
- * - 32U unsigned 32 bit,
- * - 32S signed 32 bit,
- * - FD Double,
- * \warning 12 bit images appear as 16 bit.
- * 24 bit images appear as 8 bit
- * 64 bit means 'DOUBLE' images
- * (no DOUBLE images in kosher DICOM,
- * but so usefull for people that miss them ;-)
- * @return
- */
-std::string gdcmHeaderHelper::GetPixelType() {
- std::string BitsAlloc;
- BitsAlloc = GetEntryByNumber(0x0028, 0x0100);
- if (BitsAlloc == GDCM_UNFOUND) { // Bits Allocated
- dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated");
- BitsAlloc = std::string("16");
- }
- if (BitsAlloc == "12") // It will be unpacked
- BitsAlloc = std::string("16");
- else if (BitsAlloc == "24") // (in order no to be messed up
- BitsAlloc = std::string("8"); // by old RGB images)
-
- std::string Signed;
- Signed = GetEntryByNumber(0x0028, 0x0103);
- if (Signed == GDCM_UNFOUND) { // "Pixel Representation"
- dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation");
- BitsAlloc = std::string("0");
- }
- if (BitsAlloc == "64") // to help users that want to deal with DOUBLE
- return("FD");
-
- if (Signed == "0")
- Signed = std::string("U");
- else
- Signed = std::string("S");
-
- return( BitsAlloc + Signed);
-}
-
-/**
- * \ingroup gdcmHeaderHelper
- * \brief gets the info from 0028,0030 : Pixel Spacing
- * else 1.0
- * @return X dimension of a pixel
- */
-float gdcmHeaderHelper::GetXSpacing() {
- float xspacing, yspacing;
- std::string StrSpacing = GetEntryByNumber(0x0028,0x0030);
-
- if (StrSpacing == GDCM_UNFOUND) {
- dbg.Verbose(0, "gdcmHeader::GetXSpacing: unfound Pixel Spacing (0028,0030)");
- return 1.;
- }
- int nbValues;
- if( (nbValues = sscanf( StrSpacing.c_str(), "%f\\%f", &yspacing, &xspacing)) != 2) {
- if (nbValues==1) // if single value is found, xspacing is defaulted to yspacing
- return yspacing;
- }
- if (xspacing == 0.) {
- dbg.Verbose(0, "gdcmHeader::GetYSpacing: gdcmData/CT-MONO2-8-abdo.dcm problem");
- // seems to be a bug in the header ...
- sscanf( StrSpacing.c_str(), "%f\\0\\%f", &yspacing, &xspacing);
- }
- return xspacing;
-}
-
-/**
- * \ingroup gdcmHeaderHelper
- * \brief gets the info from 0028,0030 : Pixel Spacing
- * else 1.0
- * @return Y dimension of a pixel
- */
-float gdcmHeaderHelper::GetYSpacing() {
- float yspacing;
- std::string StrSpacing = GetEntryByNumber(0x0028,0x0030);
-
- if (StrSpacing == GDCM_UNFOUND) {
- dbg.Verbose(0, "gdcmHeader::GetYSpacing: unfound Pixel Spacing (0028,0030)");
- return 1.;
- }
- sscanf( StrSpacing.c_str(), "%f", &yspacing);
- return yspacing;
-}
-
-/**
- *\ingroup gdcmHeaderHelper
- *\brief gets the info from 0018,0088 : Space Between Slices
- * else from 0018,0050 : Slice Thickness
- * else 1.0
- * @return Z dimension of a voxel-to be
- */
-float gdcmHeaderHelper::GetZSpacing() {
- // Spacing Between Slices : distance entre le milieu de chaque coupe
- // Les coupes peuvent etre :
- // jointives (Spacing between Slices = Slice Thickness)
- // chevauchantes (Spacing between Slices < Slice Thickness)
- // disjointes (Spacing between Slices > Slice Thickness)
- // Slice Thickness : epaisseur de tissus sur laquelle est acquis le signal
- // ca interesse le physicien de l'IRM, pas le visualisateur de volumes ...
- // Si le Spacing Between Slices est absent,
- // on suppose que les coupes sont jointives
-
- std::string StrSpacingBSlices = GetEntryByNumber(0x0018,0x0088);
-
- if (StrSpacingBSlices == GDCM_UNFOUND) {
- dbg.Verbose(0, "gdcmHeader::GetZSpacing: unfound StrSpacingBSlices");
- std::string StrSliceThickness = GetEntryByNumber(0x0018,0x0050);
- if (StrSliceThickness == GDCM_UNFOUND)
- return 1.;
- else
- // if no 'Spacing Between Slices' is found,
- // we assume slices join together
- // (no overlapping, no interslice gap)
- // if they don't, we're fucked up
- return atof(StrSliceThickness.c_str());
- } else {
- return atof(StrSpacingBSlices.c_str());
- }
-}
-
-/**
- *\ingroup gdcmHeaderHelper
- *\brief gets the info from 0028,1052 : Rescale Intercept
- * @return Rescale Intercept
- */
-float gdcmHeaderHelper::GetRescaleIntercept() {
- float resInter = 0.;
- std::string StrRescInter = GetEntryByNumber(0x0028,0x1052); //0028 1052 DS IMG Rescale Intercept
- if (StrRescInter != GDCM_UNFOUND) {
- if( sscanf( StrRescInter.c_str(), "%f", &resInter) != 1) {
- dbg.Verbose(0, "gdcmHeader::GetRescaleIntercept: Rescale Slope is empty");
- // bug in the element 0x0028,0x1052
- }
- }
- return resInter;
-}
-
-/**
- *\ingroup gdcmHeaderHelper
- *\brief gets the info from 0028,1053 : Rescale Slope
- * @return Rescale Slope
- */
- float gdcmHeaderHelper::GetRescaleSlope() {
- float resSlope = 1.;
- std::string StrRescSlope = GetEntryByNumber(0x0028,0x1053); //0028 1053 DS IMG Rescale Slope
- if (StrRescSlope != GDCM_UNFOUND) {
- if( sscanf( StrRescSlope.c_str(), "%f", &resSlope) != 1) {
- dbg.Verbose(0, "gdcmHeader::GetRescaleSlope: Rescale Slope is empty");
- // bug in the element 0x0028,0x1053
- }
- }
- return resSlope;
-}
-
-/**
- * \ingroup gdcmHeaderHelper
- * \brief This function is intended to user who doesn't want
- * to have to manage a LUT and expects to get an RBG Pixel image
- * (or a monochrome one ...)
- * \warning to be used with GetImagePixels()
- * @return 1 if Gray level, 3 if Color (RGB, YBR or PALETTE COLOR)
- */
-int gdcmHeaderHelper::GetNumberOfScalarComponents() {
- if (GetSamplesPerPixel() ==3)
- return 3;
-
- // 0028 0100 US IMG Bits Allocated
- // (in order no to be messed up by old RGB images)
- if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
- return 3;
-
- std::string PhotometricInterpretation =
- gdcmHeader::GetEntryByNumber(0x0028,0x0004);
-
- if ( ( PhotometricInterpretation == "PALETTE COLOR ") ) {
- if (HasLUT()) // PALETTE COLOR is NOT enough
- return 3;
- else
- return 1;
- }
-
- //beware of trailing space at end of string
- if (PhotometricInterpretation.find(GDCM_UNFOUND) <
- PhotometricInterpretation.length() ||
- PhotometricInterpretation.find("MONOCHROME1") <
- PhotometricInterpretation.length() ||
- PhotometricInterpretation.find("MONOCHROME2") <
- PhotometricInterpretation.length() )
- return 1;
- else
- // we assume that *all* kinds of YBR are dealt with
- return 3;
-}
-
-/**
- * \ingroup gdcmHeaderHelper
- * \brief This function is intended to user that DOESN'T want
- * to get RGB pixels image when it's stored as a PALETTE COLOR image
- * - the (vtk) user is supposed to know how deal with LUTs -
- * \warning to be used with GetImagePixelsRaw()
- * @return 1 if Gray level, 3 if Color (RGB or YBR - NOT 'PALETTE COLOR' -)
- */
-int gdcmHeaderHelper::GetNumberOfScalarComponentsRaw() {
-
- // 0028 0100 US IMG Bits Allocated
- // (in order no to be messed up by old RGB images)
- if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
- return 3;
-
- // we assume that *all* kinds of YBR are dealt with
- return GetSamplesPerPixel();
-}
-
-/**
- *\ingroup gdcmHeaderHelper
- *\brief gets the info from 0020,000d : Study Instance UID
- *\todo ? : return the ACR-NEMA element value if DICOM one is not found
- * @return Study Instance UID
- */
- std::string gdcmHeaderHelper::GetStudyUID(){
- return GetEntryByNumber(0x0020,0x000d); //0020 000d UI REL Study Instance UID
-}
-
-/**
- *\ingroup gdcmHeaderHelper
- *\brief gets the info from 0020,000e : Series Instance UID
- *\todo ? : return the ACR-NEMA element value if DICOM one is not found
- * @return Series Instance UID
- */
- std::string gdcmHeaderHelper::GetSeriesUID(){
- return GetEntryByNumber(0x0020,0x000e); //0020 000e UI REL Series Instance UID
-}
-
-/**
- *\ingroup gdcmHeaderHelper
- *\brief gets the info from 0008,0016 : SOP Class UID
- *\todo ? : return the ACR-NEMA element value if DICOM one is not found
- * @return SOP Class UID
- */
- std::string gdcmHeaderHelper::GetClassUID(){
- return GetEntryByNumber(0x0008,0x0016); //0008 0016 UI ID SOP Class UID
-}
-
-/**
- *\brief gets the info from 0008,0018 : SOP Instance UID
- *\todo ? : return the ACR-NEMA element value if DICOM one is not found
- * @return SOP Instance UID
- */
- std::string gdcmHeaderHelper::GetInstanceUID(){
- return GetEntryByNumber(0x0008,0x0018); //0008 0018 UI ID SOP Instance UID
-}
-//
-// -------------- Remember ! ----------------------------------
-//
-// Image Position Patient (0020,0032):
-// 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,
-// 0. for all the coordinates if nothing is found
-
-// \todo find a way to inform the caller nothing was found
-// \todo How to tell the caller a wrong number of values was found?
-//
-// ---------------------------------------------------------------
-//
-
-/**
- * \brief gets the info from 0020,0032 : Image Position Patient
- * else from 0020,0030 : Image Position (RET)
- * else 0.
- * @return up-left image corner X position
- */
-
-float gdcmHeaderHelper::GetXOrigin() {
- float xImPos, yImPos, zImPos;
- std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
-
- if (StrImPos == GDCM_UNFOUND) {
- dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position Patient (0020,0032)");
- StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images
- if (StrImPos == GDCM_UNFOUND) {
- dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position (RET) (0020,0030)");
- /// \todo How to tell the caller nothing was found ?
- return 0.;
- }
- }
- if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3)
- return 0.;
- return xImPos;
-}
-
-/**
- * \brief gets the info from 0020,0032 : Image Position Patient
- * else from 0020,0030 : Image Position (RET)
- * else 0.
- * @return up-left image corner Y position
- */
-float gdcmHeaderHelper::GetYOrigin() {
- float xImPos, yImPos, zImPos;
- std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
-
- if (StrImPos == GDCM_UNFOUND) {
- dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position Patient (0020,0032)");
- StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images
- if (StrImPos == GDCM_UNFOUND) {
- dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position (RET) (0020,0030)");
- /// \todo How to tell the caller nothing was found ?
- return 0.;
- }
- }
- if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3)
- return 0.;
- return yImPos;
-}
-
-/**
- * \brief gets the info from 0020,0032 : Image Position Patient
- * \ else from 0020,0030 : Image Position (RET)
- * \ else from 0020,1041 : Slice Location
- * \ else from 0020,0050 : Location
- * \ else 0.
- * @return up-left image corner Z position
- */
-float gdcmHeaderHelper::GetZOrigin() {
- float xImPos, yImPos, zImPos;
- std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
- if (StrImPos != GDCM_UNFOUND) {
- if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) {
- dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position Patient (0020,0032)");
- return 0.; // bug in the element 0x0020,0x0032
- } else {
- return zImPos;
- }
- }
- StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images
- if (StrImPos != GDCM_UNFOUND) {
- if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) {
- dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position (RET) (0020,0030)");
- return 0.; // bug in the element 0x0020,0x0032
- } else {
- return zImPos;
- }
- }
- std::string StrSliceLocation = GetEntryByNumber(0x0020,0x1041);// for *very* old ACR-NEMA images
- if (StrSliceLocation != GDCM_UNFOUND) {
- if( sscanf( StrSliceLocation.c_str(), "%f", &zImPos) !=1) {
- dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Slice Location (0020,1041)");
- return 0.; // bug in the element 0x0020,0x1041
- } else {
- return zImPos;
- }
- }
- dbg.Verbose(0, "gdcmHeader::GetZImagePosition: unfound Slice Location (0020,1041)");
- std::string StrLocation = GetEntryByNumber(0x0020,0x0050);
- if (StrLocation != GDCM_UNFOUND) {
- if( sscanf( StrLocation.c_str(), "%f", &zImPos) !=1) {
- dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Location (0020,0050)");
- return 0.; // bug in the element 0x0020,0x0050
- } else {
- return zImPos;
- }
- }
- dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Location (0020,0050)");
- return 0.; // Hopeless
-}
-
-/**
- * \brief gets the info from 0020,0013 : Image Number
- * \ else 0.
- * @return image number
- */
-int gdcmHeaderHelper::GetImageNumber() {
- // The function i atoi() takes the address of an area of memory as
- // parameter and converts the string stored at that location to an integer
- // using the external decimal to internal binary conversion rules. This may
- // be preferable to sscanf() since atoi() is a much smaller, simpler and
- // faster function. sscanf() can do all possible conversions whereas
- // atoi() can only do single decimal integer conversions.
- std::string StrImNumber = GetEntryByNumber(0x0020,0x0013); //0020 0013 IS REL Image Number
- if (StrImNumber != GDCM_UNFOUND) {
- return atoi( StrImNumber.c_str() );
- }
- return 0; //Hopeless
-}
-
-/**
- * \brief gets the info from 0008,0060 : Modality
- * @return Modality Type
- */
-ModalityType gdcmHeaderHelper::GetModality(void) {
- // 0008 0060 CS ID Modality
- std::string StrModality = GetEntryByNumber(0x0008,0x0060);
- if (StrModality != GDCM_UNFOUND) {
- if ( StrModality.find("AU") < StrModality.length()) return AU;
- else if ( StrModality.find("AS") < StrModality.length()) return AS;
- else if ( StrModality.find("BI") < StrModality.length()) return BI;
- else if ( StrModality.find("CF") < StrModality.length()) return CF;
- else if ( StrModality.find("CP") < StrModality.length()) return CP;
- else if ( StrModality.find("CR") < StrModality.length()) return CR;
- else if ( StrModality.find("CT") < StrModality.length()) return CT;
- else if ( StrModality.find("CS") < StrModality.length()) return CS;
- else if ( StrModality.find("DD") < StrModality.length()) return DD;
- else if ( StrModality.find("DF") < StrModality.length()) return DF;
- else if ( StrModality.find("DG") < StrModality.length()) return DG;
- else if ( StrModality.find("DM") < StrModality.length()) return DM;
- else if ( StrModality.find("DS") < StrModality.length()) return DS;
- else if ( StrModality.find("DX") < StrModality.length()) return DX;
- else if ( StrModality.find("ECG") < StrModality.length()) return ECG;
- else if ( StrModality.find("EPS") < StrModality.length()) return EPS;
- else if ( StrModality.find("FA") < StrModality.length()) return FA;
- else if ( StrModality.find("FS") < StrModality.length()) return FS;
- else if ( StrModality.find("HC") < StrModality.length()) return HC;
- else if ( StrModality.find("HD") < StrModality.length()) return HD;
- else if ( StrModality.find("LP") < StrModality.length()) return LP;
- else if ( StrModality.find("LS") < StrModality.length()) return LS;
- else if ( StrModality.find("MA") < StrModality.length()) return MA;
- else if ( StrModality.find("MR") < StrModality.length()) return MR;
- else if ( StrModality.find("NM") < StrModality.length()) return NM;
- else if ( StrModality.find("OT") < StrModality.length()) return OT;
- else if ( StrModality.find("PT") < StrModality.length()) return PT;
- else if ( StrModality.find("RF") < StrModality.length()) return RF;
- else if ( StrModality.find("RG") < StrModality.length()) return RG;
- else if ( StrModality.find("RTDOSE") < StrModality.length()) return RTDOSE;
- else if ( StrModality.find("RTIMAGE") < StrModality.length()) return RTIMAGE;
- else if ( StrModality.find("RTPLAN") < StrModality.length()) return RTPLAN;
- else if ( StrModality.find("RTSTRUCT")< StrModality.length()) return RTSTRUCT;
- else if ( StrModality.find("SM") < StrModality.length()) return SM;
- else if ( StrModality.find("ST") < StrModality.length()) return ST;
- else if ( StrModality.find("TG") < StrModality.length()) return TG;
- else if ( StrModality.find("US") < StrModality.length()) return US;
- else if ( StrModality.find("VF") < StrModality.length()) return VF;
- else if ( StrModality.find("XA") < StrModality.length()) return XA;
- else if ( StrModality.find("XC") < StrModality.length()) return XC;
-
- else
- {
- /// \todo throw error return value ???
- /// specified <> unknow in our database
- return Unknow;
- }
- }
- return Unknow;
-}
-
-/**
- * \brief gets the info from 0020,0037 : Image Orientation Patient
- * @param iop adress of the (6)float aray to receive values
- * @return cosines of image orientation patient
- */
-void gdcmHeaderHelper::GetImageOrientationPatient( float* iop ) {
-
- //iop is supposed to be float[6]
- iop[0] = iop[1] = iop[2] = iop[3] = iop[4] = iop[5] = 0;
-
- // 0020 0037 DS REL Image Orientation (Patient)
- std::string StrImOriPat = GetEntryByNumber(0x0020,0x0037);
- if (StrImOriPat != GDCM_UNFOUND) {
- if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f",
- &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) {
- dbg.Verbose(0, "gdcmHeader::GetImageOrientationPatient: wrong Image Orientation Patient (0020,0037)");
- return ; // bug in the element 0x0020,0x0037
- }
- else
- return ;
- }
-
- //For ACR-NEMA
- // 0020 0035 DS REL Image Orientation (RET)
- StrImOriPat = GetEntryByNumber(0x0020,0x0035);
- if (StrImOriPat != GDCM_UNFOUND) {
- if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f",
- &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) {
- dbg.Verbose(0, "gdcmHeader::GetImageOrientationPatient: wrong Image Orientation Patient (0020,0035)");
- return ; // bug in the element 0x0020,0x0035
- }
- else
- return ;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Protected
-
-//-----------------------------------------------------------------------------
-// Private
-
-//-----------------------------------------------------------------------------
-
-
-
//-----------------------------------------------------------------------------
// Constructor / Destructor
-gdcmSerieHeaderHelper::~gdcmSerieHeaderHelper(){
+gdcmSerieHeader::~gdcmSerieHeader(){
/// \todo
- for (std::list<gdcmHeaderHelper*>::iterator it = CoherentGdcmFileList.begin();
+ for (std::list<gdcmHeader*>::iterator it = CoherentGdcmFileList.begin();
it != CoherentGdcmFileList.end(); it++)
{
delete *it;
* \brief add a gdcmFile to the list based on file name
* @param filename Name of the file to deal with
*/
-void gdcmSerieHeaderHelper::AddFileName(std::string filename) {
- gdcmHeaderHelper *GdcmFile = new gdcmHeaderHelper( filename.c_str() );
+void gdcmSerieHeader::AddFileName(std::string filename) {
+ gdcmHeader *GdcmFile = new gdcmHeader( filename );
this->CoherentGdcmFileList.push_back( GdcmFile );
}
/**
* \brief add a gdcmFile to the list
- * @param file gdcmHeaderHelper to add
+ * @param file gdcmHeader to add
*/
-void gdcmSerieHeaderHelper::AddGdcmFile(gdcmHeaderHelper *file){
+void gdcmSerieHeader::AddGdcmFile(gdcmHeader *file){
this->CoherentGdcmFileList.push_back( file );
}
* \brief Sets the Directory
* @param dir Name of the directory to deal with
*/
-void gdcmSerieHeaderHelper::SetDirectory(std::string dir){
+void gdcmSerieHeader::SetDirectory(std::string dir){
gdcmDirList filenames_list(dir); //OS specific
for(gdcmDirList::iterator it = filenames_list.begin();
it !=filenames_list.end(); it++)
{
- gdcmHeaderHelper *file = new gdcmHeaderHelper( it->c_str() );
+ gdcmHeader *file = new gdcmHeader( it->c_str() );
this->CoherentGdcmFileList.push_back( file );
}
}
* But as I don't know how to do it, I leave it this way
* BTW, this is also a Strategy, I don't know this is the best approach :)
*/
-void gdcmSerieHeaderHelper::OrderGdcmFileList(){
+void gdcmSerieHeader::OrderGdcmFileList(){
if( ImagePositionPatientOrdering() ) {
return ;
}
* \brief Gets the *coherent* File List
* @return the *coherent* File List
*/
-std::list<gdcmHeaderHelper*> &gdcmSerieHeaderHelper::GetGdcmFileList() {
+std::list<gdcmHeader*> &gdcmSerieHeader::GetGdcmFileList() {
return CoherentGdcmFileList;
}
//-----------------------------------------------------------------------------
// Private
/**
- * \ingroup gdcmHeaderHelper
+ * \ingroup gdcmHeader
* \brief sorts the images, according to their Patient Position
* We may order, considering :
* -# Image Number
* -# More to come :)
* @return false only if the header is bugged !
*/
-bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering()
+bool gdcmSerieHeader::ImagePositionPatientOrdering()
//based on Jolinda's algorithm
{
//iop is calculated based on the file file
std::vector<float> distlist;
//!\todo rewrite this for loop.
- for (std::list<gdcmHeaderHelper*>::iterator it = CoherentGdcmFileList.begin();
+ for (std::list<gdcmHeader*>::iterator it = CoherentGdcmFileList.begin();
it != CoherentGdcmFileList.end(); it++)
{
if(first) {
//Then I order the slices according to the value "dist". Finally, once
//I've read in all the slices, I calculate the z-spacing as the difference
//between the "dist" values for the first two slices.
- std::vector<gdcmHeaderHelper*> CoherentGdcmFileVector(n);
+ std::vector<gdcmHeader*> CoherentGdcmFileVector(n);
//CoherentGdcmFileVector.reserve( n );
CoherentGdcmFileVector.resize( n );
//assert( CoherentGdcmFileVector.capacity() >= n );
n = 0;
//VC++ don't understand what scope is !! it -> it2
- for (std::list<gdcmHeaderHelper*>::iterator it2 = CoherentGdcmFileList.begin();
+ for (std::list<gdcmHeader*>::iterator it2 = CoherentGdcmFileList.begin();
it2 != CoherentGdcmFileList.end(); it2++, n++)
{
//2*n sort algo !!
CoherentGdcmFileList.clear(); //this doesn't delete list's element, node only
//VC++ don't understand what scope is !! it -> it3
- for (std::vector<gdcmHeaderHelper*>::iterator it3 = CoherentGdcmFileVector.begin();
+ for (std::vector<gdcmHeader*>::iterator it3 = CoherentGdcmFileVector.begin();
it3 != CoherentGdcmFileVector.end(); it3++)
{
CoherentGdcmFileList.push_back( *it3 );
}
/**
- * \ingroup gdcmHeaderHelper
+ * \ingroup gdcmHeader
* \brief sorts the images, according to their Image Number
* @return false only if the header is bugged !
*/
-bool gdcmSerieHeaderHelper::ImageNumberOrdering() {
+bool gdcmSerieHeader::ImageNumberOrdering() {
int min, max, pos;
int n = 0;//CoherentGdcmFileList.size() is a O(N) operation !!
unsigned char *partition;
- std::list<gdcmHeaderHelper*>::iterator it = CoherentGdcmFileList.begin();
+ std::list<gdcmHeader*>::iterator it = CoherentGdcmFileList.begin();
min = max = (*it)->GetImageNumber();
for (; it != CoherentGdcmFileList.end(); it++, n++)
partition = new unsigned char[n];
memset(partition, 0, n);
- std::vector<gdcmHeaderHelper*> CoherentGdcmFileVector(n);
+ std::vector<gdcmHeader*> CoherentGdcmFileVector(n);
//VC++ don't understand what scope is !! it -> it2
- for (std::list<gdcmHeaderHelper*>::iterator it2 = CoherentGdcmFileList.begin();
+ for (std::list<gdcmHeader*>::iterator it2 = CoherentGdcmFileList.begin();
it2 != CoherentGdcmFileList.end(); it2++)
{
pos = (*it2)->GetImageNumber();
//VC++ don't understand what scope is !! it -> it3
CoherentGdcmFileList.clear(); //this doesn't delete list's element, node only
- for (std::vector<gdcmHeaderHelper*>::iterator it3 = CoherentGdcmFileVector.begin();
+ for (std::vector<gdcmHeader*>::iterator it3 = CoherentGdcmFileVector.begin();
it3 != CoherentGdcmFileVector.end(); it3++)
{
CoherentGdcmFileList.push_back( *it3 );
/**
- * \ingroup gdcmHeaderHelper
+ * \ingroup gdcmHeader
* \brief sorts the images, according to their File Name
* @return false only if the header is bugged !
*/
- bool gdcmSerieHeaderHelper::FileNameOrdering() {
+ bool gdcmSerieHeader::FileNameOrdering() {
//using the sort
//sort(CoherentGdcmFileList.begin(), CoherentGdcmFileList.end());
return true;
Program: gdcm
Module: $RCSfile: gdcmHeaderHelper.h,v $
Language: C++
- Date: $Date: 2004/06/20 18:08:48 $
- Version: $Revision: 1.16 $
+ Date: $Date: 2004/06/21 04:18:26 $
+ Version: $Revision: 1.17 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
#include "gdcmHeader.h"
//-----------------------------------------------------------------------------
-// Dicom Part 3.3 Compliant
-enum ModalityType {
- Unknow,
- AU, // Voice Audio
- AS, // Angioscopy
- BI, // Biomagnetic Imaging
- CF, // Cinefluorography
- CP, // Culposcopy
- CR, // Computed Radiography
- CS, // Cystoscopy
- CT, // Computed Tomography
- DD, // Duplex Dopler
- DF, // Digital Fluoroscopy
- DG, // Diaphanography
- DM, // Digital Microscopy
- DS, // Digital Substraction Angiography
- DX, // Digital Radiography
- ECG, // Echocardiography
- EPS, // Basic Cardiac EP
- ES, // Endoscopy
- FA, // Fluorescein Angiography
- FS, // Fundoscopy
- HC, // Hard Copy
- HD, // Hemodynamic
- LP, // Laparoscopy
- LS, // Laser Surface Scan
- MA, // Magnetic Resonance Angiography
- MR, // Magnetic Resonance
- NM, // Nuclear Medicine
- OT, // Other
- PT, // Positron Emission Tomography
- RF, // Radio Fluoroscopy
- RG, // Radiographic Imaging
- RTDOSE, // Radiotherapy Dose
- RTIMAGE, // Radiotherapy Image
- RTPLAN, // Radiotherapy Plan
- RTSTRUCT, // Radiotherapy Structure Set
- SM, // Microscopic Imaging
- ST, // Single-photon Emission Computed Tomography
- TG, // Thermography
- US, // Ultrasound
- VF, // Videofluorography
- XA, // X-Ray Angiography
- XC // Photographic Imaging
-};
-
-//-----------------------------------------------------------------------------
-/*
- * \defgroup gdcmHeaderHelper
- * \brief
- *
- * - This class is meant to *interpret* data given from gdcmHeader
- * - That is to say :
- * - it will help other dev to link against there lib
- * - return value instead of string
- * - will be able to search for data at some other place
- * - return *default value* which is not a gdcmHeader goal
- * - ...
- */
-class GDCM_EXPORT gdcmHeaderHelper : public gdcmHeader {
-public:
- gdcmHeaderHelper();
- gdcmHeaderHelper(const char *filename,
- bool exception_on_error = false,
- bool enable_sequences = false,
- bool ignore_shadow = false);
-
- int GetPixelSize();
- std::string GetPixelType();
-
- float GetXSpacing();
- float GetYSpacing();
- float GetZSpacing();
-
- // Usefull for rescaling graylevel:
- float GetRescaleIntercept();
- float GetRescaleSlope();
- int GetNumberOfScalarComponents();
- int GetNumberOfScalarComponentsRaw();
-
- std::string GetStudyUID();
- std::string GetSeriesUID();
- std::string GetClassUID();
- std::string GetInstanceUID();
-
- /**
- * change GetXImagePosition -> GetXOrigin in order not to confuse reader
- * -# GetXOrigin can return default value (=0) if it was not ImagePosition
- * -# Image Position is different in dicomV3 <> ACR NEMA -> better use generic
- * name
- */
- float GetXOrigin();
- float GetYOrigin();
- float GetZOrigin();
-
- int GetImageNumber();
- ModalityType GetModality();
-
- void GetImageOrientationPatient( float* iop );
+class GDCM_EXPORT gdcmHeaderHelper : public gdcmHeader
+{
};
-//-----------------------------------------------------------------------------
/*
- * \defgroup gdcmSerieHeaderHelper
+ * \defgroup gdcmSerieHeader
* \brief
*
* - This class should be used for a stack of 2D dicom images.
* - For a multiframe dicom image better use directly gdcmHeaderHelper
*/
-class GDCM_EXPORT gdcmSerieHeaderHelper {
+class GDCM_EXPORT gdcmSerieHeader {
public:
- gdcmSerieHeaderHelper() {};
- ~gdcmSerieHeaderHelper();
+ gdcmSerieHeader() {};
+ ~gdcmSerieHeader();
void AddFileName(std::string filename); //should return bool or throw error ?
- void AddGdcmFile(gdcmHeaderHelper *file);
+ void AddGdcmFile(gdcmHeader *file);
void SetDirectory(std::string dir);
void OrderGdcmFileList();
- inline gdcmHeaderHelper *GetGdcmHeader()
+ inline gdcmHeader *GetGdcmHeader()
{
//Assume all element in the list have the same global infos
return CoherentGdcmFileList.front();
}
- std::list<gdcmHeaderHelper*>& GetGdcmFileList();
+ std::list<gdcmHeader*>& GetGdcmFileList();
private:
bool ImagePositionPatientOrdering();
bool ImageNumberOrdering();
bool FileNameOrdering();
- std::list<gdcmHeaderHelper*> CoherentGdcmFileList;
+ std::list<gdcmHeader*> CoherentGdcmFileList;
};
//-----------------------------------------------------------------------------
{
// The memory size for a full stack of images of course depends
// on the number of planes and the size of each image:
- size_t StackNumPixels = this->NumColumns * this->NumLines
- * this->TotalNumberOfPlanes * this->NumComponents;
- size_t stack_size = StackNumPixels * this->PixelSize;
+ //size_t StackNumPixels = this->NumColumns * this->NumLines
+ // * this->TotalNumberOfPlanes * this->NumComponents;
+ //size_t stack_size = StackNumPixels * this->PixelSize; //not used
// Allocate pixel data space itself.
// Variables for the UpdateProgress. We shall use 50 steps to signify
fclose(fp);
// Stage 1.2: check for Gdcm parsability
- gdcmHeaderHelper GdcmHeader(FileName->c_str(), false, true);
+ gdcmHeader GdcmHeader(FileName->c_str(), false, true);
// true : for enableSequences
if (!GdcmHeader.IsReadable())
{
{
this->ImageViewer = NULL;
}
- virtual void Execute(vtkObject *wdg, unsigned long event, void* calldata)
+ virtual void Execute(vtkObject *, unsigned long event, void* )
{
if ( this->ImageViewer )
{
}
viewer->SetupInteractor (iren);
- vtkFloatingPointType *range = reader->GetOutput()->GetScalarRange();
+ //vtkFloatingPointType *range = reader->GetOutput()->GetScalarRange();
//viewer->SetColorWindow (range[1] - range[0]);
//viewer->SetColorLevel (0.5 * (range[1] + range[0]));