- {
- foundLength = 0;
- }
- }
-
- entry->SetUsableLength(foundLength);
-}
-
-/**
- * \brief Apply some heuristics to predict whether the considered
- * element value contains/represents an integer or not.
- * @param entry The element value on which to apply the predicate.
- * @return The result of the heuristical predicate.
- */
-bool Document::IsDocEntryAnInteger(DocEntry *entry)
-{
- uint16_t element = entry->GetElement();
- uint16_t group = entry->GetGroup();
- const std::string & vr = entry->GetVR();
- uint32_t length = entry->GetLength();
-
- // When we have some semantics on the element we just read, and if we
- // a priori know we are dealing with an integer, then we shall be
- // able to swap it's element value properly.
- if ( element == 0 ) // This is the group length of the group
- {
- if ( length == 4 )
- {
- return true;
- }
- else
- {
- // Allthough this should never happen, still some images have a
- // corrupted group length [e.g. have a glance at offset x(8336) of
- // gdcmData/gdcm-MR-PHILIPS-16-Multi-Seq.dcm].
- // Since for dicom compliant and well behaved headers, the present
- // test is useless (and might even look a bit paranoid), when we
- // encounter such an ill-formed image, we simply display a warning
- // message and proceed on parsing (while crossing fingers).
- std::ostringstream s;
- long filePosition = Fp->tellg();
- s << "Erroneous Group Length element length on : (" \
- << std::hex << group << " , " << element
- << ") -before- position x(" << filePosition << ")"
- << "lgt : " << length;
- dbg.Verbose(0, "Document::IsDocEntryAnInteger", s.str().c_str() );
- }
- }
-
- if ( vr == "UL" || vr == "US" || vr == "SL" || vr == "SS" )
- {
- return true;
- }
-
- return false;
-}
-
-/**
- * \brief Find the Length till the next sequence delimiter
- * \warning NOT end user intended method !
- * @return
- */
-
-uint32_t Document::FindDocEntryLengthOB()
- throw( FormatUnexpected )
-{
- // See PS 3.5-2001, section A.4 p. 49 on encapsulation of encoded pixel data.
- long positionOnEntry = Fp->tellg();
- bool foundSequenceDelimiter = false;
- uint32_t totalLength = 0;
-
- while ( !foundSequenceDelimiter )
- {
- uint16_t group;
- uint16_t elem;
- try
- {
- group = ReadInt16();
- elem = ReadInt16();
- }
- catch ( FormatError )
- {
- throw FormatError("Document::FindDocEntryLengthOB()",
- " group or element not present.");
- }
-
- // We have to decount the group and element we just read
- totalLength += 4;
-
- if ( group != 0xfffe || ( ( elem != 0xe0dd ) && ( elem != 0xe000 ) ) )
- {
- dbg.Verbose(1, "Document::FindDocEntryLengthOB: neither an Item "
- "tag nor a Sequence delimiter tag.");
- Fp->seekg(positionOnEntry, std::ios_base::beg);
- throw FormatUnexpected("Document::FindDocEntryLengthOB()",
- "Neither an Item tag nor a Sequence "
- "delimiter tag.");
- }
-
- if ( elem == 0xe0dd )
- {
- foundSequenceDelimiter = true;
- }
-
- uint32_t itemLength = ReadInt32();
- // We add 4 bytes since we just read the ItemLength with ReadInt32
- totalLength += itemLength + 4;
- SkipBytes(itemLength);
-
- if ( foundSequenceDelimiter )
- {
- break;
- }
- }
- Fp->seekg( positionOnEntry, std::ios_base::beg);
- return totalLength;
-}
-
-/**
- * \brief Reads a supposed to be 16 Bits integer
- * (swaps it depending on processor endianity)
- * @return read value
- */
-uint16_t Document::ReadInt16()
- throw( FormatError )
-{
- uint16_t g;
- Fp->read ((char*)&g, (size_t)2);
- if ( Fp->fail() )
- {
- throw FormatError( "Document::ReadInt16()", " file error." );
- }
- if( Fp->eof() )
- {
- throw FormatError( "Document::ReadInt16()", "EOF." );
- }
- g = SwapShort(g);
- return g;
-}
-
-/**
- * \brief Reads a supposed to be 32 Bits integer
- * (swaps it depending on processor endianity)
- * @return read value
- */
-uint32_t Document::ReadInt32()
- throw( FormatError )
-{
- uint32_t g;
- Fp->read ((char*)&g, (size_t)4);
- if ( Fp->fail() )
- {
- throw FormatError( "Document::ReadInt32()", " file error." );
- }
- if( Fp->eof() )
- {
- throw FormatError( "Document::ReadInt32()", "EOF." );
- }
- g = SwapLong(g);
- return g;
-}
-
-/**
- * \brief skips bytes inside the source file
- * \warning NOT end user intended method !
- * @return
- */
-void Document::SkipBytes(uint32_t nBytes)
-{
- //FIXME don't dump the returned value
- Fp->seekg((long)nBytes, std::ios_base::cur);