GDCM  2.2.1
gdcmFragment.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: GDCM (Grassroots DICOM). A DICOM library
4 
5  Copyright (c) 2006-2011 Mathieu Malaterre
6  All rights reserved.
7  See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
8 
9  This software is distributed WITHOUT ANY WARRANTY; without even
10  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11  PURPOSE. See the above copyright notice for more information.
12 
13 =========================================================================*/
14 #ifndef GDCMFRAGMENT_H
15 #define GDCMFRAGMENT_H
16 
17 #include "gdcmDataElement.h"
18 #include "gdcmByteValue.h"
19 #include "gdcmSmartPointer.h"
20 #include "gdcmParseException.h"
21 
22 namespace gdcm
23 {
24 
25 // Implementation detail:
26 // I think Fragment should be a protected sublclass of DataElement:
27 // looking somewhat like this:
28 /*
29 class GDCM_EXPORT Fragment : protected DataElement
30 {
31 public:
32  using DataElement::GetTag;
33  using DataElement::GetVL;
34  using DataElement::SetByteValue;
35  using DataElement::GetByteValue;
36  using DataElement::GetValue;
37 */
38 // Instead I am only hiding the SetTag member...
39 
44 {
45 //protected:
46 // void SetTag(const Tag &t);
47 public:
48  Fragment() : DataElement(Tag(0xfffe, 0xe000), 0) {}
49  friend std::ostream &operator<<(std::ostream &os, const Fragment &val);
50 
51  VL GetLength() const {
52  assert( !ValueLengthField.IsUndefined() );
53  assert( !ValueField || ValueField->GetLength() == ValueLengthField );
54  return TagField.GetLength() + ValueLengthField.GetLength()
55  + ValueLengthField;
56  }
57 
58  template <typename TSwap>
59  std::istream &Read(std::istream &is)
60  {
61  ReadPreValue<TSwap>(is);
62  return ReadValue<TSwap>(is);
63  }
64 
65  template <typename TSwap>
66  std::istream &ReadPreValue(std::istream &is)
67  {
68  const Tag itemStart(0xfffe, 0xe000);
69  const Tag seqDelItem(0xfffe,0xe0dd);
70 
71  TagField.Read<TSwap>(is);
72  if( !is )
73  {
74  // BogusItemStartItemEnd.dcm
75  throw Exception( "Problem" );
76  return is;
77  }
78  if( !ValueLengthField.Read<TSwap>(is) )
79  {
80  // GENESIS_SIGNA-JPEG-CorruptFrag.dcm
81  // JPEG fragment is declared to have 61902, but infact really is only 61901
82  // so we end up reading 0xddff,0x00e0, and VL = 0x0 (1 byte)
83  throw Exception( "Problem" );
84  return is;
85  }
86 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
87  if( TagField != itemStart && TagField != seqDelItem )
88  {
89  throw Exception( "Problem" );
90  }
91 #endif
92  return is;
93  }
94 
95  template <typename TSwap>
96  std::istream &ReadValue(std::istream &is)
97  {
98  // Superclass
99  const Tag itemStart(0xfffe, 0xe000);
100  const Tag seqDelItem(0xfffe,0xe0dd);
101  // Self
103  bv->SetLength(ValueLengthField);
104  if( !bv->Read<TSwap>(is) )
105  {
106  // Fragment is incomplete, but is a itemStart, let's try to push it anyway...
107  gdcmWarningMacro( "Fragment could not be read" );
108  //bv->SetLength(is.gcount());
109  ValueField = bv;
110  ParseException pe;
111  pe.SetLastElement( *this );
112  throw pe;
113  return is;
114  }
115  ValueField = bv;
116  return is;
117  }
118 
119 
120  template <typename TSwap>
121  std::ostream &Write(std::ostream &os) const {
122  const Tag itemStart(0xfffe, 0xe000);
123  const Tag seqDelItem(0xfffe,0xe0dd);
124  if( !TagField.Write<TSwap>(os) )
125  {
126  assert(0 && "Should not happen");
127  return os;
128  }
129  assert( TagField == itemStart
130  || TagField == seqDelItem );
131  const ByteValue *bv = GetByteValue();
132  // VL
133  // The following piece of code is hard to read in order to support such broken file as:
134  // CompressedLossy.dcm
135  if( IsEmpty() )
136  {
137  //assert( bv );
138  VL zero = 0;
139  if( !zero.Write<TSwap>(os) )
140  {
141  assert(0 && "Should not happen");
142  return os;
143  }
144  }
145  else
146  {
147  assert( ValueLengthField );
148  if( !ValueLengthField.Write<TSwap>(os) )
149  {
150  assert(0 && "Should not happen");
151  return os;
152  }
153  }
154  // Value
155  if( ValueLengthField && bv )
156  {
157  // Self
158  assert( bv );
159  assert( bv->GetLength() == ValueLengthField );
160  if( !bv->Write<TSwap>(os) )
161  {
162  assert(0 && "Should not happen");
163  return os;
164  }
165  }
166  return os;
167  }
168 };
169 //-----------------------------------------------------------------------------
170 inline std::ostream &operator<<(std::ostream &os, const Fragment &val)
171 {
172  os << "Tag: " << val.TagField;
173  os << "\tVL: " << val.ValueLengthField;
174  if( val.ValueField )
175  {
176  os << "\t" << *(val.ValueField);
177  }
178 
179  return os;
180 }
181 
182 } // end namespace gdcm
183 
184 #endif //GDCMFRAGMENT_H

Generated on Mon Feb 18 2013 18:42:58 for GDCM by doxygen 1.8.3.1
SourceForge.net Logo