[Insight-developers] dicom fields with VR = FL

Kris Thielemans kris.thielemans at csc.mrc.ac.uk
Wed Oct 11 20:33:55 EDT 2006


Hi

I need to load some DICOM private tags from GE DICOM files. Some of those
have VR=FL (i.e. it are float values). However, because ITK still ships with
gdcm 1.0, this turns out not to work. The GetValue() of such dictionary
entries is not a string with the value of the float, but a 4-byte string
with the binary representation, which aften means it's null-terminated and
unusable.

I managed to fix this by changing gdcm::Document:

1) add a new function in the .cxx (and declare it in .h) (straightforward
copy from ReadInt32)


/** 
 * \brief  Reads a supposed to be 32 Bits float 
 *        (swaps it depending on processor endianness)   
 * @return read value 
 * @bug probably does not work on architectures that use non-IEEE floats 
 */ 
float Document::ReadFloat() // KT  
   throw( FormatError ) 
{ 
   float g; 
   Fp->read ((char*)&g, (size_t)4); 
   if ( Fp->fail() ) 
   { 
      throw FormatError( "Document::ReadFloat()", " file error." ); 
   } 
   if ( Fp->eof() ) 
   { 
      throw FormatError( "Document::ReadFloat()", "EOF." ); 
   } 
   // TODO MAKE A SwapFloat g = SwapFloat(g); 
   return g; 
} 
 

2) change LoadDocEntry(...) by inserting some new code to handle the FL
case:
(a straightforward copy of the SL case)

   if ( IsDocEntryAnInteger(entry) ) 
   {    
	original code here
   } 
   // KT START NEW 
   if (vr == "FL") 
     { 
       float NewFloat; 
       int nbFloat; 
       // see above code for reading ints 
       { 
         nbFloat = length / 4; 
         NewFloat = ReadFloat(); 
         s << NewFloat; 
         if (nbFloat > 1) 
         { 
            for (int i=1; i < nbFloat; i++) 
            { 
               s << '\\'; 
               NewFloat = ReadFloat(); 
               s << NewFloat; 
            } 
         } 
       } 
#ifdef GDCM_NO_ANSI_STRING_STREAM 
       s << std::ends; // to avoid oddities on Solaris 
#endif //GDCM_NO_ANSI_STRING_STREAM 
 
      ((ValEntry *)entry)->SetValue(s.str()); 
       return; 
     } 
   // KT END NEW 

  // FIXME: 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); 




As you can see, this needs some work. SwapFloat would need to be written
(you can't just call SwapLong on 64-bit architectures), and potential
conversions from DICOM float format (presumably in IEEE format) to native
format.
And of course, we'd want to add double support as well.

Far better would be to upgrade to gdcm 1.2 which seems to support FL ->
string out-of-the-box. But I guess that's a non-trivial task.

Any chance that this can be fixed in CVS? 
(Before you ask, no, I have no time for at least another month to improve
the above code).

Kris Thielemans
Hammersmith Imanet, part of GE Healthcare 
London, United Kingdom




More information about the Insight-developers mailing list