[Dcmlib] Incoherence de longueur de champ

Mathieu Malaterre mathieu.malaterre at kitware.com
Fri Nov 5 16:56:53 CET 2004


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
> 






More information about the Dcmlib mailing list