Program: gdcm
Module: $RCSfile: gdcmDocument.cxx,v $
Language: C++
- Date: $Date: 2004/10/06 09:58:08 $
- Version: $Revision: 1.93 $
+ Date: $Date: 2004/10/06 22:31:31 $
+ Version: $Revision: 1.96 $
Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
l'Image). All rights reserved. See Doc/License.txt or
long beg = ftell(Fp);
lgt -= beg;
- (void)ParseDES( this, beg, lgt, false); // le Load sera fait a la volee
+ ParseDES( this, beg, lgt, false); // le Load sera fait a la volee
rewind(Fp);
|| IsGivenTransferSyntax(UI1_2_840_10008_1_2_4_91) );
}
+/**
+ * \brief Determines if the Transfer Syntax corresponds to encapsulated
+ * of encoded Pixel Data (as opposed to native).
+ * @return True when encapsulated. False when native.
+ */
+bool gdcmDocument::IsEncapsulateTransferSyntax()
+{
+ return ( IsJPEGBaseLineProcess1TransferSyntax()
+ || IsJPEGExtendedProcess2_4TransferSyntax()
+ || IsJPEGExtendedProcess3_5TransferSyntax()
+ || IsJPEGSpectralSelectionProcess6_8TransferSyntax()
+ || IsRLELossLessTransferSyntax()
+ || IsJPEGLossless()
+ || IsJPEG2000() );
+}
+
/**
* \brief Predicate for dicom version 3 file.
* @return True when the file is a dicom version 3.
* \brief Parses a DocEntrySet (Zero-level DocEntries or SQ Item DocEntries)
* @return length of the parsed set.
*/
-
-long gdcmDocument::ParseDES(gdcmDocEntrySet *set,
+void gdcmDocument::ParseDES(gdcmDocEntrySet *set,
long offset,
long l_max,
bool delim_mode)
{
gdcmDocEntry *newDocEntry = 0;
- unsigned long l = 0;
while (true)
{
// form ( group, elem )...
if (gdcmDocument* dummy = dynamic_cast< gdcmDocument* > ( set ) )
{
- (void)dummy;
newBinEntry->SetKey( newBinEntry->GetKey() );
}
// but when "this" is a SQItem, we are inserting this new
if (newDocEntry->GetGroup() == 0x7fe0 &&
newDocEntry->GetElement() == 0x0010 )
{
- if ( newDocEntry->GetReadLength()==0xffffffff )
+ if ( IsRLELossLessTransferSyntax() )
{
- // Broken US.3405.1.dcm
- Parse7FE0(); // to skip the pixels
- // (multipart JPEG/RLE are trouble makers)
+ long PositionOnEntry = ftell(Fp);
+ fseek(Fp, newDocEntry->GetOffset(), SEEK_SET);
+ ComputeRLEInfo();
+ fseek(Fp, PositionOnEntry, SEEK_SET);
}
else
{
SkipToNextDocEntry(newDocEntry);
- l = newDocEntry->GetFullLength();
}
}
else
{
// to be sure we are at the beginning
SkipToNextDocEntry(newDocEntry);
- l = newDocEntry->GetFullLength();
}
}
else
{
// VR = "SQ"
- l = newDocEntry->GetReadLength();
+ unsigned long l = newDocEntry->GetReadLength();
if ( l != 0 ) // don't mess the delim_mode for zero-length sequence
{
if ( l == 0xffffffff )
if ( l != 0 )
{ // Don't try to parse zero-length sequences
- (void)ParseSQ( newSeqEntry,
- newDocEntry->GetOffset(),
- l, delim_mode);
+ ParseSQ( newSeqEntry,
+ newDocEntry->GetOffset(),
+ l, delim_mode);
}
set->AddEntry( newSeqEntry );
if ( !delim_mode && (ftell(Fp)-offset) >= l_max)
}
delete newDocEntry;
}
- return l; // Probably useless
}
/**
* \brief Parses a Sequence ( SeqEntry after SeqEntry)
* @return parsed length for this level
*/
-long gdcmDocument::ParseSQ( gdcmSeqEntry* seqEntry,
+void gdcmDocument::ParseSQ( gdcmSeqEntry* seqEntry,
long offset, long l_max, bool delim_mode)
{
int SQItemNumber = 0;
dlm_mod = false;
}
- (void)ParseDES(itemSQ, newDocEntry->GetOffset(), l, dlm_mod);
+ ParseDES(itemSQ, newDocEntry->GetOffset(), l, dlm_mod);
seqEntry->AddEntry( itemSQ, SQItemNumber );
SQItemNumber++;
break;
}
}
-
- int lgth = ftell(Fp) - offset;
- return lgth;
}
/**
fseek(Fp, 2L, SEEK_CUR);
uint32_t length32 = ReadInt32();
- if ( vr == "OB" && length32 == 0xffffffff )
+ if ( (vr == "OB" || vr == "OW") && length32 == 0xffffffff )
{
uint32_t lengthOB;
try
{
+ /// \todo rename that to FindDocEntryLengthOBOrOW since
+ /// the above test is on both OB and OW...
lengthOB = FindDocEntryLengthOB();
}
catch ( gdcmFormatUnexpected )
}
/**
- * \brief Parse pixel data from disk for multi-fragment Jpeg/Rle files
- * No other way so 'skip' the Data
+ * \brief Parse pixel data from disk of [multi-]fragment RLE encoding.
+ * Compute the RLE extra information and store it in \ref RLEInfo
+ * for later pixel retrieval usage.
*/
-void gdcmDocument::Parse7FE0 ()
+void gdcmDocument::ComputeRLEInfo()
{
- gdcmDocEntry* element = GetDocEntryByNumber(0x0002, 0x0010);
- if ( !element )
- {
- // Should warn user FIXME
- return;
- }
-
- if ( IsImplicitVRLittleEndianTransferSyntax()
- || IsExplicitVRLittleEndianTransferSyntax()
- || IsExplicitVRBigEndianTransferSyntax() /// \todo 1.2.2 ??? A verifier !
- || IsDeflatedExplicitVRLittleEndianTransferSyntax() )
+ if ( ! IsRLELossLessTransferSyntax() )
{
return;
}
-
// Encoded pixel data: for the time being we are only concerned with
// Jpeg or RLE Pixel data encodings.
// As stated in ps-3.3, 8.2:
- // "If sent in Encapsulated Format (i.e. other than the Narive Format) the
+ // "If sent in Encapsulated Format (i.e. other than the Native Format) the
// value representation OB is used".
// Hence we expect an OB value representation. Concerning OB VR,
// the section PS3.3, A.4.c (p58 and p59), states:
// we can't rely on it for the implementation, and we will simply
// trash it's content (when present).
// - still, when present, we could add some further checks on the
- // lengths, but not bother with such fuses for the time being.
+ // lengths, but we won't bother with such fuses for the time being.
if ( itemLength != 0 )
{
char* basicOffsetTableItemValue = new char[itemLength + 1];
std::ostringstream s;
s << " Read one length: ";
s << std::hex << individualLength << std::endl;
- dbg.Verbose(0, "gdcmDocument::Parse7FE0: ", s.str().c_str());
+ dbg.Verbose(0, "gdcmDocument::ComputeRLEInfo: ", s.str().c_str());
}
delete[] basicOffsetTableItemValue;
}
- if ( ! IsRLELossLessTransferSyntax() )
- {
- // JPEG Image
-
- //// We then skip (not reading them) all the fragments of images:
- while ( (itemLength = ReadTagLength(0xfffe, 0xe000)) )
+ // Encapsulated RLE Compressed Images (see PS-3.3, Annex G).
+ // Loop on the frame[s] and store the parsed information in a
+ // gdcmRLEFramesInfo.
+ long frameLength;
+
+ // Loop on the individual frame[s] and store the information
+ // on the RLE fragments in a gdcmRLEFramesInfo.
+ // Note: - when only a single frame is present, this is a
+ // classical image.
+ // - when more than one frame are present, then we are in
+ // the case of a multi-frame image.
+ while ( (frameLength = ReadTagLength(0xfffe, 0xe000)) )
+ {
+ // Parse the RLE Header and store the corresponding RLE Segment
+ // Offset Table information on fragments of this current Frame.
+ // Note that the fragment pixels themselves are not loaded
+ // (but just skipped).
+ long frameOffset = ftell(Fp);
+
+ uint32_t nbRleSegments = ReadInt32();
+
+ uint32_t rleSegmentOffsetTable[15];
+ for( int k = 1; k <= 15; k++ )
{
- SkipBytes(itemLength);
+ rleSegmentOffsetTable[k] = ReadInt32();
}
- }
- else
- {
- // Encapsulated RLE Compressed Images (see PS-3.3, Annex G).
- // Loop on the frame[s] and store the parsed information in a
- // gdcmRLEFramesInfo.
- long frameLength;
-
- // Loop on the individual frame[s] and store the information
- // on the RLE fragments in a gdcmRLEFramesInfo.
- // Note: - when only a single frame is present, this is a
- // classical image.
- // - when more than one frame are present, then we are in
- // the case of a multi-frame image.
- while ( (frameLength = ReadTagLength(0xfffe, 0xe000)) )
- {
- // Parse the RLE Header and store the corresponding RLE Segment
- // Offset Table information on fragments of this current Frame.
- // Note that the fragment pixels themselves are not loaded
- // (but just skipped).
- uint32_t nbRleSegments = ReadInt32();
-
- uint32_t rleSegmentOffsetTable[15];
- long ftellRes;
- for( int k = 1; k <= 15; k++ )
- {
- ftellRes = ftell(Fp);
- rleSegmentOffsetTable[k] = ReadInt32();
- }
- // Deduce from both the RLE Header and the frameLength the
- // fragment length, and again store this infor in a
- // gdcmRLEFramesInfo.
- long rleSegmentLength[15];
- // skipping (not reading) RLE Segments
- if ( nbRleSegments > 1)
+ // Deduce from both the RLE Header and the frameLength the
+ // fragment length, and again store this info in a
+ // gdcmRLEFramesInfo.
+ long rleSegmentLength[15];
+ // skipping (not reading) RLE Segments
+ if ( nbRleSegments > 1)
+ {
+ for(unsigned int k = 1; k <= nbRleSegments-1; k++)
{
- for(unsigned int k = 1; k <= nbRleSegments-1; k++)
- {
- rleSegmentLength[k] = rleSegmentOffsetTable[k+1]
- - rleSegmentOffsetTable[k];
- ftellRes = ftell(Fp);
- SkipBytes(rleSegmentLength[k]);
- }
+ rleSegmentLength[k] = rleSegmentOffsetTable[k+1]
+ - rleSegmentOffsetTable[k];
+ SkipBytes(rleSegmentLength[k]);
}
+ }
- rleSegmentLength[nbRleSegments] = frameLength
- - rleSegmentOffsetTable[nbRleSegments];
- ftellRes = ftell(Fp);
- SkipBytes(rleSegmentLength[nbRleSegments]);
-
- // Store the collected info
- gdcmRLEFrame* newFrameInfo = new gdcmRLEFrame;
- newFrameInfo->NumberFragments = nbRleSegments;
- for( unsigned int k = 1; k <= nbRleSegments; k++ )
- {
- newFrameInfo->Offset[k] = rleSegmentOffsetTable[k];
- newFrameInfo->Length[k] = rleSegmentLength[k];
- }
- RLEInfo.Frames.push_back( newFrameInfo );
- }
+ rleSegmentLength[nbRleSegments] = frameLength
+ - rleSegmentOffsetTable[nbRleSegments];
+ SkipBytes(rleSegmentLength[nbRleSegments]);
- // Make sure that at the end of the item we encounter a 'Sequence
- // Delimiter Item':
- if ( !ReadTag(0xfffe, 0xe0dd) )
- {
- dbg.Verbose(0, "gdcmDocument::Parse7FE0: no sequence delimiter item");
- dbg.Verbose(0, " at end of RLE item sequence");
- }
+ // Store the collected info
+ gdcmRLEFrame* newFrameInfo = new gdcmRLEFrame;
+ newFrameInfo->NumberFragments = nbRleSegments;
+ for( unsigned int k = 1; k <= nbRleSegments; k++ )
+ {
+ newFrameInfo->Offset[k] = frameOffset + rleSegmentOffsetTable[k];
+ newFrameInfo->Length[k] = rleSegmentLength[k];
+ }
+ RLEInfo.Frames.push_back( newFrameInfo );
+ }
+
+ // Make sure that at the end of the item we encounter a 'Sequence
+ // Delimiter Item':
+ if ( !ReadTag(0xfffe, 0xe0dd) )
+ {
+ dbg.Verbose(0, "gdcmDocument::ComputeRLEInfo: no sequence delimiter ");
+ dbg.Verbose(0, " item at end of RLE item sequence");
}
}