X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmHeaderHelper.cxx;h=340dc812d577533db891d4e0119afbc594d04f14;hb=1d69b92978803204089d270599133917d944c651;hp=cb32855dc1c67997fe0a28ecec98fe51e4f2510a;hpb=5f5eda4e34ec5f7975adcb1c3fbc4064f918db98;p=gdcm.git diff --git a/src/gdcmHeaderHelper.cxx b/src/gdcmHeaderHelper.cxx index cb32855d..340dc812 100644 --- a/src/gdcmHeaderHelper.cxx +++ b/src/gdcmHeaderHelper.cxx @@ -1,709 +1,314 @@ -// $Header: /cvs/public/gdcm/src/Attic/gdcmHeaderHelper.cxx,v 1.2 2003/09/09 08:46:32 malaterre Exp $ - -//This is needed when compiling in debug mode -#ifdef _MSC_VER -#pragma warning ( disable : 4800 ) -// 'identifier' : class 'type' needs to have dll-interface to be used by -// clients of class 'type2' -#pragma warning ( disable : 4251 ) -// 'identifier' : identifier was truncated to 'number' characters in the -// debug information -#pragma warning ( disable : 4786 ) -#endif //_MSC_VER +/*========================================================================= + + Program: gdcm + Module: $RCSfile: gdcmHeaderHelper.cxx,v $ + Language: C++ + Date: $Date: 2004/10/12 04:35:46 $ + Version: $Revision: 1.43 $ + + 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.html 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 "gdcmUtil.h" //for debug +#include "gdcmDirList.h" +#include "gdcmDebug.h" + #include #include -#include //for bzero -using namespace std; - -//directory manipulation (os indep). -//cygwin ???? -> _WIN32 ?? -#ifdef _MSC_VER -#include -int GetDir(string dPath, list &filenames) +#include + +namespace gdcm { - WIN32_FIND_DATA FileData; - HANDLE hFile; - hFile = FindFirstFile(dPath.c_str(), &FileData); - if ( hFile == INVALID_HANDLE_VALUE ) - { - //No files ! - return false; - } - - filenames.push_back( FileData.cFileName ); - while( FindNextFile(hFile, &FileData ) != 0) - { - filenames.push_back( FileData.cFileName ); - } - return true; -} -#else -#include +typedef std::vector GdcmHeaderVector; +//----------------------------------------------------------------------------- +// Constructor / Destructor +SerieHeader::SerieHeader() +{ + CoherentGdcmFileList.clear(); +} -int GetDir(string dPath, list &filenames) +SerieHeader::~SerieHeader() { - 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 ) + /// \todo + for ( GdcmHeaderList::const_iterator it = CoherentGdcmFileList.begin(); + it != CoherentGdcmFileList.end(); ++it) { - filenames.push_back( dPath + "/" + entry->d_name ); + delete *it; } - } - closedir(dir); - return true; + CoherentGdcmFileList.clear(); } -#endif +//----------------------------------------------------------------------------- +// Print -//---------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// Public /** - * \ingroup gdcmHeaderHelper - * \brief cstor + * \brief add a File to the list based on file name + * @param filename Name of the file to deal with */ -gdcmHeaderHelper::gdcmHeaderHelper() : gdcmHeader( ) +void SerieHeader::AddFileName(std::string const & filename) { + Header *header = new Header( filename ); + CoherentGdcmFileList.push_back( header ); } -//---------------------------------------------------------------------------- + /** - * \ingroup gdcmHeaderHelper - * \brief cstor + * \brief add a File to the list + * @param file Header to add */ -gdcmHeaderHelper::gdcmHeaderHelper(const char *InFilename, - bool exception_on_error) : gdcmHeader( InFilename , exception_on_error) +void SerieHeader::AddGdcmFile(Header *file) { + CoherentGdcmFileList.push_back( file ); } -//---------------------------------------------------------------------------- -/** - * \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() { - string PixelType = GetPixelType(); - if (PixelType == "8U" || PixelType == "8S") - return 1; - if (PixelType == "16U" || PixelType == "16S") - return 2; - if (PixelType == "32U" || PixelType == "32S") - return 4; - 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, - * \warning 12 bit images appear as 16 bit. - * @return - */ -string gdcmHeaderHelper::GetPixelType() { - string BitsAlloc; - BitsAlloc = GetElValByName("Bits Allocated"); - if (BitsAlloc == "gdcm::Unfound") { - dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated"); - BitsAlloc = string("16"); - } - if (BitsAlloc == "12") - BitsAlloc = string("16"); - - string Signed; - Signed = GetElValByName("Pixel Representation"); - if (Signed == "gdcm::Unfound") { - dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation"); - BitsAlloc = string("0"); - } - if (Signed == "0") - Signed = string("U"); - else - Signed = 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; - string StrSpacing = GetPubElValByNumber(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", &xspacing, &yspacing) != 2) - return 0.; - //else - 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; - string StrSpacing = GetPubElValByNumber(0x0028,0x0030); + * \brief Sets the Directory + * @param dir Name of the directory to deal with + */ +void SerieHeader::SetDirectory(std::string const & dir) +{ + DirList filenames_list(dir); //OS specific - if (StrSpacing == "gdcm::Unfound") { - dbg.Verbose(0, "gdcmHeader::GetYSpacing: unfound Pixel Spacing (0028,0030)"); - return 1.; - } - if( sscanf( StrSpacing.c_str(), "%f\\%f", &xspacing, &yspacing) != 2) - return 0.; - if (yspacing == 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", &xspacing, &yspacing); - } - 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() { - // TODO : translate into English - // 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 - - string StrSpacingBSlices = GetPubElValByNumber(0x0018,0x0088); - - if (StrSpacingBSlices == "gdcm::Unfound") { - dbg.Verbose(0, "gdcmHeader::GetZSpacing: unfound StrSpacingBSlices"); - string StrSliceThickness = GetPubElValByNumber(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()); + for( DirList::const_iterator it = filenames_list.begin(); + it != filenames_list.end(); ++it) + { + //use string and not const char*: + Header *header = new Header( *it ); + CoherentGdcmFileList.push_back( header ); } } -//---------------------------------------------------------------------------- -// -// 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; - string StrImPos = GetPubElValByNumber(0x0020,0x0032); - - if (StrImPos == "gdcm::Unfound") { - dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position Patient (0020,0032)"); - StrImPos = GetPubElValByNumber(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; - string StrImPos = GetPubElValByNumber(0x0020,0x0032); - - if (StrImPos == "gdcm::Unfound") { - dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position Patient (0020,0032)"); - StrImPos = GetPubElValByNumber(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; - string StrImPos = GetPubElValByNumber(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 = GetPubElValByNumber(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; - } - } - string StrSliceLocation = GetPubElValByNumber(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)"); - string StrLocation = GetPubElValByNumber(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. - string StrImNumber = GetPubElValByNumber(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) { - string StrModality = GetPubElValByNumber(0x0008,0x0060); //0008 0060 CS ID Modality - if (StrModality != "gdcm::Unfound") { - if ( StrModality.find("CR") < StrModality.length()) - { - return CR; - } - else if ( StrModality.find("CT") < StrModality.length() ) - { - return CT; - } - 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("US") < StrModality.length()) - { - return US; - } - else if ( StrModality.find("XA") < StrModality.length()) - { - return XA; - } - else - { - //throw error return value ??? - // specified <> unknow in our database - return Unknow; - } - } - return Unknow; -} - -//---------------------------------------------------------------------------- -string gdcmHeaderHelper::GetStudyUID() -{ - return GetPubElValByNumber(0x0020,0x000d); //!0020 000d UI REL Study Instance UID -} -//---------------------------------------------------------------------------- -string gdcmHeaderHelper::GetSeriesUID() -{ - return GetPubElValByNumber(0x0020,0x000e); //!0020 000e UI REL Series Instance UID -} -//---------------------------------------------------------------------------- -string gdcmHeaderHelper::GetClassUID() -{ - return GetPubElValByNumber(0x0008,0x0016); //!0008 0016 UI ID SOP Class UID -} -//---------------------------------------------------------------------------- -string gdcmHeaderHelper::GetInstanceUID() -{ - return GetPubElValByNumber(0x0008,0x0018); //!0008 0018 UI ID SOP Instance UID -} - - - - - - - - - -gdcmSerieHeaderHelper::~gdcmSerieHeaderHelper() + * \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 SerieHeader::OrderGdcmFileList() { - //! \todo - for (list::iterator it = CoherentGdcmFileList.begin(); - it != CoherentGdcmFileList.end(); it++) - { - delete *it; - } - CoherentGdcmFileList.clear(); -} -//---------------------------------------------------------------------------- -/** - * \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; - - string StrImOriPat = GetPubElValByNumber(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 + if( ImagePositionPatientOrdering() ) + { return ; - } - - //For ACR-NEMA - StrImOriPat = GetPubElValByNumber(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 + } + else if( ImageNumberOrdering() ) + { return ; - } + } + else + { + FileNameOrdering(); + } } -//---------------------------------------------------------------------------- -/** - * \ingroup gdcmHeaderHelper - * \brief add a gdcmFile to the list based on file name - */ -void gdcmSerieHeaderHelper::AddFileName(string filename) -{ - gdcmHeaderHelper *GdcmFile = new gdcmHeaderHelper( filename.c_str() ); - this->CoherentGdcmFileList.push_back( GdcmFile ); -} -//---------------------------------------------------------------------------- -/** - * \ingroup gdcmHeaderHelper - * \brief add a gdcmFile to the list - */ -void gdcmSerieHeaderHelper::AddGdcmFile(gdcmHeaderHelper *file) -{ - this->CoherentGdcmFileList.push_back( file ); -} -//---------------------------------------------------------------------------- -/** - * \ingroup gdcmHeaderHelper - * \brief \todo - */ -void gdcmSerieHeaderHelper::SetDirectory(string dir) -{ - list filenames_list; - GetDir(dir, filenames_list); //OS specific - - for(list::iterator it = filenames_list.begin(); it != - filenames_list.end(); it++) - { - gdcmHeaderHelper *file = new gdcmHeaderHelper( 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 approcah :) -void gdcmSerieHeaderHelper::OrderGdcmFileList() -{ - if( ImagePositionPatientOrdering() ) - { - return ; - } - else if( ImageNumberOrdering() ) - { - return ; - } - else - { - FileNameOrdering(); - } -} -//---------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// Protected + +//----------------------------------------------------------------------------- +// Private /** - * \ingroup gdcmHeaderHelper - * \brief - We may order, considering : - -# Image Number - -# Image Position Patient - -# More to come :) -*/ + * \ingroup Header + * \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 SerieHeader::ImagePositionPatientOrdering() //based on Jolinda's algorithm -bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering() { - //iop is calculated based on the file file - float *cosines = new float[6]; - float normal[3]; - float ipp[3]; - float dist; - float min, max; - bool first = true; - int n=0; - vector distlist; - - //!\todo rewrite this for loop. - for (list::iterator it = CoherentGdcmFileList.begin(); - it != CoherentGdcmFileList.end(); it++) - { - if(first) { - (*it)->GetImageOrientationPatient(cosines); + //iop is calculated based on the file file + float *cosines = new float[6]; + float normal[3]; + float ipp[3]; + float dist; + float min = 0, max = 0; + bool first = true; + int n=0; + std::vector distlist; + + //!\todo rewrite this for loop. + for ( GdcmHeaderList::const_iterator + it = CoherentGdcmFileList.begin(); + it != CoherentGdcmFileList.end(); ++it ) + { + if( first ) + { + (*it)->GetImageOrientationPatient( cosines ); - //You only have to do this once for all slices in the volume. Next, for - //each slice, calculate the distance along the slice normal using the IPP - //tag ("dist" is initialized to zero before reading the first slice) : - normal[0] = cosines[1]*cosines[5] - cosines[2]*cosines[4]; - normal[1] = cosines[2]*cosines[3] - cosines[0]*cosines[5]; - normal[2] = cosines[0]*cosines[4] - cosines[1]*cosines[3]; + //You only have to do this once for all slices in the volume. Next, + // for each slice, calculate the distance along the slice normal + // using the IPP tag ("dist" is initialized to zero before reading + // the first slice) : + normal[0] = cosines[1]*cosines[5] - cosines[2]*cosines[4]; + normal[1] = cosines[2]*cosines[3] - cosines[0]*cosines[5]; + normal[2] = cosines[0]*cosines[4] - cosines[1]*cosines[3]; - ipp[0] = (*it)->GetXOrigin(); - ipp[1] = (*it)->GetYOrigin(); - ipp[2] = (*it)->GetZOrigin(); - - dist = 0; - for (int i = 0; i < 3; ++i) - dist += normal[i]*ipp[i]; + ipp[0] = (*it)->GetXOrigin(); + ipp[1] = (*it)->GetYOrigin(); + ipp[2] = (*it)->GetZOrigin(); + + dist = 0; + for ( int i = 0; i < 3; ++i ) + { + dist += normal[i]*ipp[i]; + } - if( dist == 0 ) - { - delete[] cosines; - return false; - } + if( dist == 0 ) + { + delete[] cosines; + return false; + } - distlist.push_back( dist ); + distlist.push_back( dist ); - max = min = dist; - first = false; - } - else { - ipp[0] = (*it)->GetXOrigin(); - ipp[1] = (*it)->GetYOrigin(); - ipp[2] = (*it)->GetZOrigin(); + max = min = dist; + first = false; + } + else + { + ipp[0] = (*it)->GetXOrigin(); + ipp[1] = (*it)->GetYOrigin(); + ipp[2] = (*it)->GetZOrigin(); - dist = 0; - for (int i = 0; i < 3; ++i) - dist += normal[i]*ipp[i]; + dist = 0; + for ( int i = 0; i < 3; ++i ) + { + dist += normal[i]*ipp[i]; + } + + if( dist == 0 ) + { + delete[] cosines; + return false; + } + + distlist.push_back( dist ); - if( dist == 0 ) - { - delete[] cosines; - return false; + min = (min < dist) ? min : dist; + max = (max > dist) ? max : dist; } + ++n; + } - - distlist.push_back( dist ); - - min = (min < dist) ? min : dist; - max = (max > dist) ? max : dist; - } - n++; - } - - //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. - vector CoherentGdcmFileVector(n); - //CoherentGdcmFileVector.reserve( n ); - CoherentGdcmFileVector.resize( n ); - //assert( CoherentGdcmFileVector.capacity() >= n ); - - float step = (max - min)/(n - 1); - int pos; - n = 0; + // 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. + GdcmHeaderVector CoherentGdcmFileVector(n); + // CoherentGdcmFileVector.reserve( n ); + CoherentGdcmFileVector.resize( n ); + // assert( CoherentGdcmFileVector.capacity() >= n ); + + float step = (max - min)/(n - 1); + int pos; + n = 0; - //VC++ don't understand what scope is !! it -> it2 - for (list::iterator it2 = CoherentGdcmFileList.begin(); - it2 != CoherentGdcmFileList.end(); it2++, n++) - { + //VC++ don't understand what scope is !! it -> it2 + for (GdcmHeaderList::const_iterator it2 = CoherentGdcmFileList.begin(); + it2 != CoherentGdcmFileList.end(); ++it2, ++n) + { //2*n sort algo !! //Assumption: all files are present (no one missing) pos = (int)( fabs( (distlist[n]-min)/step) + .5 ); CoherentGdcmFileVector[pos] = *it2; - } + } - CoherentGdcmFileList.clear(); //this doesn't delete list's element, node only - - //VC++ don't understand what scope is !! it -> it3 - for (vector::iterator it3 = CoherentGdcmFileVector.begin(); - it3 != CoherentGdcmFileVector.end(); it3++) - { - CoherentGdcmFileList.push_back( *it3 ); - } - - distlist.clear(); - CoherentGdcmFileVector.clear(); - delete[] cosines; + CoherentGdcmFileList.clear(); //this doesn't delete list's element, node only - return true; + //VC++ don't understand what scope is !! it -> it3 + for (GdcmHeaderVector::const_iterator it3 = CoherentGdcmFileVector.begin(); + it3 != CoherentGdcmFileVector.end(); ++it3) + { + CoherentGdcmFileList.push_back( *it3 ); + } + + distlist.clear(); + CoherentGdcmFileVector.clear(); + delete[] cosines; + + return true; } -//---------------------------------------------------------------------------- -//Based on Image Number -bool gdcmSerieHeaderHelper::ImageNumberOrdering() + +/** + * \ingroup Header + * \brief sorts the images, according to their Image Number + * @return false only if the header is bugged ! + */ + +bool SerieHeader::ImageNumberOrdering() { - int min, max, pos; - int n = 0;//CoherentGdcmFileList.size(); //O(N) operation !! - unsigned char *partition; + int min, max, pos; + int n = 0;//CoherentGdcmFileList.size() is a O(N) operation !! + unsigned char *partition; - list::iterator it = CoherentGdcmFileList.begin(); - min = max = (*it)->GetImageNumber(); - - for (; it != CoherentGdcmFileList.end(); it++, n++) - { - pos = (*it)->GetImageNumber(); - - //else - min = (min < pos) ? min : pos; - } - - //bzeros(partition, n); //Cette fonction est déconseillée, utilisez plutôt memset. - partition = new unsigned char[n]; - memset(partition, 0, n); - - vector CoherentGdcmFileVector(n); - - //VC++ don't understand what scope is !! it -> it2 - for (list::iterator it2 = CoherentGdcmFileList.begin(); - it2 != CoherentGdcmFileList.end(); it2++) - { - pos = (*it2)->GetImageNumber(); - CoherentGdcmFileVector[pos - min] = *it2; - partition[pos - min]++; - } + GdcmHeaderList::const_iterator it = CoherentGdcmFileList.begin(); + min = max = (*it)->GetImageNumber(); + + for (; it != CoherentGdcmFileList.end(); ++it, ++n) + { + pos = (*it)->GetImageNumber(); + + //else + min = (min < pos) ? min : pos; + } + + //bzeros(partition, n); //Cette fonction est déconseillée, utilisez plutôt memset. + partition = new unsigned char[n]; + memset(partition, 0, n); + + GdcmHeaderVector CoherentGdcmFileVector(n); + + //VC++ don't understand what scope is !! it -> it2 + for (GdcmHeaderList::const_iterator it2 = CoherentGdcmFileList.begin(); + it2 != CoherentGdcmFileList.end(); ++it2) + { + pos = (*it2)->GetImageNumber(); + CoherentGdcmFileVector[pos - min] = *it2; + partition[pos - min]++; + } - unsigned char mult; - for(int i=0; i it3 - CoherentGdcmFileList.clear(); //this doesn't delete list's element, node only - for (vector::iterator it3 = CoherentGdcmFileVector.begin(); - it3 != CoherentGdcmFileVector.end(); it3++) - { - CoherentGdcmFileList.push_back( *it3 ); - } - CoherentGdcmFileVector.clear(); + unsigned char mult = 1; + for( int i=0; i it3 + CoherentGdcmFileList.clear(); //this doesn't delete list's element, node only + for ( GdcmHeaderVector::const_iterator it3 = CoherentGdcmFileVector.begin(); + it3 != CoherentGdcmFileVector.end(); ++it3 ) + { + CoherentGdcmFileList.push_back( *it3 ); + } + CoherentGdcmFileVector.clear(); - delete[] partition; - return mult; -} -//---------------------------------------------------------------------------- -bool gdcmSerieHeaderHelper::FileNameOrdering() -{ - //using the sort - //sort(CoherentGdcmFileList.begin(), CoherentGdcmFileList.end()); - return true; + delete[] partition; + + return (mult != 0); } -//---------------------------------------------------------------------------- -list &gdcmSerieHeaderHelper::GetGdcmFileList() + + +/** + * \ingroup Header + * \brief sorts the images, according to their File Name + * @return false only if the header is bugged ! + */ +bool SerieHeader::FileNameOrdering() { - return CoherentGdcmFileList; + //using the sort + //sort(CoherentGdcmFileList.begin(), CoherentGdcmFileList.end()); + return true; } -//---------------------------------------------------------------------------- + +} // end namespace gdcm +//-----------------------------------------------------------------------------