X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmDocument.cxx;h=ba76c1e9f79fbc89914956dcda9d7170a925f675;hb=1bae8d2ba47d1b9cc8acfb7b5ab82026e48275dd;hp=683491dc27d5a239ec4c82d39e95660f29a7e210;hpb=dc2846f4750cf09f08d5f356792b8a12f2a97a2f;p=gdcm.git diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 683491dc..ba76c1e9 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.cxx,v $ Language: C++ - Date: $Date: 2004/11/16 17:31:39 $ - Version: $Revision: 1.131 $ + Date: $Date: 2004/11/25 15:46:11 $ + Version: $Revision: 1.140 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -36,39 +36,6 @@ namespace gdcm { -static const char *TransferSyntaxStrings[] = { - // Implicit VR Little Endian - "1.2.840.10008.1.2", - // Explicit VR Little Endian - "1.2.840.10008.1.2.1", - // Deflated Explicit VR Little Endian - "1.2.840.10008.1.2.1.99", - // Explicit VR Big Endian - "1.2.840.10008.1.2.2", - // JPEG Baseline (Process 1) - "1.2.840.10008.1.2.4.50", - // JPEG Extended (Process 2 & 4) - "1.2.840.10008.1.2.4.51", - // JPEG Extended (Process 3 & 5) - "1.2.840.10008.1.2.4.52", - // JPEG Spectral Selection, Non-Hierarchical (Process 6 & 8) - "1.2.840.10008.1.2.4.53", - // JPEG Full Progression, Non-Hierarchical (Process 10 & 12) - "1.2.840.10008.1.2.4.55", - // JPEG Lossless, Non-Hierarchical (Process 14) - "1.2.840.10008.1.2.4.57", - // JPEG Lossless, Hierarchical, First-Order Prediction (Process 14, [Selection Value 1]) - "1.2.840.10008.1.2.4.70", - // JPEG 2000 Lossless - "1.2.840.10008.1.2.4.90", - // JPEG 2000 - "1.2.840.10008.1.2.4.91", - // RLE Lossless - "1.2.840.10008.1.2.5", - // Unknown - "Unknown Transfer Syntax" -}; - //----------------------------------------------------------------------------- // Refer to Document::CheckSwap() const unsigned int Document::HEADER_LENGTH_TO_READ = 256; @@ -479,41 +446,22 @@ bool Document::CloseFile() * (ACR-NEMA, ExplicitVR, ImplicitVR) * \return Always true. */ -void Document::Write(std::ofstream* fp, FileType filetype) +void Document::WriteContent(std::ofstream* fp, FileType filetype) { /// \todo move the following lines (and a lot of others, to be written) /// to a future function CheckAndCorrectHeader /// (necessary if user wants to write a DICOM V3 file /// starting from an ACR-NEMA (V2) Header - if (filetype == ImplicitVR) - { - std::string ts = - Util::DicomString( TransferSyntaxStrings[ImplicitVRLittleEndian] ); - ReplaceOrCreateByNumber(ts, 0x0002, 0x0010); - - /// \todo Refer to standards on page 21, chapter 6.2 - /// "Value representation": values with a VR of UI shall be - /// padded with a single trailing null - /// in the following case we have to padd manually with a 0 - - SetEntryLengthByNumber(18, 0x0002, 0x0010); - } - - if (filetype == ExplicitVR) + if ( filetype == ImplicitVR || filetype == ExplicitVR ) { - std::string ts = - Util::DicomString( TransferSyntaxStrings[ExplicitVRLittleEndian] ); - ReplaceOrCreateByNumber(ts, 0x0002, 0x0010); //LEAK - - /// \todo Refer to standards on page 21, chapter 6.2 - /// "Value representation": values with a VR of UI shall be - /// padded with a single trailing null - /// Dans le cas suivant on doit pader manuellement avec un 0 - - SetEntryLengthByNumber(20, 0x0002, 0x0010); + // writing Dicom File Preamble + char filePreamble[128]; + memset(filePreamble, 0, 128); + fp->write(filePreamble, 128); + fp->write("DICM", 4); } - + /** * \todo rewrite later, if really usefull * - 'Group Length' element is optional in DICOM @@ -526,8 +474,7 @@ void Document::Write(std::ofstream* fp, FileType filetype) * UpdateGroupLength(true,ACR); */ - ElementSet::Write(fp, filetype); // This one is recursive - + ElementSet::WriteContent(fp, filetype); // This one is recursive } /** @@ -619,6 +566,7 @@ ValEntry* Document::ReplaceOrCreateByNumber( /* * \brief Modifies the value of a given Header Entry (Dicom Element) * when it exists. Create it with the given value when unexistant. + * A copy of the binArea is made to be kept in the Document. * @param binArea (binary) value to be set * @param Group Group number of the Entry * @param Elem Element number of the Entry @@ -690,7 +638,23 @@ BinEntry* Document::ReplaceOrCreateByNumber( } } - SetEntryByNumber(binArea, lgth, group, elem); + uint8_t *tmpArea; + if (lgth>0 && binArea) + { + tmpArea = new uint8_t[lgth]; + memcpy(tmpArea,binArea,lgth); + } + else + { + tmpArea = 0; + } + if (!SetEntryByNumber(tmpArea, lgth, group, elem)) + { + if (tmpArea) + { + delete[] tmpArea; + } + } return binEntry; } @@ -1046,7 +1010,12 @@ void Document::LoadEntryBinArea(uint16_t group, uint16_t elem) if ( !docElement ) return; - size_t o =(size_t)docElement->GetOffset(); + BinEntry *binElement = dynamic_cast(docElement); + if( !binElement ) + return; + + LoadEntryBinArea(binElement); +/* size_t o =(size_t)docElement->GetOffset(); Fp->seekg( o, std::ios_base::beg); size_t l = docElement->GetLength(); uint8_t* a = new uint8_t[l]; @@ -1069,8 +1038,9 @@ void Document::LoadEntryBinArea(uint16_t group, uint16_t elem) { delete[] a; dbg.Verbose(0, "Document::LoadEntryBinArea setting failed."); - } + }*/ } + /** * \brief Loads (from disk) the element content * when a string is not suitable @@ -1078,8 +1048,16 @@ void Document::LoadEntryBinArea(uint16_t group, uint16_t elem) */ void Document::LoadEntryBinArea(BinEntry* element) { + if(element->GetBinArea()) + return; + + bool openFile = !Fp; + if(openFile) + OpenFile(); + size_t o =(size_t)element->GetOffset(); Fp->seekg(o, std::ios_base::beg); + size_t l = element->GetLength(); uint8_t* a = new uint8_t[l]; if( !a ) @@ -1097,6 +1075,9 @@ void Document::LoadEntryBinArea(BinEntry* element) } element->SetBinArea(a); + + if(openFile) + CloseFile(); } /** @@ -1241,9 +1222,12 @@ ValEntry* Document::GetValEntryByNumber(uint16_t group, uint16_t element) */ void Document::LoadDocEntrySafe(DocEntry * entry) { - long PositionOnEntry = Fp->tellg(); - LoadDocEntry(entry); - Fp->seekg(PositionOnEntry, std::ios_base::beg); + if(Fp) + { + long PositionOnEntry = Fp->tellg(); + LoadDocEntry(entry); + Fp->seekg(PositionOnEntry, std::ios_base::beg); + } } /** @@ -1320,10 +1304,10 @@ void Document::ParseDES(DocEntrySet *set, long offset, long l_max, bool delim_mode) { DocEntry *newDocEntry = 0; - + while (true) - { - if ( !delim_mode && (Fp->tellg()-offset) >= l_max) + { + if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) { break; } @@ -1370,10 +1354,12 @@ void Document::ParseDES(DocEntrySet *set, long offset, if (delimitor) { + delete newDocEntry; break; } - if ( !delim_mode && (Fp->tellg()-offset) >= l_max) + if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) { + delete newDocEntry; break; } } @@ -1387,9 +1373,6 @@ void Document::ParseDES(DocEntrySet *set, long offset, } //////////////////// BinEntry or UNKOWN VR: -/* BinEntry* newBinEntry = - new BinEntry( newDocEntry->GetDictEntry() ); //LEAK - newBinEntry->Copy( newDocEntry );*/ BinEntry* newBinEntry = new BinEntry( newDocEntry ); //LEAK // When "this" is a Document the Key is simply of the @@ -1438,6 +1421,7 @@ void Document::ParseDES(DocEntrySet *set, long offset, // Just to make sure we are at the beginning of next entry. SkipToNextDocEntry(newDocEntry); + //delete newDocEntry; } else { @@ -1487,8 +1471,9 @@ void Document::ParseDES(DocEntrySet *set, long offset, l, delim_mode); } set->AddEntry( newSeqEntry ); - if ( !delim_mode && (Fp->tellg()-offset) >= l_max) + if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) { + delete newDocEntry; break; } } @@ -1518,13 +1503,14 @@ void Document::ParseSQ( SeqEntry* seqEntry, { if ( newDocEntry->IsSequenceDelimitor() ) { - seqEntry->SetSequenceDelimitationItem( newDocEntry ); + seqEntry->SetSequenceDelimitationItem( newDocEntry ); break; } } - if ( !delim_mode && (Fp->tellg()-offset) >= l_max) + if ( !delim_mode && ((long)(Fp->tellg())-offset) >= l_max) { - break; + delete newDocEntry; + break; } SQItem *itemSQ = new SQItem( seqEntry->GetDepthLevel() ); @@ -1546,10 +1532,11 @@ void Document::ParseSQ( SeqEntry* seqEntry, } ParseDES(itemSQ, newDocEntry->GetOffset(), l, dlm_mod); + delete newDocEntry; seqEntry->AddEntry( itemSQ, SQItemNumber ); SQItemNumber++; - if ( !delim_mode && ( Fp->tellg() - offset ) >= l_max ) + if ( !delim_mode && ((long)(Fp->tellg())-offset ) >= l_max ) { break; } @@ -1770,7 +1757,7 @@ void Document::FindDocEntryLength( DocEntry *entry ) // the length and proceed. long currentPosition = Fp->tellg(); Fp->seekg(0L,std::ios_base::end); - long lengthUntilEOF = Fp->tellg() - currentPosition; + long lengthUntilEOF = (long)(Fp->tellg())-currentPosition; Fp->seekg(currentPosition, std::ios_base::beg); entry->SetLength(lengthUntilEOF); return; @@ -2515,7 +2502,7 @@ bool Document::CheckSwap() // representation of a 32 bits integer. Hence the following dirty // trick : s32 = *((uint32_t *)(entCur)); - + switch( s32 ) { case 0x00040000 : @@ -2592,6 +2579,7 @@ bool Document::CheckSwap() } + /** * \brief Restore the unproperly loaded values i.e. the group, the element * and the dictionary entry depending on them. @@ -3083,7 +3071,7 @@ void Document::BuildFlatHashTableRecurse( TagDocEntryHT& builtHT, * Document. * * The structure used by a Document (through \ref ElementSet), - * in order to old the parsed entries of a Dicom header, is a recursive + * in order to hold the parsed entries of a Dicom header, is a recursive * one. This is due to the fact that the sequences (when present) * can be nested. Additionaly, the sequence items (represented in * gdcm as \ref SQItem) add an extra complexity to the data