X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmDocument.cxx;h=6080c6efacdc4a04216473e9e0050088582034de;hb=00b6e0ddcbdbd41252e03732783f65efe5f52526;hp=43f9b0a199eb97a473651f644d3b2a25dcb4a47e;hpb=934741ba56fd719a775e93cc93616c25b3d10901;p=gdcm.git diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 43f9b0a1..6080c6ef 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/06/23 09:30:22 $ - Version: $Revision: 1.26 $ + Date: $Date: 2004/06/25 19:37:05 $ + Version: $Revision: 1.35 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -74,9 +74,9 @@ const unsigned int gdcmDocument::HEADER_LENGTH_TO_READ = 256; // Refer to gdcmDocument::SetMaxSizeLoadEntry() -const unsigned int gdcmDocument::MAX_SIZE_LOAD_ELEMENT_VALUE = 4096; +const unsigned int gdcmDocument::MAX_SIZE_LOAD_ELEMENT_VALUE = 0x7fffffff;// 4096; -const unsigned int gdcmDocument::MAX_SIZE_PRINT_ELEMENT_VALUE = 64; +const unsigned int gdcmDocument::MAX_SIZE_PRINT_ELEMENT_VALUE = 0x7fffffff;//64; //----------------------------------------------------------------------------- // Constructor / Destructor @@ -126,8 +126,8 @@ gdcmDocument::gdcmDocument(std::string const & inFilename, long l=ParseDES( this, beg, lgt, false); // le Load sera fait a la volee (void)l; //is l used anywhere ? - - rewind(fp); + + rewind(fp); // Load 'non string' values @@ -144,7 +144,7 @@ gdcmDocument::gdcmDocument(std::string const & inFilename, } //FIXME later : how to use it? LoadEntryVoidArea(0x0028,0x3006); //LUT Data (CTX dependent) - + CloseFile(); // -------------------------------------------------------------- @@ -225,14 +225,14 @@ void gdcmDocument::PrintShaDict(std::ostream & os) { * \brief Get the public dictionary used */ gdcmDict *gdcmDocument::GetPubDict(void) { - return(RefPubDict); + return RefPubDict; } /** * \brief Get the shadow dictionary used */ gdcmDict *gdcmDocument::GetShaDict(void) { - return(RefShaDict); + return RefShaDict; } /** @@ -241,7 +241,7 @@ gdcmDict *gdcmDocument::GetShaDict(void) { */ bool gdcmDocument::SetShaDict(gdcmDict *dict){ RefShaDict=dict; - return(!RefShaDict); + return !RefShaDict; } /** @@ -250,7 +250,7 @@ bool gdcmDocument::SetShaDict(gdcmDict *dict){ */ bool gdcmDocument::SetShaDict(DictKey dictName){ RefShaDict=gdcmGlobal::GetDicts()->GetDict(dictName); - return(!RefShaDict); + return !RefShaDict; } /** @@ -264,12 +264,12 @@ bool gdcmDocument::SetShaDict(DictKey dictName){ bool gdcmDocument::IsReadable(void) { if(Filetype==gdcmUnknown) { dbg.Verbose(0, "gdcmDocument::IsReadable: wrong filetype"); - return(false); + return false; } if(!tagHT.empty()<=0) { dbg.Verbose(0, "gdcmDocument::IsReadable: no tags in internal" " hash table."); - return(false); + return false; } return(true); @@ -414,7 +414,7 @@ bool gdcmDocument::IsJPEGLossless(void) { return ( IsGivenTransferSyntax(UI1_2_840_10008_1_2_4_55) || IsGivenTransferSyntax(UI1_2_840_10008_1_2_4_57) - || IsGivenTransferSyntax(UI1_2_840_10008_1_2_4_70) ); // was 90 + || IsGivenTransferSyntax(UI1_2_840_10008_1_2_4_70) ); } /** @@ -516,8 +516,8 @@ bool gdcmDocument::CloseFile(void) { * (ACR-NEMA, ExplicitVR, ImplicitVR) * \return Always true. */ -bool gdcmDocument::WriteF(FileType filetype) { -/// \todo +void gdcmDocument::Write(FILE* fp,FileType filetype) { +/// /// ============== /// The stuff is rewritten using the SeQuence based /// tree-like stucture (cf : Print ) @@ -530,8 +530,8 @@ bool gdcmDocument::WriteF(FileType filetype) { /// WARNING : Si on veut ecrire du DICOM V3 a partir d'un DcmHeader ACR-NEMA /// no way (check : FileType est un champ de gdcmDocument ...) /// a moins de se livrer a un tres complique ajout des champs manquants. - /// faire un CheckAndCorrectHeader (?) - + /// faire un CheckAndCorrectHeader (?) + if (filetype == gdcmImplicitVR) { std::string implicitVRTransfertSyntax = UI1_2_840_10008_1_2; @@ -572,10 +572,9 @@ bool gdcmDocument::WriteF(FileType filetype) { * UpdateGroupLength(true,ACR); */ - Write(fp,filetype); // the gdcmElementSet one ! + gdcmElementSet::Write(fp,filetype); - /// WriteEntries(fp,type); // old stuff - return true; + // return true; } /** @@ -657,7 +656,7 @@ gdcmBinEntry * gdcmDocument::ReplaceOrCreateByNumber( guint16 Elem) { gdcmDocEntry* a; - gdcmBinEntry* b; + gdcmBinEntry* b = 0; a = GetDocEntryByNumber( Group, Elem); if (a == NULL) { a =NewBinEntryByNumber(Group, Elem); @@ -968,7 +967,31 @@ void *gdcmDocument::LoadEntryVoidArea(guint16 Group, guint16 Elem) delete[] a; return NULL; } - + return a; +} +/** + * \brief Loads (from disk) the element content + * when a string is not suitable + * @param Element Entry whose voidArea is going to be loaded + */ +void *gdcmDocument::LoadEntryVoidArea(gdcmBinEntry *Element) +{ + size_t o =(size_t)Element->GetOffset(); + fseek(fp, o, SEEK_SET); + size_t l = Element->GetLength(); + char* a = new char[l]; + if(!a) { + dbg.Verbose(0, "gdcmDocument::LoadEntryVoidArea cannot allocate a"); + return NULL; + } + Element->SetVoidArea((void *)a); + /// \todo check the result + size_t l2 = fread(a, 1, l ,fp); + if(l != l2) + { + delete[] a; + return NULL; + } return a; } @@ -1066,7 +1089,7 @@ void gdcmDocument::UpdateShaEntries(void) { */ gdcmDocEntry* gdcmDocument::GetDocEntryByNumber(guint16 group, guint16 element) { - TagKey key = gdcmDictEntry::TranslateToKey(group, element); + TagKey key = gdcmDictEntry::TranslateToKey(group, element); if ( ! tagHT.count(key)) return NULL; return tagHT.find(key)->second; @@ -1130,7 +1153,7 @@ guint32 gdcmDocument::SwapLong(guint32 a) { dbg.Error(" gdcmDocument::SwapLong : unset swap code"); a=0; } - return(a); + return a; } /** @@ -1139,7 +1162,7 @@ guint32 gdcmDocument::SwapLong(guint32 a) { * @return The properly unswaped 32 bits integer. */ guint32 gdcmDocument::UnswapLong(guint32 a) { - return (SwapLong(a)); + return SwapLong(a); } /** @@ -1149,7 +1172,7 @@ guint32 gdcmDocument::UnswapLong(guint32 a) { guint16 gdcmDocument::SwapShort(guint16 a) { if ( (sw==4321) || (sw==2143) ) a =(((a<<8) & 0x0ff00) | ((a>>8)&0x00ff)); - return (a); + return a; } /** @@ -1157,7 +1180,7 @@ guint16 gdcmDocument::SwapShort(guint16 a) { * @return The properly unswaped 16 bits integer. */ guint16 gdcmDocument::UnswapShort(guint16 a) { - return (SwapShort(a)); + return SwapShort(a); } //----------------------------------------------------------------------------- @@ -1175,7 +1198,7 @@ long gdcmDocument::ParseDES(gdcmDocEntrySet *set, long offset, long l_max, bool gdcmBinEntry *bn; gdcmSeqEntry *sq; VRKey vr; - unsigned long l; + unsigned long l = 0; int depth; depth = set->GetDepthLevel(); @@ -1226,10 +1249,17 @@ long gdcmDocument::ParseDES(gdcmDocEntrySet *set, long offset, long l_max, bool if (NewDocEntry->GetGroup() == 0x7fe0 && NewDocEntry->GetElement() == 0x0010 ) { - if (NewDocEntry->GetLength()==0xffffffff) + if (NewDocEntry->GetReadLength()==0xffffffff) + { // Broken US.3405.1.dcm Parse7FE0(); // to skip the pixels // (multipart JPEG/RLE are trouble makers) + } + else + { + SkipToNextDocEntry(NewDocEntry); + l = NewDocEntry->GetFullLength(); + } } else { @@ -1261,7 +1291,6 @@ long gdcmDocument::ParseDES(gdcmDocEntrySet *set, long offset, long l_max, bool l, delim_mode); (void)lgt; //not used... } - // FIXME : on en fait quoi, de lgt ? set->AddEntry(sq); if ( !delim_mode && ftell(fp)-offset >= l_max) { @@ -1270,7 +1299,7 @@ long gdcmDocument::ParseDES(gdcmDocEntrySet *set, long offset, long l_max, bool } delete NewDocEntry; } - return l; // ?? + return l; // Probably useless } /** @@ -1291,7 +1320,10 @@ long gdcmDocument::ParseSQ(gdcmSeqEntry *set, (void)depth; //not used while (true) { + NewDocEntry = ReadNextDocEntry(); + if (!NewDocEntry) + break; if(delim_mode) { if (NewDocEntry->isSequenceDelimitor()) { set->SetSequenceDelimitationItem(NewDocEntry); @@ -1320,7 +1352,7 @@ long gdcmDocument::ParseSQ(gdcmSeqEntry *set, } } lgth = ftell(fp) - offset; - return(lgth); + return lgth; } /** @@ -1355,11 +1387,11 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry *Entry) // The elements whose length is bigger than the specified upper bound // are not loaded. Instead we leave a short notice of the offset of // the element content and it's length. - + + std::ostringstream s; if (length > MaxSizeLoadEntry) { if (gdcmBinEntry* BinEntryPtr = dynamic_cast< gdcmBinEntry* >(Entry) ) - { - std::ostringstream s; + { s << "gdcm::NotLoaded (BinEntry)"; s << " Address:" << (long)Entry->GetOffset(); s << " Length:" << Entry->GetLength(); @@ -1368,17 +1400,16 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry *Entry) } // to be sure we are at the end of the value ... fseek(fp,(long)Entry->GetOffset()+(long)Entry->GetLength(),SEEK_SET); - return; - // Be carefull : a BinEntry IS_A ValEntry ... + return; + // Be carefull : a BinEntry IS_A ValEntry ... if (gdcmValEntry* ValEntryPtr = dynamic_cast< gdcmValEntry* >(Entry) ) { - std::ostringstream s; s << "gdcm::NotLoaded. (ValEntry)"; s << " Address:" << (long)Entry->GetOffset(); s << " Length:" << Entry->GetLength(); s << " x(" << std::hex << Entry->GetLength() << ")"; ValEntryPtr->SetValue(s.str()); - } + } // to be sure we are at the end of the value ... fseek(fp,(long)Entry->GetOffset()+(long)Entry->GetLength(),SEEK_SET); return; @@ -1386,9 +1417,12 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry *Entry) // When we find a BinEntry not very much can be done : if (gdcmBinEntry* BinEntryPtr = dynamic_cast< gdcmBinEntry* >(Entry) ) { - LoadEntryVoidArea (BinEntryPtr->GetGroup(),BinEntryPtr->GetElement()); - return; - } + + LoadEntryVoidArea(BinEntryPtr); + s << "gdcm::Loaded (BinEntry)"; + BinEntryPtr->SetValue(s.str()); + return; + } // Any compacter code suggested (?) @@ -1439,16 +1473,22 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry *Entry) // We need an additional byte for storing \0 that is not on disk std::string NewValue(length,0); item_read = fread(&(NewValue[0]), (size_t)length, (size_t)1, fp); - if ( item_read != 1 ) { - dbg.Verbose(1, "gdcmDocument::LoadElementValue","unread element value"); - ((gdcmValEntry *)Entry)->SetValue("gdcm::UnRead"); - return; + if (gdcmValEntry* ValEntry = dynamic_cast< gdcmValEntry* >(Entry) ) { + if ( item_read != 1 ) { + dbg.Verbose(1, "gdcmDocument::LoadElementValue","unread element value"); + ValEntry->SetValue("gdcm::UnRead"); + return; + } + + if( (vr == "UI") ) // Because of correspondance with the VR dic + ValEntry->SetValue(NewValue.c_str()); + else + ValEntry->SetValue(NewValue); + } else { + // fusible + std::cout << "Should have a ValEntry, here !" << std::endl; } - if( (vr == "UI") ) // Because of correspondance with the VR dic - ((gdcmValEntry *)Entry)->SetValue(NewValue.c_str()); - else - ((gdcmValEntry *)Entry)->SetValue(NewValue); } @@ -1538,14 +1578,12 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry *Entry) Entry->SetDictEntry(NewTag); } - // Heuristic: well some files are really ill-formed. + // Heuristic: well, some files are really ill-formed. if ( length16 == 0xffff) { length16 = 0; - //dbg.Verbose(0, "gdcmDocument::FindLength", - // "Erroneous element length fixed."); - // Actually, length= 0xffff means that we deal with - // Unknown Sequence Length + // Length16= 0xffff means that we deal with + // 'Unknown Length' Sequence } FixDocEntryFoundLength(Entry, (guint32)length16); return; @@ -1644,7 +1682,7 @@ bool gdcmDocument::CheckDocEntryVR(gdcmDocEntry *Entry, VRKey vr) "UL","FIXME","Group Length"); Entry->SetDictEntry(NewEntry); } - return(false); + return false; } if ( Entry->IsVRUnknown() ) @@ -1668,7 +1706,7 @@ bool gdcmDocument::CheckDocEntryVR(gdcmDocEntry *Entry, VRKey vr) vr,"FIXME",Entry->GetName()); Entry->SetDictEntry(NewEntry); } - return(true); + return true; } /** @@ -1734,10 +1772,10 @@ std::string gdcmDocument::GetDocEntryValue(gdcmDocEntry *Entry) #ifdef GDCM_NO_ANSI_STRING_STREAM s << std::ends; // to avoid oddities on Solaris #endif //GDCM_NO_ANSI_STRING_STREAM - return(s.str()); + return s.str(); } - return(((gdcmValEntry *)Entry)->GetValue()); + return ((gdcmValEntry *)Entry)->GetValue(); } /** @@ -1787,10 +1825,10 @@ std::string gdcmDocument::GetDocEntryUnvalue(gdcmDocEntry *Entry) #ifdef GDCM_NO_ANSI_STRING_STREAM s << std::ends; // to avoid oddities on Solaris #endif //GDCM_NO_ANSI_STRING_STREAM - return(s.str()); + return s.str(); } - return(((gdcmValEntry *)Entry)->GetValue()); + return ((gdcmValEntry *)Entry)->GetValue(); } /**