X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmDocument.cxx;h=e0d531a7e382d6cb1268fb6741a96759cf59d497;hb=05f9a9731209a5c98895a57c6abca609f8e9b312;hp=ece8f61937dffe2e50f38e741e82340c07d68b8d;hpb=c1e76b5446c340a4b2df46cabedeab2d71bd45f8;p=gdcm.git diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index ece8f619..e0d531a7 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/22 14:07:05 $ - Version: $Revision: 1.23 $ + Date: $Date: 2004/06/25 12:56:39 $ + Version: $Revision: 1.33 $ 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,6 +126,25 @@ 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); + + // Load 'non string' values + + std::string PhotometricInterpretation = GetEntryByNumber(0x0028,0x0004); + if( PhotometricInterpretation == "PALETTE COLOR " ) { + LoadEntryVoidArea(0x0028,0x1200); // gray LUT + LoadEntryVoidArea(0x0028,0x1201); // R LUT + LoadEntryVoidArea(0x0028,0x1202); // G LUT + LoadEntryVoidArea(0x0028,0x1203); // B LUT + + LoadEntryVoidArea(0x0028,0x1221); // Segmented Red Palette Color LUT Data + LoadEntryVoidArea(0x0028,0x1222); // Segmented Green Palette Color LUT Data + LoadEntryVoidArea(0x0028,0x1223); // Segmented Blue Palette Color LUT Data + } + //FIXME later : how to use it? + LoadEntryVoidArea(0x0028,0x3006); //LUT Data (CTX dependent) + CloseFile(); // -------------------------------------------------------------- @@ -206,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; } /** @@ -222,7 +241,7 @@ gdcmDict *gdcmDocument::GetShaDict(void) { */ bool gdcmDocument::SetShaDict(gdcmDict *dict){ RefShaDict=dict; - return(!RefShaDict); + return !RefShaDict; } /** @@ -231,7 +250,7 @@ bool gdcmDocument::SetShaDict(gdcmDict *dict){ */ bool gdcmDocument::SetShaDict(DictKey dictName){ RefShaDict=gdcmGlobal::GetDicts()->GetDict(dictName); - return(!RefShaDict); + return !RefShaDict; } /** @@ -245,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); @@ -390,11 +409,12 @@ bool gdcmDocument::IsRLELossLessTransferSyntax(void) * @return True when RLE Lossless found. False in all * other cases. */ + 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_90) ); + || IsGivenTransferSyntax(UI1_2_840_10008_1_2_4_70) ); } /** @@ -552,9 +572,8 @@ 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; } @@ -948,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; } @@ -1046,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; @@ -1110,7 +1153,7 @@ guint32 gdcmDocument::SwapLong(guint32 a) { dbg.Error(" gdcmDocument::SwapLong : unset swap code"); a=0; } - return(a); + return a; } /** @@ -1119,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); } /** @@ -1129,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; } /** @@ -1137,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); } //----------------------------------------------------------------------------- @@ -1180,7 +1223,7 @@ long gdcmDocument::ParseDES(gdcmDocEntrySet *set, long offset, long l_max, bool NewValEntry->SetDepthLevel(depth); set->AddEntry(NewValEntry); LoadDocEntry(NewValEntry); - if (/*!delim_mode && */NewValEntry->isItemDelimitor()) + if (NewValEntry->isItemDelimitor()) break; if ( !delim_mode && ftell(fp)-offset >= l_max) { @@ -1206,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 { @@ -1241,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) { @@ -1250,7 +1299,7 @@ long gdcmDocument::ParseDES(gdcmDocEntrySet *set, long offset, long l_max, bool } delete NewDocEntry; } - return l; // ?? + return l; // Probably useless } /** @@ -1271,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); @@ -1300,7 +1352,7 @@ long gdcmDocument::ParseSQ(gdcmSeqEntry *set, } } lgth = ftell(fp) - offset; - return(lgth); + return lgth; } /** @@ -1323,9 +1375,6 @@ void gdcmDocument::LoadDocEntry(gdcmDocEntry *Entry) // (fffe e0dd) tells us the current SeQuence just ended if( group == 0xfffe ) { // NO more value field for SQ ! - //Entry->SetValue("gdcm::Skipped"); - // appel recursif de Load Value - // (meme pb que pour le parsing) return; } @@ -1338,21 +1387,43 @@ 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) ) + { + s << "gdcm::NotLoaded (BinEntry)"; + s << " Address:" << (long)Entry->GetOffset(); + s << " Length:" << Entry->GetLength(); + s << " x(" << std::hex << Entry->GetLength() << ")"; + BinEntryPtr->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; + // Be carefull : a BinEntry IS_A ValEntry ... if (gdcmValEntry* ValEntryPtr = dynamic_cast< gdcmValEntry* >(Entry) ) { - std::ostringstream s; - s << "gdcm::NotLoaded."; + 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); - + fseek(fp,(long)Entry->GetOffset()+(long)Entry->GetLength(),SEEK_SET); return; } + + // When we find a BinEntry not very much can be done : + if (gdcmBinEntry* BinEntryPtr = dynamic_cast< gdcmBinEntry* >(Entry) ) { + + LoadEntryVoidArea(BinEntryPtr); + s << "gdcm::Loaded (BinEntry)"; + BinEntryPtr->SetValue(s.str()); + return; + } + // Any compacter code suggested (?) if ( IsDocEntryAnInteger(Entry) ) { @@ -1402,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); } @@ -1501,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; @@ -1607,7 +1682,7 @@ bool gdcmDocument::CheckDocEntryVR(gdcmDocEntry *Entry, VRKey vr) "UL","FIXME","Group Length"); Entry->SetDictEntry(NewEntry); } - return(false); + return false; } if ( Entry->IsVRUnknown() ) @@ -1631,7 +1706,7 @@ bool gdcmDocument::CheckDocEntryVR(gdcmDocEntry *Entry, VRKey vr) vr,"FIXME",Entry->GetName()); Entry->SetDictEntry(NewEntry); } - return(true); + return true; } /** @@ -1697,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(); } /** @@ -1750,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(); } /** @@ -1777,16 +1852,6 @@ void gdcmDocument::SkipToNextDocEntry(gdcmDocEntry *entry) (void)fseek(fp, (long)(entry->GetReadLength()), SEEK_CUR); } -/** - * \brief Loads the value for a a given VLEntry - * \warning NOT end user intended method ! - * @param entry - */ -void gdcmDocument::LoadVLEntry(gdcmDocEntry *entry) -{ - //SkipBytes(entry->GetLength()); - LoadDocEntry(entry); -} /** * \brief When the length of an element value is obviously wrong (because * the parser went Jabberwocky) one can hope improving things by