]> Creatis software - gdcm.git/blobdiff - src/gdcmDocument.cxx
* Test/PrintAllDocument.cxx: looping on files is now effective. It used to
[gdcm.git] / src / gdcmDocument.cxx
index 550443d860939ac858db2e9b188f799edaa4eb20..e0d531a7e382d6cb1268fb6741a96759cf59d497 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/06/22 15:31:17 $
-  Version:   $Revision: 1.25 $
+  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);
 }
 
 //-----------------------------------------------------------------------------
@@ -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;
 }
 
 /**
@@ -1335,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();
@@ -1348,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;
@@ -1366,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 (?)
@@ -1419,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);
 }
 
 
@@ -1518,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;
@@ -1624,7 +1682,7 @@ bool gdcmDocument::CheckDocEntryVR(gdcmDocEntry *Entry, VRKey vr)
                                    "UL","FIXME","Group Length");
          Entry->SetDictEntry(NewEntry);     
       }
-      return(false);
+      return false;
    }
 
    if ( Entry->IsVRUnknown() ) 
@@ -1648,7 +1706,7 @@ bool gdcmDocument::CheckDocEntryVR(gdcmDocEntry *Entry, VRKey vr)
                                  vr,"FIXME",Entry->GetName());
       Entry->SetDictEntry(NewEntry);
    }
-   return(true)
+   return true
 }
 
 /**
@@ -1714,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();
 }
 
 /**
@@ -1767,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();
 }
 
 /**