-2004-04-02 Jean-Pierre Roux
+2004-19-02 Jean-Pierre Roux
+ * ADD gdcmData/Wrist.pap (PAPYRUS 3.0 -single frame-) for checking purpose
+ * ENH add parameters :
+ bool exception_on_error = false,
+ bool enable_sequences = false,
+ bool ignore_shadow = false
+ to the gdcmFile constructors to be full gdcmParser compliant
+ * FIX vtk/vtkGdcmReader.cxx now uses enable_sequences = true in gdcmFile
+ to allow reading of PAPYRUS 3.0 files
+
+2004-06-02 Jean-Pierre Roux
* ADD gdcmData/E00001S03I0015.dcm for SQ checking purpose
2004-04-02 Jean-Pierre Roux
metaElem 0002 0010 "1.2.840.10008.1.2.1" // Transfer Syntax UID i.e. : Explicit VR - Little Endian
metaElem 0002 0012 "" // Implementation Class UID : may be forged later
metaElem 0002 0013 "gdcmLib " // Implementation Version Name don't remove trailing space !
+metaElem 0002 0016 " " // Source Application Entity Title (our ?)
metaElem 0004 1130 "" // File-set ID
metaElem 0004 1200 "0" // Offset of the first dir of root dir entity : to be computed later
metaElem 0004 1202 "0" // Offset of the last dir of root dir entity : to be computed later
metaElem 0004 1220 "123456879" // Directory record sequence : *length* to be set later
patientElem fffe e000 "0"
-patientElem 0004 1400 "0" // Offset of next directory record : to be computed later
-patientElem 0004 1410 "65535" // Record in use flag : 65535 ?
+patientElem 0004 1400 "0" // Offset of next directory record : = 0x0 : fffe e00d at end !
+patientElem 0004 1410 "65535" // Record in use flag : 65535 = 0xFFFF (see 03_10PU.PDF p 31)
patientElem 0004 1420 "0" // Offset of referenced lower-level dir entity : to be computed later
patientElem 0004 1430 "PATIENT " // Directory Record Type don't remove trailing space !
patientElem 0008 0005 "ISO_IR 100" // Specific Character Set
patientElem fffe e00d "0"
studyElem fffe e000 "0"
-studyElem 0004 1400 "0" // Offset of next directory record : to be computed later
-studyElem 0004 1410 "65535" // Record in use flag : 65535 ?
+studyElem 0004 1400 "0" // Offset of next directory record : = 0x0 : fffe e00d at end !
+studyElem 0004 1410 "65535" // Record in use flag : 65535 = 0xFFFF (see 03_10PU.PDF p 31)
studyElem 0004 1420 "0" // Offset of referenced lower-level dir entity : to be computed later
studyElem 0004 1430 "STUDY " // Directory Record Type don't remove trailing space !
studyElem 0008 0005 "ISO_IR 100" // Specific Character Set
studyElem 0008 0050 "" // Accession Number
studyElem 0008 1030 "" // Study Description
studyElem 0020 000d "" // Study Instance UID : may be forged later
-studyElem 0020 0010 "" // Study ID : may be forged later
+studyElem 0020 0010 "" // Study ID : may be forged later
studyElem fffe e00d "0"
serieElem fffe e000 "0"
-serieElem 0004 1400 "0" // Offset of next directory record : to be computed later
-serieElem 0004 1410 "65535" // Record in use flag : 65535 ?
+serieElem 0004 1400 "0" // Offset of next directory record : = 0x0 : fffe e00d at end !
+serieElem 0004 1410 "65535" // Record in use flag : 65535 = 0xFFFF (see 03_10PU.PDF p 31)
serieElem 0004 1420 "0" // Offset of referenced lower-level dir entity : to be computed later
serieElem 0004 1430 "SERIES" // Directory Record Type don't add trailing space !
serieElem 0008 0005 "ISO_IR 100" // Specific Character Set
serieElem 0008 0021 "" // Series Date
serieElem 0008 0031 "" // Series Time
serieElem 0008 0060 "" // Modality
-serieElem 0008 0080 "" // Institution Name : may be forged later
+serieElem 0008 0080 "" // Institution Name : may be forged later
serieElem 0008 0081 "" // Institution Address : may be forged later
serieElem 0008 103e "" // Series Description : may be forged later
serieElem 0020 000e "" // Series Instance UID : may be forged later
-serieElem 0020 0011 "0" // Series Number : may be forged later
+serieElem 0020 0011 "0" // Series Number : may be forged later
serieElem fffe e00d "0"
imageElem fffe e000 "0"
-imageElem 0004 1400 "0" // Offset of next directory record : to be computed later
-imageElem 0004 1410 "65535" // Record in use flag : 65535 ?
+imageElem 0004 1400 "0" // Offset of next directory record : = 0x0 : fffe e00d at end !
+imageElem 0004 1410 "65535" // Record in use flag : 65535 = 0xFFFF (see 03_10PU.PDF p 31)
imageElem 0004 1420 "0" // Offset of referenced lower-level dir entity : to be computed later
imageElem 0004 1430 "IMAGE " // Directory Record Type don't remove trailing space !
-imageElem 0004 1500 "" // Referenced File ID : to be set later = relative File Name
+imageElem 0004 1500 "" // Referenced File ID : will be set later = relative File Name
imageElem 0004 1510 "" // Referenced SOP Class UID in File : may be forged later
imageElem 0004 1511 "" // Referenced SOP Instance UID in File : may be forged later
imageElem 0004 1512 "" // Referenced Transfer Syntax in File
imageElem 0008 0005 "ISO_IR 100" // Specific Character Set
imageElem 0008 0008 "" // Image Type
-imageElem 0008 0016 "" // SOP Class UID : to be set/forged later
+imageElem 0008 0016 "" // SOP Class UID : to be set/forged later
imageElem 0008 0018 "" // SOP Instance UID : to be set/forged later
imageElem 0008 0023 "" // Content Date
imageElem 0008 0033 "" // Content Time
-imageElem 0008 1040 "" // Referenced Image Sequence : to be set/forged later
-imageElem 0008 1150 "" // Referenced SOP Class UID : to be set/forged later
+imageElem 0008 1040 "" // Referenced Image Sequence : to be set/forged later
+imageElem 0008 1150 "" // Referenced SOP Class UID : to be set/forged later
imageElem 0008 1155 "" // Referenced SOP Instance UID : to be set/forged later
imageElem 0020 0013 "0" // Image Number
imageElem 0020 0032 "1.0\1.0\1.0 " // Image Position Patient
0040 db0c UI PRC Template Extension Organization UID (RET)
0040 db0d UI PRC Template Extension Creator UID (RET)
0040 db73 UL PRC Referenced Content Item Identifier
+0041 1050 SQ ??? Special PAPYRUS 3.0 (?)
0050 0000 UL DEV Group Length
0050 0004 CS DEV Calibration Image
0050 0010 SQ DEV Device Sequence
# used. If set to NO the values of all tags below this one will be ignored.
SEARCHENGINE = NO
-
-# The CGI_NAME tag should be the name of the CGI script that
-# starts the search engine (doxysearch) with the correct parameters.
-# A script with this name will be generated by doxygen.
-
-CGI_NAME = search.cgi
-
-# The CGI_URL tag should be the absolute URL to the directory where the
-# cgi binaries are located. See the documentation of your http daemon for
-# details.
-
-CGI_URL =
-
-# The DOC_URL tag should be the absolute URL to the directory where the
-# documentation is located. If left blank the absolute path to the
-# documentation, with file:// prepended to it, will be used.
-
-DOC_URL =
-
-# The DOC_ABSPATH tag should be the absolute path to the directory where the
-# documentation is located. If left blank the directory on the local machine
-# will be used.
-
-DOC_ABSPATH =
-
-# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
-# is installed.
-
-BIN_ABSPATH = /usr/local/bin/
-
-# The EXT_DOC_PATHS tag can be used to specify one or more paths to
-# documentation generated for other projects. This allows doxysearch to search
-# the documentation for these projects as well.
-
-EXT_DOC_PATHS =
-gdcmVERSION="0.4"
+gdcmVERSION="0.4.1"
* seen as a side effect).
* @param filename file to be opened for parsing
*/
-gdcmFile::gdcmFile(std::string & filename) {
- Header=new gdcmHeader(filename.c_str());
+gdcmFile::gdcmFile(std::string & filename,
+ bool exception_on_error,
+ bool enable_sequences,
+ bool ignore_shadow) {
+ Header=new gdcmHeader(filename.c_str(),
+ exception_on_error,
+ enable_sequences,
+ ignore_shadow);
SelfHeader=true;
PixelRead=-1; // no ImageData read yet.
* seen as a side effect).
* @param filename file to be opened for parsing
*/
- gdcmFile::gdcmFile(const char * filename) {
- Header=new gdcmHeader(filename);
+ gdcmFile::gdcmFile(const char * filename,
+ bool exception_on_error,
+ bool enable_sequences,
+ bool ignore_shadow) {
+ Header=new gdcmHeader(filename,
+ exception_on_error,
+ enable_sequences,
+ ignore_shadow);
SelfHeader=true;
PixelRead=-1; // no ImageData read yet.
{
public:
gdcmFile(gdcmHeader *header);
- gdcmFile(std::string & filename);
- gdcmFile(const char * filename);
+ gdcmFile(std::string & filename,
+ bool exception_on_error = false,
+ bool enable_sequences = false,
+ bool skip_shadow = false);
+
+ gdcmFile(const char * filename,
+ bool exception_on_error = false,
+ bool enable_sequences = false,
+ bool skip_shadow = false);
+
virtual ~gdcmFile(void);
gdcmHeader *GetHeader(void);
//-----------------------------------------------------------------------------
// Public
+/**
+ * \ingroup gdcmHeaderEntry
+ * \brief Gets the full length of the HeaderEntry (not only value length)
+ */
+guint32 gdcmHeaderEntry::GetFullLength(void) {
+ guint32 l;
+ l = GetLength();
+ if ( IsImplicitVR() )
+ l = l + 8; // 2 (gr) + 2 (el) + 4 (lgth)
+ else
+ if ( GetVR()=="OB" || GetVR()=="OW" || GetVR()=="SQ" )
+ l = l + 12; // 2 (gr) + 2 (el) + 2 (vr) + 2 (unused) + 4 (lgth)
+ else
+ l = l + 8; // 2 (gr) + 2 (el) + 2 (vr) + 2 (lgth)
+ return(l);
+}
+
//-----------------------------------------------------------------------------
// Protected
*/
void SetPrintLevel(int level) { printLevel = level; };
void Print (std::ostream & os = std::cout);
-
+
+ guint32 GetFullLength(void);
+
private:
// FIXME: In fact we should be more specific and use :
// friend gdcmHeaderEntry * gdcmHeader::ReadNextElement(void);
return;
if (ParseHeader()) {
LoadHeaderEntries();
- }
+ }
CloseFile();
wasUpdated = 0; // will be set to 1 if user adds an entry
/**
* \ingroup gdcmParser
* \brief Prints the Header Entries (Dicom Elements)
- * both from the H Table and the chained list
+ * from the chained list
* @return
*/
void gdcmParser::PrintEntry(std::ostream & os) {
- std::ostringstream s;
for (ListTag::iterator i = listEntries.begin();
i != listEntries.end();
(*i)->SetPrintLevel(printLevel);
(*i)->Print(os);
}
- os<<s.str();
}
/**
- * \brief Prints The Dict Entries of THE public Dicom Dictionnry
+ * \ingroup gdcmParser
+ * \brief Prints the Header Entries (Dicom Elements)
+ * from the chained list
+ * and skips the elements belonging to a SeQuence
+ * @return
+ */
+void gdcmParser::PrintEntryNoSQ(std::ostream & os) {
+ int countSQ = 0;
+ for (ListTag::iterator i = listEntries.begin();
+ i != listEntries.end();
+ ++i)
+ {
+ if ( (*i)->GetVR() == "SQ"){
+ countSQ ++;
+ }
+
+ if ( (*i)->GetGroup() == 0xfffe && (*i)->GetElement() == 0xe0dd){
+ countSQ --;
+ continue;
+ }
+
+ if (countSQ == 0) {
+ (*i)->SetPrintLevel(printLevel);
+ (*i)->Print(os);
+ }
+ }
+}
+
+/**
+ * \ingroup gdcmParser
+ * \brief Prints the Header Entries (Dicom Elements)
+ * from the chained list
+ * and indents the elements belonging to a SeQuence
+ * @return
+ */
+void gdcmParser::PrintEntryNiceSQ(std::ostream & os) {
+ int countSQ = 0;
+ std::ostringstream tab;
+ tab << " ";
+ for (ListTag::iterator i = listEntries.begin();
+ i != listEntries.end();
+ ++i)
+ {
+ // we ignore '0 length' SeQuences
+ if ( (*i)->GetVR() == "SQ" && (*i)->GetReadLength()!=0){
+ countSQ ++;
+ }
+ // a SeQuence is over when a Sequence Delimiter Item is found
+ // pb : 'actual length' Sequence have NO Sequence Delimiter
+ // --> They 'never' finish : check the global length !
+ if ( (*i)->GetGroup() == 0xfffe && (*i)->GetElement() == 0xe0dd){
+ countSQ --;
+ continue;
+ }
+
+
+ if (countSQ != 0) {
+ for (int i=0;i<countSQ;i++)
+ os << tab.str();
+ }
+ (*i)->SetPrintLevel(printLevel);
+ (*i)->Print(os);
+ }
+}
+/**
+ * \brief Prints The Dict Entries of THE public Dicom Dictionary
* @return
*/
void gdcmParser::PrintPubDict(std::ostream & os) {
}
/**
- * \brief Prints The Dict Entries of THE shadow Dicom Dictionnary
+ * \brief Prints The Dict Entries of THE shadow Dicom Dictionary
* @return
*/
void gdcmParser::PrintShaDict(std::ostream & os) {
// since it's at the end of the Hash Table
// (fffe,e0dd)
- // pas SEQUENCE en ACR-NEMA
+ // there is SEQUENCE in ACR-NEMA
// WARNING :
// --> la descente a l'interieur' des SQ
// devrait etre faite avec une liste chainee, pas avec une HTable...
/// Canonical Printing method (see also gdcmParser::SetPrintLevel)
virtual void Print (std::ostream &os = std::cout)
{PrintEntry(os);};
- virtual void PrintEntry (std::ostream &os = std::cout);
+ virtual void PrintEntry (std::ostream &os = std::cout);
+ virtual void PrintEntryNoSQ (std::ostream &os = std::cout);
+ virtual void PrintEntryNiceSQ(std::ostream &os = std::cout);
+
virtual void PrintPubDict (std::ostream &os = std::cout);
virtual void PrintShaDict (std::ostream &os = std::cout);
continue;
}
fclose(fp);
-
+
+ cout << " Try to gdcmHeader ... " << endl;
// Stage 1.2: check for Gdcm parsability
- gdcmHeaderHelper GdcmHeader(FileName->c_str());
+ gdcmHeaderHelper GdcmHeader(FileName->c_str(), false, true);
+ // true : for enableSequences
if (!GdcmHeader.IsReadable())
{
vtkErrorMacro("Gdcm cannot parse file " << FileName->c_str());
const unsigned long UpdateProgressTarget,
unsigned long & UpdateProgressCount)
{
- vtkDebugMacro("Copying to memory image" << FileName.c_str());
- gdcmFile GdcmFile(FileName.c_str());
+ vtkDebugMacro("Copying to memory image [" << FileName.c_str() << "]");
+ gdcmFile GdcmFile(FileName.c_str(),false,true);
+ // true : to enable SeQuences
size_t size;
// If the data structure of vtk for image/volume representation
for(int i=1; i< argc; i++)
reader->AddFileName( argv[i] );
- //reader->DebugOn();
+ reader->DebugOn();
reader->Update();
//print debug info: