Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

gdcmSQItem.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002   
00003   Program:   gdcm
00004   Module:    $RCSfile: gdcmSQItem.cxx,v $
00005   Language:  C++
00006   Date:      $Date: 2005/12/13 09:22:05 $
00007   Version:   $Revision: 1.83 $
00008   
00009   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
00010   l'Image). All rights reserved. See Doc/License.txt or
00011   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
00012   
00013      This software is distributed WITHOUT ANY WARRANTY; without even
00014      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00015      PURPOSE.  See the above copyright notices for more information.
00016   
00017 =========================================================================*/
00018 
00019 #include "gdcmSQItem.h"
00020 #include "gdcmSeqEntry.h"
00021 #include "gdcmGlobal.h"
00022 #include "gdcmDictSet.h"
00023 #include "gdcmUtil.h"
00024 #include "gdcmDebug.h"
00025 
00026 #include <fstream>
00027 
00028 namespace gdcm 
00029 {
00030 //-----------------------------------------------------------------------------
00031 // Constructor / Destructor
00035 SQItem::SQItem(int depthLevel ) 
00036           : DocEntrySet( )
00037 {
00038    SQDepthLevel = depthLevel;
00039    SQItemNumber = 0;
00040 }
00041 
00045 SQItem::~SQItem() 
00046 {
00047    ClearEntry();
00048 }
00049 
00050 //-----------------------------------------------------------------------------
00051 // Public
00052 /*
00053  * \brief   canonical Writer
00054  * @param fp     file pointer to an already open file. 
00055  * @param filetype type of the file (ACR, ImplicitVR, ExplicitVR, ...)
00056  */
00057 void SQItem::WriteContent(std::ofstream *fp, FileType filetype)
00058 {
00059    int j;
00060    uint16_t item[4] = { 0xfffe, 0xe000, 0xffff, 0xffff };
00061    uint16_t itemt[4]= { 0xfffe, 0xe00d, 0x0000, 0x0000 };
00062 
00063     //we force the writting of an 'Item' Start Element
00064     // because we want to write the Item as a 'No Length' item
00065    for(j=0;j<4;++j)
00066    {
00067       binary_write( *fp, item[j]);  // fffe e000 ffff ffff 
00068    }
00069      
00070    for (ListDocEntry::iterator it = DocEntries.begin();  
00071                                it != DocEntries.end();
00072                              ++it)
00073    {   
00074       // we skip delimitors (start and end one) because 
00075       // we force them as 'no length'
00076       if ( (*it)->GetGroup() == 0xfffe )
00077       {
00078          continue;
00079       }
00080 
00081       // Fix in order to make some MR PHILIPS images e-film readable
00082       // see gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm:
00083       // we just *always* ignore spurious fffe|0000 tag ! 
00084       if ( (*it)->GetGroup() == 0xfffe && (*it)->GetElement() == 0x0000 )
00085       {
00086           break; // FIXME : break or continue; ?!?  
00087                  // --> makes no difference since the only bugged file we have
00088                  // contains 'impossible tag' fffe|0000 in last position !                            
00089       }
00090 
00091       (*it)->WriteContent(fp, filetype);
00092    }
00093       
00094     //we force the writting of an 'Item Delimitation' item
00095     // because we wrote the Item as a 'no Length' item
00096    for(j=0;j<4;++j)
00097    {
00098       binary_write( *fp, itemt[j]);  // fffe e000 0000 0000 
00099    } 
00100 }
00101 
00106 uint32_t SQItem::ComputeFullLength()
00107 {
00108    uint32_t l = 8;  // Item Starter length
00109    for (ListDocEntry::iterator it = DocEntries.begin();  
00110                                it != DocEntries.end();
00111                              ++it)
00112    {   
00113       // we skip delimitors (start and end one) because 
00114       // we force them as 'no length'
00115       if ( (*it)->GetGroup() == 0xfffe )
00116       {
00117          continue;
00118       }
00119       l += (*it)->ComputeFullLength();
00120    }
00121    l += 8; // 'Item Delimitation' item 
00122    return l;  
00123 }
00124 
00131 bool SQItem::AddEntry(DocEntry *entry)
00132 {   
00133    if (DocEntries.empty() )
00134    {
00135       DocEntries.push_back(entry);
00136       entry->Register();
00137       return true;
00138    }
00139  
00140    ListDocEntry::iterator insertSpot;
00141    ListDocEntry::iterator it = DocEntries.end();
00142    do
00143    {
00144       it--;
00145 
00146       if ( (*it)->IsItemDelimitor() )
00147       {
00148          continue;
00149       }
00150       if ( (*it)->GetGroup() < entry->GetGroup() )
00151          break;
00152       else
00153          if ( (*it)->GetGroup() == entry->GetGroup() &&
00154               (*it)->GetElement() < entry->GetElement() )
00155             break;
00156    } while (it != DocEntries.begin() );
00157   
00158    ++it;
00159    insertSpot = it;
00160    DocEntries.insert(insertSpot, entry); 
00161    entry->Register();
00162    return true;
00163 }   
00164 
00170 bool SQItem::RemoveEntry( DocEntry *entryToRemove )
00171 {
00172    for(ListDocEntry::iterator it = DocEntries.begin();
00173                               it != DocEntries.end();
00174                             ++it)
00175    {
00176       if ( *it == entryToRemove )
00177       {
00178          DocEntries.erase(it);
00179          gdcmDebugMacro( "One element erased: " << entryToRemove->GetKey() );
00180          entryToRemove->Unregister();
00181          return true;
00182       }
00183    }
00184    gdcmWarningMacro( "Entry not found: " << entryToRemove->GetKey() );
00185    return false ;
00186 }
00187 
00191 void SQItem::ClearEntry()
00192 {
00193    for(ListDocEntry::iterator cc = DocEntries.begin();
00194                               cc != DocEntries.end();
00195                             ++cc)
00196    {
00197       (*cc)->Unregister();
00198    }
00199    DocEntries.clear();
00200 }
00201 
00206 DocEntry *SQItem::GetFirstEntry()
00207 {
00208    ItDocEntries = DocEntries.begin();
00209    if ( ItDocEntries != DocEntries.end() )
00210       return *ItDocEntries;
00211    return 0;   
00212 }
00213                                                                                 
00218 DocEntry *SQItem::GetNextEntry()
00219 {
00220    ++ItDocEntries;
00221    if ( ItDocEntries != DocEntries.end() )
00222       return  *ItDocEntries;
00223    return NULL;
00224 }
00225 
00232 DocEntry *SQItem::GetDocEntry(uint16_t group, uint16_t elem)
00233 {
00234    for(ListDocEntry::iterator i =  DocEntries.begin();
00235                               i != DocEntries.end(); 
00236                             ++i)
00237    {
00238       if ( (*i)->GetGroup() == group && (*i)->GetElement() == elem )
00239          return *i;
00240    }
00241    return NULL;
00242 }
00243 
00249 void SQItem::Copy(DocEntrySet *set)
00250 {
00251    // Remove all previous entries
00252    ClearEntry();
00253 
00254    DocEntrySet::Copy(set);
00255 
00256    SQItem *sq = dynamic_cast<SQItem *>(set);
00257    if( sq )
00258    {
00259       SQDepthLevel = sq->SQDepthLevel;
00260       SQItemNumber = sq->SQItemNumber;
00261 
00262       DocEntries = sq->DocEntries;
00263       for(ItDocEntries = DocEntries.begin();ItDocEntries != DocEntries.end();++ItDocEntries)
00264          (*ItDocEntries)->Register();
00265    }
00266 }
00267 
00268 //-----------------------------------------------------------------------------
00269 // Protected
00270 
00271 //-----------------------------------------------------------------------------
00272 // Private
00273 
00274 //-----------------------------------------------------------------------------
00275 // Print
00276 /*
00277  * \brief   canonical Printer
00278  * @param os     Stream to print to. 
00279  * @param indent Indentation string to be prepended during printing.
00280  */
00281 void SQItem::Print(std::ostream &os, std::string const &)
00282 {
00283    std::ostringstream s;
00284 
00285    if (SQDepthLevel > 0)
00286    {
00287       for (int i = 0; i < SQDepthLevel; ++i)
00288       {
00289          s << "   | " ;
00290       }
00291    }
00292    os << s.str() << " --- SQItem number " << SQItemNumber  << std::endl;
00293    for (ListDocEntry::iterator i  = DocEntries.begin();
00294                                i != DocEntries.end();
00295                              ++i)
00296    {
00297       DocEntry *Entry = *i;
00298       bool PrintEndLine = true;
00299 
00300       os << s.str();
00301       Entry->SetPrintLevel(PrintLevel);
00302       Entry->Print(os); 
00303       if ( dynamic_cast<SeqEntry*>(Entry) )
00304       {
00305          PrintEndLine = false;
00306       }
00307       if (PrintEndLine)
00308       {
00309          os << std::endl;
00310       }
00311    } 
00312 }
00313 
00314 //-----------------------------------------------------------------------------
00315 } // end namespace gdcm

Generated on Fri Jan 20 10:14:26 2006 for gdcm by  doxygen 1.4.4