]> Creatis software - gdcm.git/commitdiff
* src/gdcmHeader.cxx :
authorfrog <frog>
Tue, 22 Oct 2002 14:10:49 +0000 (14:10 +0000)
committerfrog <frog>
Tue, 22 Oct 2002 14:10:49 +0000 (14:10 +0000)
        - RecupLgr renamed to FindLength and cut off with new IsAnInteger
          method.
        - SetLgrElem renamed to SetLength
        - GetLgrElem renamed to GetLength
        - ~gdcmHeader() made virtual to pesky warning messages at compile.
      * src/gdcmElValSet.cxx fixed both GetElValue methods
      * Dicts/dicomV3.dic falacious entry [7fe0 0010 OT PXL Pixel Data]
        due to IdoDude was cleaned out.   --- Frog

ChangeLog
Dicts/dicomV3.dic
src/gdcmDict.cxx
src/gdcmElValSet.cxx
src/gdcmHeader.cxx
src/gdcmlib.h

index d5fbb52ce4ea37fa94c1fd068dfa2fd769cb0281..1260378734a9f1140d40af4ab783f3b1425931b1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2002-10-22 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
+      * src/gdcmHeader.cxx :
+        - RecupLgr renamed to FindLength and cut off with new IsAnInteger
+          method.
+        - SetLgrElem renamed to SetLength
+        - GetLgrElem renamed to GetLength
+        - ~gdcmHeader() made virtual to pesky warning messages at compile.
+      * src/gdcmElValSet.cxx fixed both GetElValue methods
+      * Dicts/dicomV3.dic falacious entry [7fe0 0010 OT PXL Pixel Data]
+        due to IdoDude was cleaned out.
+
 2002-10-21 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
       * src/gdcmHeader.cxx RecupLgr split in FindVR and RecupLgr. FindVR
         concentrates on finding the value representation (when it exists).
index e6c4cf58b14d9fc48ca7f49d61e5a338291b4f7b..a83f4ab5a9470a3e39cfc192217826a1d96bc84f 100644 (file)
 6000 3000 OW OLY Data
 6000 4000 LO OLY Comments (RET)
 7fe0 0000 UL PXL Group Length
-7fe0 0010 OT PXL Pixel Data
 fffe e000 UL XX   item
 ffff ffff UKN UKN Unknown Code
index f21e37a1bd99b83623bbd576b96df65a97231a3a..8b42624d8924da9e841ddcf64e8d2b393c451ded 100644 (file)
@@ -9,7 +9,6 @@ gdcmDict::gdcmDict(char * FileName) {
        guint16 group, element;
        // CLEANME : use defines for all those constants
        char buff[1024];
-       char trash[10];
        TagKey key, vr, fourth, name;
        while (!from.eof()) {
                from >> hex >> group >> element;
index 57512516d74ae7b19e665605eb53ee9fb69905f0..9101d26f97ab2541b25bdf4a44110a7620d27318 100644 (file)
@@ -1,16 +1,49 @@
 #include "gdcmlib.h"
+#include "gdcmUtil.h"
 
-int ElValSet::Add(ElValue * newElValue) {
+void ElValSet::Add(ElValue * newElValue) {
        tagHt[newElValue->GetKey()]   = newElValue;
        NameHt[newElValue->GetName()] = newElValue;
 }
 
-int ElValSet::Print(ostream & os) {
+void ElValSet::Print(ostream & os) {
        for (TagElValueHT::iterator tag = tagHt.begin();
                  tag != tagHt.end();
                  ++tag){
-               os << tag->first << ": [";
-               os << tag->second->GetValue() << "] [";
-               os << tag->second->GetName() << "]" << endl;
+               os << tag->first << ": ";
+               os << "[" << tag->second->GetValue() << "]";
+               os << "[" << tag->second->GetName()  << "]";
+               os << "[" << tag->second->GetVR()    << "]" << endl;
        }
 }
+
+void ElValSet::PrintByName(ostream & os) {
+       for (TagElValueNameHT::iterator tag = NameHt.begin();
+                 tag != NameHt.end();
+                 ++tag){
+               os << tag->first << ": ";
+               os << "[" << tag->second->GetValue() << "]";
+               os << "[" << tag->second->GetKey()  << "]";
+               os << "[" << tag->second->GetVR()    << "]" << endl;
+       }
+}
+
+string ElValSet::GetElValue(guint32 group, guint32 element) {
+       TagKey key = gdcmDictEntry::TranslateToKey(group, element);
+       if ( ! tagHt.count(key))
+               return "UNFOUND";
+       if (tagHt.count(key) > 1)
+               dbg.Verbose(0, "ElValSet::GetElValue",
+                           "multiple entries for this key (FIXME) !");
+       return tagHt.find(key)->second->GetValue();
+}
+
+string ElValSet::GetElValue(string TagName) {
+       if ( ! NameHt.count(TagName))
+               return "UNFOUND";
+       if (NameHt.count(TagName) > 1)
+               dbg.Verbose(0, "ElValSet::GetElValue",
+                           "multipe entries for this key (FIXME) !");
+       return NameHt.find(TagName)->second->GetValue();
+}
+
index 955411202925e9d289de811cdd8ba5efe6f4fea8..dc6bbf41a7ee6ca995746d9a3baad681f57b3ca1 100644 (file)
@@ -289,7 +289,7 @@ void gdcmHeader::FindVR( ElValue *pleCourant) {
        fseek(fp, PositionOnEntry, SEEK_SET);
 }
 
-void gdcmHeader::RecupLgr( ElValue *pleCourant) {
+void gdcmHeader::FindLength( ElValue *pleCourant) {
        int lgrLue;
        guint32 l_gr;
        unsigned short int l_gr_2;
@@ -307,7 +307,7 @@ void gdcmHeader::RecupLgr( ElValue *pleCourant) {
                        l_gr = SwapLong((guint32)l_gr);
                        
                } else {
-                       //on lit la lgr sur DEUX octets
+                       // Length is encoded on 2 bytes.
                        lgrLue=fread (&l_gr_2, (size_t)2,(size_t)1, fp);
                        
                        l_gr_2 = SwapShort((unsigned short)l_gr_2);
@@ -319,17 +319,17 @@ void gdcmHeader::RecupLgr( ElValue *pleCourant) {
                        }
                }
        } else {
-               // Explicit VR = 0
-               //on lit la lgr sur QUATRE octets
+               // Either implicit VR or an explicit VR that (at least for this
+               // element) lied a little bit. Length is on 4 bytes.
                lgrLue=fread (&l_gr, (size_t)4,(size_t)1, fp);
                l_gr= SwapLong((long)l_gr);
        }
 
        // Traitement des curiosites sur la longueur
-       if ( (int)l_gr == 0xffffffff)
+       if ( l_gr == 0xffffffff)
                l_gr=0; 
        
-       pleCourant->SetLgrElem(l_gr);
+       pleCourant->SetLength(l_gr);
 }
 
 /**
@@ -386,8 +386,8 @@ short int gdcmHeader::SwapShort(short int a) {
  */
 
 ElValue * gdcmHeader::ReadNextElement(void) {
-       unsigned short g;
-       unsigned short n;
+       guint16 g;
+       guint16 n;
        guint32 l;
        size_t lgrLue;
        ElValue * nouvDcmElem;
@@ -431,19 +431,18 @@ ElValue * gdcmHeader::ReadNextElement(void) {
                return(NULL);
        }
 
-       // ------------------------- Lecture longueur element : l
-       
        FindVR(nouvDcmElem);
-       RecupLgr(nouvDcmElem);
+       FindLength(nouvDcmElem);
        nouvDcmElem->SetOffset(ftell(fp));
-       l = nouvDcmElem->GetLgrElem();
+       l = nouvDcmElem->GetLength();
 
        //FIXMEif(!memcmp( VR,"SQ",(size_t)2 )) { // ca annonce une SEQUENCE d'items ?!
        //FIXME l_gr=0;                         // on lira donc les items de la sequence 
        //FIXME}
        //FIXMEreturn(l_gr);
 
-
+   // Une sequence contient un ensemble de group element repetes n fois
+       // et g=fffe indique la fin (contient une longueur bidon).
        if(g==0xfffe) l=0;  // pour sauter les indicateurs de 'SQ'
        
        
@@ -462,41 +461,58 @@ ElValue * gdcmHeader::ReadNextElement(void) {
        // pas etre charge's !!!! Voir TODO.
        lgrLue=fread (NewValue, (size_t)l,(size_t)1, fp);
        
+       if ( IsAnInteger(g, n, NewTag->GetVR(), l) ) {
+               // CLEANME THe following is really UGLY ! 
+               if( l == 4 ) {
+                       *(guint32 *) NewValue = SwapLong  ((*(guint32 *) NewValue)); 
+               } else {
+                       if( l == 2 )
+                               *(guint16 *) NewValue = SwapShort ((*(guint16 *)NewValue));
+               }
+               //FIXME: don't we have to distinguish guin16 and guint32
+               //FIXME: make the following an util fonction
+               ostringstream s;
+               s << *(guint32 *) NewValue;
+               nouvDcmElem->value = s.str();
+               g_free(NewValue);
+       } else
+               nouvDcmElem->value = NewValue;
+       return nouvDcmElem;
+}
 
-       // ------------------------- Doit-on le Swapper ?
-       
-       if ((n==0) && sw)  {  // n=0 : lgr du groupe : guint32
-               *(guint32 *) NewValue = SwapLong ((*(guint32 *) NewValue));  
-       } else {
-               if(sw) {
-                       if ( (g/2)*2-g==0) { /* on ne teste pas les groupes impairs */
-                               
-                               if ((l==4)||(l==2)) {  // pour eviter de swapper les chaines 
-                                                           // de lgr 2 ou 4
-                                       
-                                       // FIXME make reference to nouvDcmElem->GetTag
-                                       string VR = NewTag->GetVR();
-                                       if (   (VR == "UL") || (VR == "US")
-                                           || (VR == "SL") || (VR == "SS")
-                                           || (g == 0x0028 && ( n == 0x0005 || n == 0x0200) )) {
-                                               // seuls (28,5) de vr RET et (28,200) sont des entiers
-                                               // ... jusqu'a preuve du contraire
-                                               
-                                               if(l==4) { 
-                                                       *(guint32 *) NewValue =
-                                                           SwapLong  ((*(guint32 *) NewValue)); 
-                                               } else {
-                                                       if(l==2) 
-                                                   *(unsigned short *) NewValue =
-                                                       SwapShort ((*(unsigned short *)NewValue));
-                                                }
-                                       }
-                               } /* fin if l==2 ==4 */
-                       } /* fin if g pair */
-               } /* fin sw */  
+bool gdcmHeader::IsAnInteger(guint16 group, guint16 element,
+                                    string vr, guint32 length ) {
+       // When we have some semantics on the element we just read, and we
+       // a priori now we are dealing with an integer, then we can swap it's
+       // element value properly.
+       if ( element == 0 )  {  // This is the group length of the group
+               if (length != 4)
+                       dbg.Error("gdcmHeader::ShouldBeSwaped", "should be four");
+               return true;
        }
-       nouvDcmElem->value = NewValue;
-       return nouvDcmElem;
+       
+       if ( group % 2 != 0 )
+               // We only have some semantics on documented elements, which are
+               // the even ones.
+               return false;
+       
+       if ( (length != 4) && ( length != 2) )
+               // Swapping only make sense on integers which are 2 or 4 bytes long.
+               return false;
+       
+       if ( (vr == "UL") || (vr == "US") || (vr == "SL") || (vr == "SS") )
+               return true;
+       
+       if ( (group == 0x0028) && (element == 0x0005) )
+               // This tag is retained from ACR/NEMA
+               // CHECKME Why should "Image Dimensions" be a single integer ?
+               return true;
+       
+       if ( (group == 0x0028) && (element == 0x0200) )
+               // This tag is retained from ACR/NEMA
+               return true;
+       
+       return false;
 }
 
 /**
@@ -505,12 +521,6 @@ ElValue * gdcmHeader::ReadNextElement(void) {
  *          (Pixel Data) then keep the info aside.
  */
 void gdcmHeader::SetAsidePixelData(ElValue* elem) {
-         /// FIXME this wall process is bizarre:
-         // on peut pas lire pixel data et pixel location puis
-         // a la fin de la lecture aller interpreter ce qui existe ?
-         // penser a nettoyer les variables globales associes genre
-         // PixelsTrouve ou grPixelTrouve...
-         //
        // They are two cases :
        // * the pixel data (i.e. the image or the volume) is pointed by it's
        //   default official tag (0x7fe0,0x0010),
@@ -527,6 +537,20 @@ void gdcmHeader::SetAsidePixelData(ElValue* elem) {
        //     * if it does not exist, look for the "Pixel Location" tag.
        //  2/ look at the proper tag ("Pixel Data" or "Pixel Location" when
        //     it exists) what the offset is.
+       cout << "aaaaaaaaaaaaaaaaaaaaa";
+       // PubElVals.PrintByName(cout);
+       ostringstream val;
+       val << hex << GetPubElValByName("Image Location");
+       cout << GetPubElValByName("Image Location") << endl;
+       cout <<hex << GetPubElValByName("Image Location") << dec << endl;
+       cout << "aaaa" << hex << val << dec << endl;
+       if (val)
+               //grPixel  = val.hex().str();
+               grPixel = 0;
+       else
+               grPixel  = 0x7FE0;
+       return;
+
        guint16 g;
        guint16 n;
        g = elem->GetGroup();
@@ -542,7 +566,7 @@ void gdcmHeader::SetAsidePixelData(ElValue* elem) {
                        if (g == 0x0028) {
                                if (n == 0x0200) {
                                        grPixelTrouve = 1;
-                                       char* NewValue = (char*)g_malloc(elem->GetLgrElem()+1);
+                                       char* NewValue = (char*)g_malloc(elem->GetLength()+1);
                                        // FIXME: not very elegant conversion
                                        for(int i=0;i<4;i++)
                                                *((char*)(&grPixel)+i) = *(NewValue+i); 
@@ -586,7 +610,12 @@ gdcmDictEntry * gdcmHeader::IsInDicts(guint32 group, guint32 element) {
        return found;
 }
 
-string gdcmHeader::GetPubElValByNumber(unsigned short, unsigned short) {
+string gdcmHeader::GetPubElValByNumber(guint16 group, guint16 element) {
+       return PubElVals.GetElValue(group, element);
+}
+
+string gdcmHeader::GetPubElValByName(string TagName) {
+       return PubElVals.GetElValue(TagName);
 }
 
 /**
@@ -599,16 +628,16 @@ string gdcmHeader::GetPubElValByNumber(unsigned short, unsigned short) {
 void gdcmHeader::BuildHeader(void) {
        ElValue * newElValue = (ElValue *)0;
        
-       rewind(fp);
        rewind(fp);
        CheckSwap();
        while ( (newElValue = ReadNextElement()) ) {
                PubElVals.Add(newElValue);
        }
+       SetAsidePixelData((ElValue*)0);
 }
 
-int gdcmHeader::PrintPubElVal(ostream & os) {
-       return PubElVals.Print(os);
+void gdcmHeader::PrintPubElVal(ostream & os) {
+       PubElVals.Print(os);
 }
 
 void gdcmHeader::PrintPubDict(ostream & os) {
index bdf786f685ad261d9541ebae7d0ccb67ed0849e9..7c16dba9a8cf3442fe7c5f9f7a56a2da2e921e35 100644 (file)
@@ -134,11 +134,11 @@ public:
        ElValue(gdcmDictEntry*);
        void   SetVR(string);
        string GetVR(void);
-       void SetLgrElem(guint32 l) {LgrElem = l; };
+       void SetLength(guint32 l){LgrElem = l; };
        void SetValue(string val){ value = val; };
        void SetOffset(size_t of){ Offset = of; };
        string  GetValue(void)   { return value; };
-       guint32 GetLgrElem(void) { return LgrElem; };
+       guint32 GetLength(void) { return LgrElem; };
        size_t  GetOffset(void)  { return Offset; };
        guint16 GetGroup(void)   { return entry->GetGroup(); };
        guint16 GetElement(void) { return entry->GetElement(); };
@@ -147,14 +147,18 @@ public:
 };
 
 typedef map<TagKey, ElValue*> TagElValueHT;
+typedef map<string, ElValue*> TagElValueNameHT;
 // Container for a set of succefully parsed ElValues.
 class ElValSet {
        // We need both accesses with a TagKey and the Dicentry.Name
        TagElValueHT tagHt;
-       map<string, ElValue*> NameHt;
+       TagElValueNameHT NameHt;
 public:
-       int Add(ElValue*);
-       int Print(ostream &);
+       void Add(ElValue*);
+       void Print(ostream &);
+       void PrintByName(ostream &);
+       string GetElValue(guint32 group, guint32 element);
+       string GetElValue(string);
 };
 
 // The various entries of the explicit value representation (VR) shall
@@ -202,7 +206,7 @@ private:
 
        void Initialise(void);
        void CheckSwap(void);
-       void RecupLgr(ElValue *);
+       void FindLength(ElValue *);
        void FindVR(ElValue *);
        guint32 SwapLong(guint32);
        short int SwapShort(short int);
@@ -225,9 +229,10 @@ protected:
 /////           See below for an example of how anonymize might be implemented.
        int anonymize(ostream&);
 public:
+       bool IsAnInteger(guint16, guint16, string, guint32);
        virtual void BuildHeader(void);
        gdcmHeader(char* filename);
-       ~gdcmHeader();
+       virtual ~gdcmHeader();
 
        int SetPubDict(string filename);
        // When some proprietary shadow groups are disclosed, whe can set
@@ -247,7 +252,7 @@ public:
        // of C/C++ vs Python).
        string GetPubElValRepByName(string TagName);
        string GetPubElValRepByNumber(guint16 group, guint16 element);
-       int    PrintPubElVal(ostream &);
+       void   PrintPubElVal(ostream &);
        void   PrintPubDict(ostream &);
          
        // Same thing with the shadow :