X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmHeaderHelper.cxx;h=e2492dc8229ef93158a8bcca03ea6a897eee6e74;hb=05f9a9731209a5c98895a57c6abca609f8e9b312;hp=513f830f02647dd9aeed29fa85c0a4f517451b18;hpb=4f2836463d980c78298e905beb79b87018ef9900;p=gdcm.git diff --git a/src/gdcmHeaderHelper.cxx b/src/gdcmHeaderHelper.cxx index 513f830f..e2492dc8 100644 --- a/src/gdcmHeaderHelper.cxx +++ b/src/gdcmHeaderHelper.cxx @@ -1,580 +1,34 @@ -// gdcmHeaderHelper.cxx -//----------------------------------------------------------------------------- +/*========================================================================= + + Program: gdcm + Module: $RCSfile: gdcmHeaderHelper.cxx,v $ + Language: C++ + 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 + http://www.creatis.insa-lyon.fr/Public/Gdcm/License.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + #include "gdcmHeaderHelper.h" +#include "gdcmDirList.h" -#include "gdcmUtil.h" //for debug +#include "gdcmDebug.h" #include #include +#include -#ifdef _MSC_VER - #include - - int GetDir(std::string dPath, std::list &filenames) - { - //For now dPath should have an ending "\" - WIN32_FIND_DATA FileData; - HANDLE hFile; - hFile = FindFirstFile((dPath+"*").c_str(), &FileData); - if ( hFile == INVALID_HANDLE_VALUE ) - { - //No files ! - return false; - } - - if( strncmp(FileData.cFileName, ".", 1) != 0 ) - filenames.push_back( dPath+FileData.cFileName ); - while( FindNextFile(hFile, &FileData ) != 0) - { - if( strncmp(FileData.cFileName, ".", 1) != 0 ) - filenames.push_back( dPath+FileData.cFileName ); - } - return true; - } - -#else - #include - - int GetDir(std::string dPath, std::list &filenames) - { - DIR *dir = opendir( dPath.c_str() ); - struct dirent *entry; - while((entry = readdir(dir)) != NULL) - { - // if( strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0) - if( strncmp(entry->d_name, ".", 1) != 0 ) - { - filenames.push_back( dPath + "/" + entry->d_name ); - } - } - closedir(dir); - return true; - } - -#endif - -//----------------------------------------------------------------------------- -// gdcmHeaderHelper //----------------------------------------------------------------------------- // Constructor / Destructor -/** - * \ingroup gdcmHeaderHelper - * \brief cstor - */ -gdcmHeaderHelper::gdcmHeaderHelper() : gdcmHeader( ) -{ -} - -/** - * \ingroup gdcmHeaderHelper - * \brief cstor - */ -gdcmHeaderHelper::gdcmHeaderHelper(const char *InFilename, - bool exception_on_error) : gdcmHeader( InFilename , exception_on_error) -{ -} - -//----------------------------------------------------------------------------- -// Print - -//----------------------------------------------------------------------------- -// Public -/** - * \ingroup gdcmHeaderHelper - * \brief Return 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 - * \ DOUBLE images are coded as 64 bits - * \ (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. - * @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.; - } - if( sscanf( StrSpacing.c_str(), "%f\\%f", &yspacing, &xspacing) != 2) - return 0.; - 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. - * @return Y dimension of a pixel - */ -float gdcmHeaderHelper::GetYSpacing() { - float xspacing, yspacing; - std::string StrSpacing = GetEntryByNumber(0x0028,0x0030); - - if (StrSpacing == GDCM_UNFOUND) { - dbg.Verbose(0, "gdcmHeader::GetYSpacing: unfound Pixel Spacing (0028,0030)"); - return 1.; - } - if( sscanf( StrSpacing.c_str(), "%f\\%f", &yspacing, &xspacing) != 2) - return 0.; - 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 yspacing; -} - -/** - *\ingroup gdcmHeaderHelper - *\brief gets the info from 0018,0088 : Space Between Slices - *\ else from 0018,0050 : Slice Thickness - *\ else 1. - * @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()); - } -} - -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; -} - -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 whan - * \ 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(); -} - -std::string gdcmHeaderHelper::GetStudyUID(){ - return GetEntryByNumber(0x0020,0x000d); //0020 000d UI REL Study Instance UID -} - -std::string gdcmHeaderHelper::GetSeriesUID(){ - return GetEntryByNumber(0x0020,0x000e); //0020 000e UI REL Series Instance UID -} - -std::string gdcmHeaderHelper::GetClassUID(){ - return GetEntryByNumber(0x0008,0x0016); //0008 0016 UI ID SOP Class UID -} - -std::string gdcmHeaderHelper::GetInstanceUID(){ - return GetEntryByNumber(0x0008,0x0018); //0008 0018 UI ID SOP Instance UID -} - -// 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? -/** - * \ingroup gdcmHeaderHelper - * \brief gets the info from 0020,0032 : Image Position Patient - *\ else from 0020,0030 : Image Position (RET) - *\ else 0. - * @return up-left image corner 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)"); - // 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; -} - -/** - * \ingroup gdcmHeaderHelper - * \brief gets the info from 0020,0032 : Image Position Patient - * \ else from 0020,0030 : Image Position (RET) - * \ else 0. - * @return up-left image corner 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)"); - // 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; -} - -/** - * \ingroup gdcmHeaderHelper - * \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 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 -} - -/** - * \ingroup gdcmHeaderHelper - * \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 -} - -/** - * \ingroup gdcmHeaderHelper - * \brief gets the info from 0008,0060 : Modality - * @return ModalityType - */ -ModalityType gdcmHeaderHelper::GetModality(void) { - std::string StrModality = GetEntryByNumber(0x0008,0x0060); //0008 0060 CS ID Modality - 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 - { - //throw error return value ??? - // specified <> unknow in our database - return Unknow; - } - } - return Unknow; -} - -/** - * \ingroup gdcmHeaderHelper - * \brief gets the info from 0020,0037 : Image Orientation Patient - * @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; - - std::string StrImOriPat = GetEntryByNumber(0x0020,0x0037); // 0020 0037 DS REL Image Orientation (Patient) - 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 - StrImOriPat = GetEntryByNumber(0x0020,0x0035); //0020 0035 DS REL Image Orientation (RET) - 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 - -//----------------------------------------------------------------------------- - - - -//----------------------------------------------------------------------------- -// gdcmSerieHeaderHelper -//----------------------------------------------------------------------------- -// Constructor / Destructor -gdcmSerieHeaderHelper::~gdcmSerieHeaderHelper(){ - //! \todo - for (std::list::iterator it = CoherentGdcmFileList.begin(); +gdcmSerieHeader::~gdcmSerieHeader(){ + /// \todo + for (std::list::iterator it = CoherentGdcmFileList.begin(); it != CoherentGdcmFileList.end(); it++) { delete *it; @@ -588,57 +42,59 @@ gdcmSerieHeaderHelper::~gdcmSerieHeaderHelper(){ //----------------------------------------------------------------------------- // Public /** - * \ingroup gdcmHeaderHelper * \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 ); } /** - * \ingroup gdcmHeaderHelper * \brief add a gdcmFile to the list + * @param file gdcmHeader to add */ -void gdcmSerieHeaderHelper::AddGdcmFile(gdcmHeaderHelper *file){ +void gdcmSerieHeader::AddGdcmFile(gdcmHeader *file){ this->CoherentGdcmFileList.push_back( file ); } /** - * \ingroup gdcmHeaderHelper - * \brief \todo + * \brief Sets the Directory + * @param dir Name of the directory to deal with */ -void gdcmSerieHeaderHelper::SetDirectory(std::string dir){ - std::list filenames_list; - GetDir(dir, filenames_list); //OS specific +void gdcmSerieHeader::SetDirectory(std::string dir){ + gdcmDirList filenames_list(dir); //OS specific - for(std::list::iterator it = filenames_list.begin(); it != - filenames_list.end(); it++) + 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 ); } } -//This could be implemented in a 'Strategy Pattern' approach -//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(){ - if( ImagePositionPatientOrdering() ) - { +/** + * \brief Sorts the File List + * \warning This could be implemented in a 'Strategy Pattern' approach + * 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 gdcmSerieHeader::OrderGdcmFileList(){ + if( ImagePositionPatientOrdering() ) { return ; } - else if( ImageNumberOrdering() ) - { + else if( ImageNumberOrdering() ) { return ; - } - else - { + } else { FileNameOrdering(); } } -std::list &gdcmSerieHeaderHelper::GetGdcmFileList() { +/** + * \brief Gets the *coherent* File List + * @return the *coherent* File List +*/ +std::list &gdcmSerieHeader::GetGdcmFileList() { return CoherentGdcmFileList; } @@ -648,14 +104,15 @@ std::list &gdcmSerieHeaderHelper::GetGdcmFileList() { //----------------------------------------------------------------------------- // Private /** - * \ingroup gdcmHeaderHelper - * \brief + * \ingroup gdcmHeader + * \brief sorts the images, according to their Patient Position * We may order, considering : * -# Image Number * -# Image Position Patient * -# 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 @@ -669,7 +126,7 @@ bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering() std::vector distlist; //!\todo rewrite this for loop. - for (std::list::iterator it = CoherentGdcmFileList.begin(); + for (std::list::iterator it = CoherentGdcmFileList.begin(); it != CoherentGdcmFileList.end(); it++) { if(first) { @@ -715,7 +172,6 @@ bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering() delete[] cosines; return false; } - distlist.push_back( dist ); @@ -728,7 +184,7 @@ bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering() //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 CoherentGdcmFileVector(n); + std::vector CoherentGdcmFileVector(n); //CoherentGdcmFileVector.reserve( n ); CoherentGdcmFileVector.resize( n ); //assert( CoherentGdcmFileVector.capacity() >= n ); @@ -738,7 +194,7 @@ bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering() n = 0; //VC++ don't understand what scope is !! it -> it2 - for (std::list::iterator it2 = CoherentGdcmFileList.begin(); + for (std::list::iterator it2 = CoherentGdcmFileList.begin(); it2 != CoherentGdcmFileList.end(); it2++, n++) { //2*n sort algo !! @@ -751,7 +207,7 @@ bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering() CoherentGdcmFileList.clear(); //this doesn't delete list's element, node only //VC++ don't understand what scope is !! it -> it3 - for (std::vector::iterator it3 = CoherentGdcmFileVector.begin(); + for (std::vector::iterator it3 = CoherentGdcmFileVector.begin(); it3 != CoherentGdcmFileVector.end(); it3++) { CoherentGdcmFileList.push_back( *it3 ); @@ -764,14 +220,18 @@ bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering() return true; } -//Based on Image Number +/** + * \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(); //O(N) operation !! + int n = 0;//CoherentGdcmFileList.size() is a O(N) operation !! unsigned char *partition; - std::list::iterator it = CoherentGdcmFileList.begin(); + std::list::iterator it = CoherentGdcmFileList.begin(); min = max = (*it)->GetImageNumber(); for (; it != CoherentGdcmFileList.end(); it++, n++) @@ -786,10 +246,10 @@ bool gdcmSerieHeaderHelper::ImageNumberOrdering() { partition = new unsigned char[n]; memset(partition, 0, n); - std::vector CoherentGdcmFileVector(n); + std::vector CoherentGdcmFileVector(n); //VC++ don't understand what scope is !! it -> it2 - for (std::list::iterator it2 = CoherentGdcmFileList.begin(); + for (std::list::iterator it2 = CoherentGdcmFileList.begin(); it2 != CoherentGdcmFileList.end(); it2++) { pos = (*it2)->GetImageNumber(); @@ -805,7 +265,7 @@ bool gdcmSerieHeaderHelper::ImageNumberOrdering() { //VC++ don't understand what scope is !! it -> it3 CoherentGdcmFileList.clear(); //this doesn't delete list's element, node only - for (std::vector::iterator it3 = CoherentGdcmFileVector.begin(); + for (std::vector::iterator it3 = CoherentGdcmFileVector.begin(); it3 != CoherentGdcmFileVector.end(); it3++) { CoherentGdcmFileList.push_back( *it3 ); @@ -816,7 +276,13 @@ bool gdcmSerieHeaderHelper::ImageNumberOrdering() { return (mult!=0); } -bool gdcmSerieHeaderHelper::FileNameOrdering() { + +/** + * \ingroup gdcmHeader + * \brief sorts the images, according to their File Name + * @return false only if the header is bugged ! + */ + bool gdcmSerieHeader::FileNameOrdering() { //using the sort //sort(CoherentGdcmFileList.begin(), CoherentGdcmFileList.end()); return true;