[Dcmlib] Incoherence de longueur de champ

Jean-Pierre Roux jpr at creatis.insa-lyon.fr
Fri Nov 5 19:06:05 CET 2004


Emmanuel olart wrote:

>Hum oui on avait évoqué ce problème, le writer ne devait pas mettre tous les
>champs en longueur paire ?
>
>Si je me souviens bien ca ne casse "qu'avec" la longueur 13 car il y a un
>small patch de JPR qui traite un cas particulier de je ne sais plus quelle
>image qui est justement reconnaissable a un champ en longueur 13.
>Je commente cette ligne a chaque fois ici avant de compiler gdcm.
>  
>

Et tu as tort ...
J'ai modifié, il y a longtemps, le patch proposé par xmedcon pour lire 
des images GE pourries (qui annoncaient une longueur de 13, mais qui en 
fait n'avaient ecrit que 10 octets sur disque), afin que les 'vieilles' 
images Theralys (qui annoncent 13 et qui ecrivent 13) passent .

Si tu as, dans le code que tu utilises, dans
void Document::FixDocEntryFoundLength :

   if ( foundLength == 13)
   {
      // Only happens for this length !
      if ( entry->GetGroup()   != 0x0008
      || ( entry->GetElement() != 0x0070
        && entry->GetElement() != 0x0080 ) )
      {
         foundLength = 10;
         entry->SetReadLength(10); /// \todo a bug is to be fixed !?
      }
   }
tu n'as pas besoin de commenter out.

>manu
>----- Original Message ----- 
>From: "Mathieu Malaterre" <mathieu.malaterre at kitware.com>
>To: "Mathieu Malaterre" <mathieu.malaterre at kitware.com>
>Cc: <dcmlib at tux.creatis.insa-lyon.fr>
>Sent: Friday, November 05, 2004 5:33 PM
>Subject: Re: [Dcmlib] Incoherence de longueur de champ
>
>
>  
>
>>Mince ca casse sur "Theralys S.A." avec sa longueur de 13...
>>
>>Mathieu Malaterre wrote:
>>    
>>
>>>Je me reponds a moi meme, changer le code en :
>>>
>>> std::string newValue = Util::DicomString(str, length);
>>>(gdcmDocument.cxx:1661)
>>>
>>>me permet plus tard de faire (gdcmValEntry.cxx:239)
>>>
>>>assert( lgr == GetValue().size() );  //cool un assert de plus
>>>binary_write(*fp, GetValue());
>>>
>>>Je patch gdcm, je compile sur Win32. Et je vous tiens au courant si ca
>>>aide un peu.
>>>
>>>Mathieu
>>>
>>>Mathieu Malaterre wrote:
>>>
>>>      
>>>
>>>>Eric Boix wrote:
>>>>
>>>>        
>>>>
>>>>>    Yo,
>>>>>
>>>>>
>>>>>          
>>>>>
>>>>>>0008|0050 lg :       x(2) 2        Off.:     x(1bc) 444     [SH]
>>>>>>                                          [Accession Number] []
>>>>>>
>>>>>>Mais j'ai beau chercher il ne passe pas dans LoadDocEntry. Comment a
>>>>>>partir d'un group element je trouve a quoi il correspond (DocEntry,
>>>>>>ValEntry, SeqEntry ... )
>>>>>>            
>>>>>>
>>>>>
>>>>>
>>>>>Morceaux choisis de void Document::ParseDES():
>>>>>
>>>>>{
>>>>>   ...
>>>>>   if ( vr != "SQ" )
>>>>>   {
>>>>>      if ( Global::GetVR()->IsVROfGdcmStringRepresentable(vr) )
>>>>>      {
>>>>>         /////////////////////// ValEntry
>>>>>         ValEntry* newValEntry = new ValEntry(...);
>>>>>         ...
>>>>>      } else {
>>>>>         //////////////////// BinEntry or UNKOWN VR:
>>>>>         BinEntry* newBinEntry = new BinEntry(...);
>>>>>      }
>>>>>      ...
>>>>>   } else {
>>>>>      // VR = "SQ"
>>>>>      SeqEntry* newSeqEntry = new SeqEntry(...)
>>>>>      ...
>>>>>   }             ...
>>>>>}
>>>>>
>>>>>Moralite':
>>>>>  * si vr = 'sq' c'est une sequence (et on recurse).
>>>>>  * si vr est "StringRepresentable" c'est une ValEntry (on interprete
>>>>>    les donnees binaires comme un string),
>>>>>  * si vr n'est pas "StringRepresentable" c'est donc du binaire
>>>>>
>>>>>A noter que pour un (group, element) qui n'est pas dans le dictionaire
>>>>>la VR est dans le fichier...
>>>>>
>>>>>C,a va ?
>>>>>          
>>>>>
>>>>
>>>>
>>>>Bon ca va, j'ai dormi. J'ai place qlq assert et j'ai trouve' le
>>>>probleme: (gdcmDocument.cxx), ligne 1681 (*)
>>>>
>>>>extrait:
>>>>   Fp->read(str, (size_t)length);
>>>>   str[length] = '\0';
>>>>   std::string newValue = str;
>>>>
>>>>Qlq plaisir de la std::string. Il y a une *enorme* difference entre:
>>>>
>>>>const char *s = "\0\0";
>>>>std::string a = s;
>>>>
>>>>-> a.size() = 0 !!!!
>>>>
>>>>*Mais*
>>>>
>>>>const char *s = "\0\0";
>>>>std::string a(s,s+2); // will copy 2 '\0'
>>>>
>>>>-> a.size() = 2
>>>>
>>>>et ou peut utiliser c_str() / data() indifferemment. Puisque la taille
>>>>de la string sera la bonne.
>>>>
>>>>
>>>>Donc je voudrais ajouter une notion de DicomString dans gdcmUtil:
>>>>
>>>>
>>>>
>>>>/**
>>>> * \ingroup Util
>>>> * \brief Create a /DICOM/ string:
>>>> * It should a of even lenght (no odd lenght ever)
>>>> * It can contains as many \0 as you want.
>>>> * This function is similar to DicomString(const char*), except it
>>>>doesn't
>>>> * take a lenght. It only pad with a null character if legnth is odd
>>>> */
>>>>std::string Util::DicomString(const char* s)
>>>>{
>>>>   size_t l = strlen(s);
>>>>   if( l%2 )
>>>>   {
>>>>      l++;
>>>>   }
>>>>   std::string r(s, s+l);
>>>>   assert( !(r.size() % 2) );
>>>>   return r;
>>>>}
>>>>
>>>>/**
>>>> * \ingroup Util
>>>> * \brief Create a /DICOM/ string:
>>>> * It should a of even lenght (no odd lenght ever)
>>>> * It can contains as many \0 as you want.
>>>> */
>>>>std::string Util::DicomString(const char* s, size_t l)
>>>>{
>>>>   std::string r(s, s+l);
>>>>   assert( !(r.size() % 2) );
>>>>   return r;
>>>>}
>>>>
>>>>
>>>>L'avantage c'est qu'ensuite au moment de l'ecriture on peut toujours
>>>>comparer la taille de la string par rapport a GetReadLenght() et faire
>>>>un assert (j'aime bien les assert car ca na pas de cout en Release).
>>>>Je pense que la classe gdcmValEntry doit vraiment avoir la notion de
>>>>'DicomString', pas de chaine ayant un nombre impaire de caractere.
>>>>Pour l'instant je ne peux pas obliger ca a cause des chaines du genre:
>>>>
>>>>"19785\8257\17747\8273"
>>>>
>>>>J'aurais preferer une notion de gdcmValVectorEntry...
>>>>
>>>>Mathieu
>>>>Ps: j'ai bine l'impression que l'on ecrivait sur le disque de la
>>>>memoire aleatoire jusqu'a present. Et ca passait car std::string en
>>>>Debug doit mettre un packet de zero sous linux, mais par sous win32:
>>>>
>>>>
>>>>        
>>>>
>http://public.kitware.com/Public/Sites/DASH3.kitware/GDCM-Win32-vs60/20041105-0100-Nightly/Test.html
>  
>
>>>>
>>>>(*)
>>>>  // We need an additional byte for storing \0 that is not on disk
>>>>   char *str = new char[length+1];
>>>>   Fp->read(str, (size_t)length);
>>>>   str[length] = '\0';
>>>>   std::string newValue = str;
>>>>   delete[] str;
>>>>
>>>>   if ( ValEntry* valEntry = dynamic_cast<ValEntry* >(entry) )
>>>>   {
>>>>      if ( Fp->fail() || Fp->eof())//Fp->gcount() == 1
>>>>      {
>>>>         dbg.Verbose(1, "Document::LoadDocEntry",
>>>>                        "unread element value");
>>>>         valEntry->SetValue(GDCM_UNREAD);
>>>>         return;
>>>>      }
>>>>
>>>>      if( vr == "UI" )
>>>>      {
>>>>         // Because of correspondance with the VR dic
>>>>         valEntry->SetValue(newValue);
>>>>      }
>>>>      else
>>>>      {
>>>>         valEntry->SetValue(newValue);
>>>>      }
>>>>   }
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>_______________________________________________
>>>>Dcmlib mailing list
>>>>Dcmlib at creatis.insa-lyon.fr
>>>>http://www.creatis.insa-lyon.fr/mailman/listinfo/dcmlib
>>>>
>>>>        
>>>>
>>>
>>>_______________________________________________
>>>Dcmlib mailing list
>>>Dcmlib at creatis.insa-lyon.fr
>>>http://www.creatis.insa-lyon.fr/mailman/listinfo/dcmlib
>>>
>>>      
>>>
>>
>>_______________________________________________
>>Dcmlib mailing list
>>Dcmlib at creatis.insa-lyon.fr
>>http://www.creatis.insa-lyon.fr/mailman/listinfo/dcmlib
>>
>>
>>    
>>
>
>
>_______________________________________________
>Dcmlib mailing list
>Dcmlib at creatis.insa-lyon.fr
>http://www.creatis.insa-lyon.fr/mailman/listinfo/dcmlib
>
>  
>



More information about the Dcmlib mailing list