X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmHeaderHelper.cxx;h=340dc812d577533db891d4e0119afbc594d04f14;hb=eafd36f8a658f5d3b29e733bf87540150feaddf6;hp=4f53b9704dd3f5ec53cacb6eb81c765b1fadd004;hpb=15915dd3b6d2c5e64f4a06a1516ae51b3cb9944a;p=gdcm.git diff --git a/src/gdcmHeaderHelper.cxx b/src/gdcmHeaderHelper.cxx index 4f53b970..340dc812 100644 --- a/src/gdcmHeaderHelper.cxx +++ b/src/gdcmHeaderHelper.cxx @@ -3,12 +3,12 @@ Program: gdcm Module: $RCSfile: gdcmHeaderHelper.cxx,v $ Language: C++ - Date: $Date: 2004/06/25 19:37:05 $ - Version: $Revision: 1.39 $ + 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.htm for details. + 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 @@ -18,22 +18,32 @@ #include "gdcmHeaderHelper.h" #include "gdcmDirList.h" - #include "gdcmDebug.h" + #include #include #include +namespace gdcm +{ + +typedef std::vector GdcmHeaderVector; //----------------------------------------------------------------------------- // Constructor / Destructor -gdcmSerieHeader::~gdcmSerieHeader(){ - /// \todo - for (std::list::iterator it = CoherentGdcmFileList.begin(); - it != CoherentGdcmFileList.end(); it++) - { - delete *it; - } - CoherentGdcmFileList.clear(); +SerieHeader::SerieHeader() +{ + CoherentGdcmFileList.clear(); +} + +SerieHeader::~SerieHeader() +{ + /// \todo + for ( GdcmHeaderList::const_iterator it = CoherentGdcmFileList.begin(); + it != CoherentGdcmFileList.end(); ++it) + { + delete *it; + } + CoherentGdcmFileList.clear(); } //----------------------------------------------------------------------------- @@ -42,35 +52,39 @@ gdcmSerieHeader::~gdcmSerieHeader(){ //----------------------------------------------------------------------------- // Public /** - * \brief add a gdcmFile to the list based on file name + * \brief add a File to the list based on file name * @param filename Name of the file to deal with */ -void gdcmSerieHeader::AddFileName(std::string filename) { - gdcmHeader *GdcmFile = new gdcmHeader( filename ); - this->CoherentGdcmFileList.push_back( GdcmFile ); +void SerieHeader::AddFileName(std::string const & filename) +{ + Header *header = new Header( filename ); + CoherentGdcmFileList.push_back( header ); } /** - * \brief add a gdcmFile to the list - * @param file gdcmHeader to add + * \brief add a File to the list + * @param file Header to add */ -void gdcmSerieHeader::AddGdcmFile(gdcmHeader *file){ - this->CoherentGdcmFileList.push_back( file ); +void SerieHeader::AddGdcmFile(Header *file) +{ + CoherentGdcmFileList.push_back( file ); } /** * \brief Sets the Directory * @param dir Name of the directory to deal with */ -void gdcmSerieHeader::SetDirectory(std::string dir){ - gdcmDirList filenames_list(dir); //OS specific +void SerieHeader::SetDirectory(std::string const & dir) +{ + DirList filenames_list(dir); //OS specific - for(gdcmDirList::iterator it = filenames_list.begin(); - it !=filenames_list.end(); it++) - { - gdcmHeader *file = new gdcmHeader( it->c_str() ); - this->CoherentGdcmFileList.push_back( file ); - } + 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 ); + } } /** @@ -78,24 +92,21 @@ void gdcmSerieHeader::SetDirectory(std::string dir){ * \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() ) { - return ; - } else { - FileNameOrdering(); - } -} - -/** - * \brief Gets the *coherent* File List - * @return the *coherent* File List -*/ -std::list &gdcmSerieHeader::GetGdcmFileList() { - return CoherentGdcmFileList; + */ +void SerieHeader::OrderGdcmFileList() +{ + if( ImagePositionPatientOrdering() ) + { + return ; + } + else if( ImageNumberOrdering() ) + { + return ; + } + else + { + FileNameOrdering(); + } } //----------------------------------------------------------------------------- @@ -104,7 +115,7 @@ std::list &gdcmSerieHeader::GetGdcmFileList() { //----------------------------------------------------------------------------- // Private /** - * \ingroup gdcmHeader + * \ingroup Header * \brief sorts the images, according to their Patient Position * We may order, considering : * -# Image Number @@ -112,180 +123,192 @@ std::list &gdcmSerieHeader::GetGdcmFileList() { * -# More to come :) * @return false only if the header is bugged ! */ -bool gdcmSerieHeader::ImagePositionPatientOrdering() +bool SerieHeader::ImagePositionPatientOrdering() //based on Jolinda's algorithm { - //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 (std::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; } - - 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. - std::vector CoherentGdcmFileVector(n); - //CoherentGdcmFileVector.reserve( n ); - CoherentGdcmFileVector.resize( n ); - //assert( CoherentGdcmFileVector.capacity() >= n ); - - float step = (max - min)/(n - 1); - int pos; - n = 0; + ++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. + 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 (std::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 (std::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; } /** - * \ingroup gdcmHeader + * \ingroup Header * \brief sorts the images, according to their Image Number * @return false only if the header is bugged ! */ -bool gdcmSerieHeader::ImageNumberOrdering() { - int min, max, pos; - int n = 0;//CoherentGdcmFileList.size() is a O(N) operation !! - unsigned char *partition; +bool SerieHeader::ImageNumberOrdering() +{ + int min, max, pos; + int n = 0;//CoherentGdcmFileList.size() is a O(N) operation !! + unsigned char *partition; - std::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); - - std::vector CoherentGdcmFileVector(n); - - //VC++ don't understand what scope is !! it -> it2 - for (std::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 = 1; - for(int i=0; i it3 - CoherentGdcmFileList.clear(); //this doesn't delete list's element, node only - for (std::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!=0); + delete[] partition; + + return (mult != 0); } /** - * \ingroup gdcmHeader + * \ingroup Header * \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; +bool SerieHeader::FileNameOrdering() +{ + //using the sort + //sort(CoherentGdcmFileList.begin(), CoherentGdcmFileList.end()); + return true; } +} // end namespace gdcm //-----------------------------------------------------------------------------