]> Creatis software - gdcm.git/blob - src/gdcmDocEntry.cxx
Jean-Pierre Roux
[gdcm.git] / src / gdcmDocEntry.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmDocEntry.cxx,v $
5   Language:  C++
6   Date:      $Date: 2004/06/24 18:03:14 $
7   Version:   $Revision: 1.10 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.htm for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18
19 #include "gdcmDocEntry.h"
20 #include "gdcmTS.h"
21 #include "gdcmGlobal.h"
22 #include "gdcmUtil.h"
23
24 #include <iomanip> // for std::ios::left, ...
25
26 // CLEAN ME
27 #define MAX_SIZE_PRINT_ELEMENT_VALUE 64
28
29 //-----------------------------------------------------------------------------
30 // Constructor / Destructor
31 /**
32  * \ingroup gdcmDocEntry
33  * \brief   Constructor from a given gdcmDictEntry
34  * @param   in Pointer to existing dictionary entry
35  */
36 gdcmDocEntry::gdcmDocEntry(gdcmDictEntry* in) {
37    ImplicitVR = false;
38    entry = in;
39 }
40
41 //-----------------------------------------------------------------------------
42 // Print
43 /**
44  * \ingroup gdcmDocEntry
45  * \brief   Prints the common part of gdcmValEntry, gdcmBinEntry, gdcmSeqEntry
46  * @param   os ostream we want to print in
47  */
48 void gdcmDocEntry::Print(std::ostream & os) {
49
50    printLevel=2; // FIXME
51    
52    size_t o;
53    unsigned short int g, e;
54    char st[20];
55    TSKey v;
56    std::string d2, vr;
57    std::ostringstream s;
58    guint32 lgth;
59    char greltag[10];  //group element tag
60
61    g  = GetGroup();
62    e  = GetElement();
63    o  = GetOffset();
64    vr = GetVR();
65    sprintf(greltag,"%04x|%04x ",g,e);           
66    s << greltag ;
67        
68    if (printLevel>=2) { 
69       s << "lg : ";
70       lgth = GetReadLength(); // ReadLength, as opposed to UsableLength
71       if (lgth == 0xffffffff) {
72          sprintf(st,"x(ffff)");  // I said : "x(ffff)" !
73          s.setf(std::ios::left);
74          s << std::setw(10-strlen(st)) << " ";  
75          s << st << " ";
76          s.setf(std::ios::left);
77          s << std::setw(8) << "-1";      
78       } else {
79          sprintf(st,"x(%x)",lgth);
80          s.setf(std::ios::left);
81          s << std::setw(10-strlen(st)) << " ";  
82          s << st << " ";
83          s.setf(std::ios::left);
84          s << std::setw(8) << lgth; 
85       }
86       s << " Off.: ";
87       sprintf(st,"x(%x)",o); 
88       s << std::setw(10-strlen(st)) << " ";
89       s << st << " ";
90       s << std::setw(8) << o; 
91    }
92
93    s << "[" << vr  << "] ";
94
95    if (printLevel>=1) {      
96       s.setf(std::ios::left);
97       s << std::setw(66-GetName().length()) << " ";
98    }
99     
100    s << "[" << GetName()<< "]";
101    os << s.str();      
102 }
103
104 /**
105  * \ingroup gdcmDocEntry
106  * \brief   Writes the common part of any gdcmValEntry, gdcmBinEntry, gdcmSeqEntry
107  */
108 void gdcmDocEntry::Write(FILE *fp, FileType filetype) {
109
110    guint32 FFFF = 0xffffffff;
111    guint16 group  = GetGroup();
112    VRKey   vr     = GetVR();
113    guint16 el     = GetElement();
114    guint32 lgr    = GetReadLength();
115
116    if ( (group == 0xfffe) && (el == 0x0000) ) 
117      // Fix in order to make some MR PHILIPS images e-film readable
118      // see gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm:
119      // we just *always* ignore spurious fffe|0000 tag !   
120       return; 
121
122 //
123 // ----------- Writes the common part
124 //
125    fwrite ( &group,(size_t)2 ,(size_t)1 ,fp);  //group
126    fwrite ( &el,   (size_t)2 ,(size_t)1 ,fp);  //element
127       
128    if ( filetype == gdcmExplicitVR ) {
129
130       // Special case of delimiters:
131       if (group == 0xfffe) {
132          // Delimiters have NO Value Representation
133          // Hence we skip writing the VR.
134          // In order to avoid further troubles, we choose to write them
135          // as 'no-length' Item Delimitors (we pad by writing 0xffffffff)
136          // The end of a given Item will be found when  :
137          //  - a new Item Delimitor Item is encountered (the Seq goes on)
138          //  - a Sequence Delimitor Item is encountered (the Seq just ended)
139
140        // TODO : verify if the Sequence Delimitor Item was forced during Parsing 
141
142          int ff=0xffffffff;
143          fwrite (&ff,(size_t)4 ,(size_t)1 ,fp);
144          return;
145       }
146
147       guint16 z=0;
148       guint16 shortLgr = lgr;
149       if (vr == "unkn") {     // Unknown was 'written'
150          // deal with Little Endian            
151          fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,fp);
152          fwrite ( &z,  (size_t)2 ,(size_t)1 ,fp);
153       } else {
154          fwrite (vr.c_str(),(size_t)2 ,(size_t)1 ,fp); 
155                   
156          if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") )
157          {
158             fwrite ( &z,  (size_t)2 ,(size_t)1 ,fp);
159             if (vr == "SQ") {
160             // we set SQ length to ffffffff
161             // and  we shall write a Sequence Delimitor Item 
162             // at the end of the Sequence! 
163                fwrite ( &FFFF,(size_t)4 ,(size_t)1 ,fp);
164             } else {
165                fwrite ( &lgr,(size_t)4 ,(size_t)1 ,fp);
166             }
167          } else {
168             fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,fp);
169          }
170       }
171    } 
172    else // IMPLICIT VR 
173    { 
174       if (vr == "SQ") {
175           fwrite ( &FFFF,(size_t)4 ,(size_t)1 ,fp);
176        } else {
177           fwrite ( &lgr,(size_t)4 ,(size_t)1 ,fp);
178        }
179    }
180 }
181
182 //-----------------------------------------------------------------------------
183 // Public
184
185 /**
186  * \ingroup gdcmDocEntry
187  * \brief   Gets the full length of the elementary DocEntry (not only value length)
188  */
189 guint32 gdcmDocEntry::GetFullLength(void) {
190    guint32 l;
191    l = GetReadLength();
192    if ( IsImplicitVR() ) 
193       l = l + 8;  // 2 (gr) + 2 (el) + 4 (lgth) 
194    else    
195       if ( GetVR()=="OB" || GetVR()=="OW" || GetVR()=="SQ" )
196          l = l + 12; // 2 (gr) + 2 (el) + 2 (vr) + 2 (unused) + 4 (lgth)
197       else
198          l = l + 8;  // 2 (gr) + 2 (el) + 2 (vr) + 2 (lgth)
199    return(l);
200 }
201
202 /**
203  * \ingroup gdcmDocEntry
204  * \brief   Copies all the attributes from an other DocEntry 
205  */
206 void gdcmDocEntry::Copy (gdcmDocEntry* e) {
207    this->entry        = e->entry;
208    this->UsableLength = e->UsableLength;
209    this->ReadLength   = e->ReadLength;
210    this->ImplicitVR   = e->ImplicitVR;
211    this->Offset       = e->Offset;
212    this->printLevel   = e->printLevel;
213    // TODO : remove gdcmDocEntry SQDepth
214 }
215
216 /**
217  * \ingroup gdcmDocEntry
218  * \brief   tells us if entry is the last one of a 'no length' SequenceItem 
219  *          (fffe,e00d) 
220  */
221 bool gdcmDocEntry::isItemDelimitor() {
222    if ( (GetGroup() == 0xfffe) && (GetElement() == 0xe00d) )
223       return true;
224    else
225       return false;      
226 }
227 /**
228  * \ingroup gdcmDocEntry
229  * \brief   tells us if entry is the last one of a 'no length' Sequence 
230  *          (fffe,e0dd) 
231  */
232 bool gdcmDocEntry::isSequenceDelimitor() {
233    if (GetGroup() == 0xfffe && GetElement() == 0xe0dd)
234       return true;
235    else
236       return false; 
237 }
238
239 //-----------------------------------------------------------------------------
240 // Protected
241
242
243 //-----------------------------------------------------------------------------
244 // Private
245
246 //-----------------------------------------------------------------------------