gdcmSeqEntry.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002                                                                                 
00003   Program:   gdcm
00004   Module:    $RCSfile: gdcmSeqEntry.cxx,v $
00005   Language:  C++
00006   Date:      $Date: 2007/07/26 08:36:49 $
00007   Version:   $Revision: 1.69 $
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 "gdcmSeqEntry.h"
00020 #include "gdcmSQItem.h"
00021 #include "gdcmTS.h"
00022 #include "gdcmGlobal.h"
00023 #include "gdcmUtil.h"
00024 #include "gdcmDebug.h"
00025 
00026 #include <iostream>
00027 #include <iomanip>
00028 #include <fstream>
00029 
00030 namespace GDCM_NAME_SPACE 
00031 {
00032 //-----------------------------------------------------------------------------
00033 // Constructor / Destructor
00034 
00035 // Constructor / Destructor
00039 SeqEntry::SeqEntry( uint16_t group,uint16_t elem ) 
00040              : DocEntry(group, elem, "SQ")
00041 {
00042    Length       = 0;
00043    ReadLength   = 0xffffffff;
00044    SQDepthLevel = -1;
00045 
00046    DelimitorMode = false;
00047    SeqTerm  = NULL;
00048 }
00049 
00055 SeqEntry::SeqEntry( DocEntry *e, int depth )
00056              //: DocEntry( e->GetDictEntry() )
00057             : DocEntry( e->GetGroup(), e->GetElement(), "SQ" /*e->GetVR()*/ )
00058 {
00059    Length       = 0;
00060    ReadLength   = 0xffffffff;
00061    SQDepthLevel = depth;
00062 
00063    ImplicitVR   = e->IsImplicitVR();
00064    Offset       = e->GetOffset();
00065    SeqTerm = NULL;
00066 }
00067 
00071 SeqEntry::~SeqEntry()
00072 {
00073    ClearSQItem();
00074 }
00075 
00076 //-----------------------------------------------------------------------------
00077 // Public
00078 /*
00079  * \brief   canonical Writer
00080  * @param fp pointer to an already open file
00081  * @param filetype type of the file (ACR, ImplicitVR, ExplicitVR, ...)
00082  */
00083 void SeqEntry::WriteContent(std::ofstream *fp, FileType filetype, bool dummy)
00084 {
00085    uint16_t seq_term_gr = 0xfffe;
00086    uint16_t seq_term_el = 0xe0dd;
00087    uint32_t seq_term_lg = 0x00000000;
00088  
00089    // ignore 'Zero length' Sequences
00090    if ( GetReadLength() == 0 )
00091       return;
00092    // false : we are not in MetaElements
00093    DocEntry::WriteContent(fp, filetype, false);
00094    for(ListSQItem::iterator cc  = Items.begin();
00095                             cc != Items.end();
00096                           ++cc)
00097    {   
00098       (*cc)->WriteContent(fp, filetype, false);
00099    }
00100    
00101    // we force the writting of a Sequence Delimitation item
00102    // because we wrote the Sequence as a 'no Length' sequence
00103    binary_write(*fp, seq_term_gr);
00104    binary_write(*fp, seq_term_el);
00105    binary_write(*fp, seq_term_lg);
00106 }
00107 
00112 uint32_t SeqEntry::ComputeFullLength()
00113 {
00114    uint32_t l = 12; // Tag (4) + VR (explicit) 4 + 4 (length);   
00115    for(ListSQItem::iterator cc  = Items.begin();
00116                             cc != Items.end();
00117                           ++cc)
00118    {        
00119       l += (*cc)->ComputeFullLength();
00120    }   
00121    l += 8; // seq_term Tag (4) +  seq_term_lg (4)
00122    return l;
00123 }
00124 
00131 void SeqEntry::AddSQItem(SQItem *sqItem, int itemNumber)
00132 {
00133 // FIXME : SQItemNumber is supposed to be the ordinal number of the SQItem
00134 //         within the Sequence.
00135 //         Either only 'push_back' is allowed, 
00136 //                and we just have to do something like SeqEntry::lastNb++
00137 //         Or we can add (or remove) anywhere, and SQItemNumber will be broken
00138    sqItem->SetSQItemNumber(itemNumber);
00139    Items.push_back(sqItem);
00140    sqItem->Register();
00141 }
00142 
00146 void SeqEntry::ClearSQItem()
00147 {
00148    for(ListSQItem::iterator cc = Items.begin(); cc != Items.end(); ++cc)
00149    {
00150       (*cc)->Unregister();
00151    }
00152    if (SeqTerm)
00153    {
00154       SeqTerm->Unregister();
00155    }
00156 }
00157 
00162 SQItem *SeqEntry::GetFirstSQItem()
00163 {
00164    ItSQItem = Items.begin();
00165    if (ItSQItem != Items.end())
00166       return *ItSQItem;
00167    return NULL;
00168 } 
00169 
00176 SQItem *SeqEntry::GetNextSQItem()
00177 {
00178    gdcmAssertMacro (ItSQItem != Items.end())
00179    {
00180       ++ItSQItem;
00181       if (ItSQItem != Items.end())
00182          return *ItSQItem;
00183    }
00184    return NULL;
00185 }
00186  
00193 SQItem *SeqEntry::GetSQItem(int nb)
00194 {
00195    if (nb<0)
00196    {
00197       return *(Items.begin());
00198    }
00199    int count = 0 ;
00200    for(ListSQItem::iterator cc = Items.begin();
00201                            cc != Items.end();
00202                            count ++, ++cc)
00203    {
00204       if (count == nb)
00205       {
00206          return *cc;
00207       }
00208    }
00209    return *(Items.end());
00210 }
00211 
00215 unsigned int SeqEntry::GetNumberOfSQItems()
00216 {
00217    return Items.size();
00218 }
00219 
00224 void SeqEntry::SetDelimitationItem(DocEntry *e)
00225 {
00226    if( SeqTerm != e )
00227    {
00228       if( SeqTerm )
00229          SeqTerm->Unregister();
00230       SeqTerm = e;
00231       if( SeqTerm )
00232          SeqTerm->Register();
00233    }
00234 }
00235 
00241 void SeqEntry::Copy(DocEntry *doc)
00242 {
00243    // Delete previous SQ items
00244    ClearSQItem();
00245 
00246    DocEntry::Copy(doc);
00247    SeqEntry *entry = dynamic_cast<SeqEntry *>(doc);
00248    if ( entry )
00249    {
00250       DelimitorMode = entry->DelimitorMode;
00251       SQDepthLevel = entry->SQDepthLevel;
00252 
00253       SeqTerm = entry->SeqTerm;
00254       if(SeqTerm)
00255          SeqTerm->Register();
00256       Items = entry->Items;
00257       for(ItSQItem = Items.begin();ItSQItem != Items.end(); ++ItSQItem)
00258       {
00259          (*ItSQItem)->Register();
00260       }
00261    }
00262 }
00263 
00264 //-----------------------------------------------------------------------------
00265 // Protected
00266 
00267 //-----------------------------------------------------------------------------
00268 // Private
00269 
00270 //-----------------------------------------------------------------------------
00271 // Print
00275 void SeqEntry::Print( std::ostream &os, std::string const & )
00276 {
00277    // First, Print the Dicom Element itself.
00278    os << "S ";
00279    DocEntry::Print(os);
00280    os << std::endl;
00281 
00282    if (GetReadLength() == 0)
00283       return;
00284 
00285    // Then, Print each SQ Item   
00286    for(ListSQItem::iterator cc = Items.begin(); cc != Items.end(); ++cc)
00287    {
00288       (*cc)->SetPrintLevel(PrintLevel);
00289       (*cc)->Print(os);   
00290    }
00291 
00292    // at end, print the sequence terminator item, if any
00293    if (DelimitorMode)
00294    {
00295       int i;
00296       for ( i = 0; i < SQDepthLevel; i++ )
00297          os << "   | " ;
00298       os << " --- "  << std::endl;
00299       for ( i = 0; i < SQDepthLevel; i++ )
00300          os << "   | " ;
00301       if (SeqTerm != NULL)
00302       {
00303          SeqTerm->SetPrintLevel(PrintLevel);
00304          SeqTerm->Print(os);
00305          os << std::endl;
00306       } 
00307       else 
00308       {
00309          // fuse
00310          gdcmWarningMacro("  -------- should have a sequence terminator item");
00311       }
00312    }
00313 }
00314 
00315 //-----------------------------------------------------------------------------
00316 } // end namespace gdcm

Generated on Fri Aug 24 12:53:18 2007 for gdcm by  doxygen 1.4.6