]> Creatis software - gdcm.git/commitdiff
Start of dispatching dcmutil.c (see src/orig) to gdcmHeader.cxx.
authorfrog <frog>
Mon, 7 Oct 2002 12:21:47 +0000 (12:21 +0000)
committerfrog <frog>
Mon, 7 Oct 2002 12:21:47 +0000 (12:21 +0000)
TODO [new file with mode: 0644]
src/Makefile [moved from Makefile with 91% similarity]
src/dcm.i [moved from dcm.i with 100% similarity]
src/gdcmHeader.cxx [new file with mode: 0644]
src/gdcmlib.h [moved from dcmlib.h with 96% similarity]
src/orig/dcmutil.c [new file with mode: 0644]
src/test.cxx [moved from test.cxx with 100% similarity]

diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..aca64a5
--- /dev/null
+++ b/TODO
@@ -0,0 +1,4 @@
+gdcmHeader::CheckSwap() dans le cas ACR pas propre, degager tout de suite 
+si on a deduit que c'en est pas...
+
+gdcmHeader::_IdDcmRecupLgr return type should be long int.
similarity index 91%
rename from Makefile
rename to src/Makefile
index 24fe1ef51a8f9fc8a71f277144498402a24e0d86..1d4bade6b0fe4436e93c2c8718afab6d02a72fc3 100644 (file)
--- a/Makefile
@@ -16,9 +16,9 @@ CXXFLAGS=$(PYTHON_INCLUDES)
 %_wrap.cxx : %.i
        $(SWIG) $(SWIGFLAGS) $(PYTHON_INCLUDES) -o $@ $<
 
-all: dcm_wrap.o
+all: gdcmHeader.o dcm_wrap.o
 
-test: test.o
+test: gdcmHeader.o
 
 clean:
        rm -f *_wrap* *.so *.o *.pyc
diff --git a/dcm.i b/src/dcm.i
similarity index 100%
rename from dcm.i
rename to src/dcm.i
diff --git a/src/gdcmHeader.cxx b/src/gdcmHeader.cxx
new file mode 100644 (file)
index 0000000..79aa013
--- /dev/null
@@ -0,0 +1,340 @@
+#include "gdcmlib.h"
+
+/* =======================================================================
+
+   _IdDcmCheckSwap
+      La seule maniere sure que l'on aie pour determiner 
+      si on est en   LITTLE_ENDIAN,       BIG-ENDIAN, 
+                  BAD-LITTLE-ENDIAN, BAD-BIG-ENDIAN
+      est de trouver l'element qui donne la longueur d'un 'GROUP'
+      (on sait que la longueur de cet element vaut 0x00000004)
+      et de regarder comment cette longueur est codee en memoire  
+
+      Le probleme vient de ce que parfois, il n'y en a pas ...
+
+      On fait alors le pari qu'on a a faire a du LITTLE_ENDIAN propre.
+      (Ce qui est la norme -pas respectee- depuis ACR-NEMA)
+      Si ce n'est pas le cas, on ne peut rien faire.
+
+      (il faudrait avoir des fonctions auxquelles 
+       on passe le code Swap en parametre, pour faire des essais 'manuels')
+
+   ======================================================================= */
+
+EndianType gdcmHeader::gdcmHeader()
+{
+       //guint32  s;
+       guint32  x=4;  // x : pour ntohs
+       bool net2host; // true when HostByteOrder is the same as NetworkByteOrder
+
+       int sw;
+       int lgrLue;
+       char * entCur;
+       char deb[LGR_ENTETE_A_LIRE];
+
+       // On teste le processeur
+       if (x==ntohs(x)) {
+      net2host = true;
+   } else {
+      net2host = false;
+   }
+
+       // On commence par verifier si c'est du DICOM 'actuel'
+       //                                      -------------
+
+   lgrLue = fread(deb,1,LGR_ENTETE_A_LIRE,e->fp);
+
+   entCur = deb+128;
+   if(memcmp(entCur, "DICM", (size_t)4) == 0) {
+      filetype = TrueDicom;
+      if (DEBUG) printf ("_IdDcmCheckSwap : C est du DICOM actuel \n");
+   } else {
+      filetype = Unknown;
+      if (DEBUG) printf ("_IdDcmCheckSwap : Ce n'est PAS du DICOM actuel\n");
+   }
+
+   if(filetype == TrueDicom) {
+          // on saute le File Preamble (souvent a ZERO) : 128 Octets
+      // + le DICM (4), et le (0002, 0000) soit 4 (136 = 128 + 4 + 4)
+      entCur = deb+136;
+      if(memcmp(entCur, "UL", (size_t)2) == 0) {
+         // les 2 premiers octets de la lgr peuvent valoir UL --> Explicit VR
+         filetype = ExplicitVR;
+         if (DEBUG)  printf ("_IdDcmCheckSwap : Explicit VR\n");
+      } else {
+         filetype = ImplicitVR;
+         if (DEBUG)  printf ("_IdDcmCheckSwap : PAS Explicit VR\n");
+      }
+
+      if (net2host) { // HostByteOrder is different from NetworkByteOrder
+         sw = 0;    // on est sur PC ou DEC --> LITTLE-ENDIAN -> Rien a faire
+         if (DEBUG) printf("HostByteOrder = NetworkByteOrder\n");
+
+      } else {    /* on est sur une Sun ou une SGI */
+         sw = 4321;
+         if (DEBUG) printf("HostByteOrder != NetworkByteOrder\n");
+      }
+
+      rewind(e->fp);
+      fseek (e->fp, 132L, SEEK_SET); //On se positionne sur le debut des info
+      e->offsetCourant=132;
+      return sw;
+
+   } /* fin TrueDicom */
+
+       // Pas du TrueDicom : permiere hypothese c'est de l'ACR 'propre', auquel
+       // cas la lgr du premier element du groupe est FORCEMENT 4
+
+   entCur=deb + 4;
+   s=str2num(entCur,int);
+
+   switch (s) {
+      case 0x00040000 :
+         sw=3412; if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
+                       filetype = ACR;
+         break;
+      case 0x04000000 :
+         sw=4321; if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
+                       filetype = ACR;
+         break;
+      case 0x00000400 :
+         sw=2143; if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
+                       filetype = ACR;
+         break;
+      case 0x00000004 :
+         sw=0;    if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
+                       filetype = ACR;
+         break;
+      default :
+         sw = -1;
+         if (DEBUG) printf (" Pas trouve l info de Swap; On va parier\n");
+       }
+
+       // Deuxieme hypothese : c'est de l'ACR 'pas propre' i.e. il manque
+       // la lgr du groupe
+
+       if(sw==-1) {
+      /* On n'a pas trouve l'info de swap    28/11/2000 JPR                */
+      // Si c'est du VRAI ACR NEMA  si on est sur une DEC ou un PC swap=0,
+          // SUN ou SGI SWAP=4321
+      /* si c'est du RAW, ca degagera + tard                      */
+
+      if (DEBUG) printf("On force la chance \n");
+
+      if (x!=ntohs(x)) // HostByteOrder is different from NetworkByteOrder
+         sw = 0;    // on est sur PC ou DEC --> LITTLE-ENDIAN -> Rien a faire
+      else
+         sw = 4321; // on est sur Sun ou SGI
+       }
+
+   rewind(e->fp);    // les info commencent au debut
+   e->offsetCourant=0;
+   return (sw);
+}
+
+void  gdcmHeader::_setAcrLibido() {
+
+   _ID_DCM_ELEM * ple;
+   PLIST_ELEMENT plelem;
+   PLIST pl;
+
+   // Positionnement ACR_LIBIDO
+   if(DEBUG) printf("Entree ds _setAcrLibido\n");
+
+   filetype = ACR_LIBIDO = 0;
+   if ( filetype != TrueDicom) {
+      // Recognition Code  --> n'existe plus en DICOM V3 ...
+
+      pl = e->plist;
+      plelem = IdLstFirst(pl);
+      while (plelem) {
+         ple= IdLstPtrObj(plelem);
+         if(DEBUG) printf("gr %04x Num %04x\n", ple->Gr, ple->Num);
+         if(ple->Gr >  0x0008) break;     // On a depasse
+         if(ple->Gr == 0x0008) {
+            if(ple->Num >  0x0010) break; // On a depasse
+            if(ple->Num == 0x0010) {
+               if (  (memcmp(ple->valeurElem,"ACRNEMA_LIBIDO",14)==0)
+                  // si c'est egal
+                  || (memcmp(ple->valeurElem,"CANRME_AILIBOD",14)==0)) {
+                  // en cas d'objet ACRLibido fait sr 1 autre machine) 
+                  e->ACR_LIBIDO =1;
+               }  // fin if memcmp
+               break;
+            } // fin if ple->Num==0x0010
+         } // fin ple->Gr==0x0008
+         plelem = IdLstNext(plelem);
+      } // fin while 
+   } // fin if TrueDicom
+
+   return;
+}
+
+/* ======================================================================= 
+*      _IdDcmRecupLgr
+*
+*      ACR-NEMA :      On a toujours 
+*                              GroupNumber   (2 Octets) 
+*                              ElementNumber (2 Octets) 
+*                              ElementSize   (4 Octets)
+*
+*
+*      DICOM :         On peut avoir (implicit Value Representation)
+*                              GroupNumber   (2 Octets) 
+*                              ElementNumber (2 Octets) 
+*                              ElementSize   (4 Octets)
+*
+*                      On peut avoir (explicit Value Representation)
+*                              GroupNumber         (2 Octets) 
+*                              ElementNumber       (2 Octets) 
+*                              ValueRepresentation (2 Octets) 
+*                              ElementSize         (2 Octets)
+*
+*                      ATTENTION : dans le cas ou ValueRepresentation = OB, OW, SQ, UN
+*                              GroupNumber         (2 Octets) 
+*                              ElementNumber       (2 Octets) 
+*                              ValueRepresentation (2 Octets)
+*                              zone reservee       (2 Octets) 
+*                              ElementSize         (4 Octets)
+*
+*
+*   ======================================================================= */
+/**
+ * \ingroup       dcm
+ * \brief         recupere la longueur d'un champ DICOM.
+ *                     (le fichier doit deja avoir ete ouvert,
+ *                      _IdAcrCheckSwap(ID_DCM_HDR *e) avoir ete appele)
+ *                     et la  partie 'group'  ainsi que la  partie 'elem' 
+ *                     de l'acr_element doivent avoir ete lues.
+ * @param sw                           code swap
+ * @param skippedLength     pointeur sur nombre d'octets que l'on a saute qd la lecture est finie
+ * @param longueurLue       pointeur sur longueur (en nombre d'octets) effectivement lue
+
+ * @return                             longueur retenue pour le champ 
+ */
+
+static guint32 _IdDcmRecupLgr(ID_DCM_HDR *e, int sw, int *skippedLength, int *longueurLue) {
+guint32 l_gr; 
+unsigned short int l_gr_2;
+int i, trouve;
+char VR[5];
+int lgrLue;
+
+/*
+ *   ATTENTION :
+*/
+
+int nbCode=26; // nombre d'elements dans la table de type DICOM_VR definie dans dicom.c
+
+/* ================ */
+
+// ID_DCM_HDR *e sert uniquement de passe-plat pour  __ExplicitVR
+
+
+if (e->__ExplicitVR == 1) {
+       lgrLue=fread (&VR, (size_t)2,(size_t)1, e->fp);
+       VR[2]=0;
+
+       // ATTENTION :
+       // Ce n'est pas parce qu'on a trouve UL la premiere fois qu'on respecte 
+       // Explicit VR tout le temps
+       // (cf e=film ...)
+
+       for(i=0,trouve=0;i<nbCode;i++) {
+               if(memcmp(_ID_dicom_vr[i].dicom_VR,VR,(size_t)2)==0) {
+                       (e->pleCourant)->VR=_ID_dicom_vr[i].dicom_VR;
+                       trouve=1;       
+                       break;
+               }
+       }
+
+       if ( trouve == 0) {
+
+               // On est mal : implicit VR repere
+               // mais ce n'est pas un code connu ...
+               // On reconstitue la longueur
+               
+               if(DEBUG) printf("IdDcmRecupLgr : Explicit VR, mais pas trouve de code connu\n");
+               memcpy(&l_gr, VR,(size_t)2);
+
+               lgrLue=fread ( ((char*)&l_gr)+2, (size_t)2, (size_t)1, e->fp);
+
+               if(sw) l_gr = _IdDcmSWAP_LONG(((guint32)l_gr),sw);
+               
+               if(DEBUG) printf("IdDcmRecupLgr : lgr deduite : %08x , %d\n",l_gr,l_gr);
+               
+               *longueurLue=l_gr;
+               if ( (int)l_gr == -1) { 
+                       l_gr=0;
+               }
+               *skippedLength = 4; 
+               if (DEBUG) printf(" 1 : lgr %08x (%d )skippedLength %d\n",l_gr,l_gr, *skippedLength);
+               return(l_gr);
+       }
+
+       // On repart dans la sequence 'sensee'
+
+       if(DEBUG) printf("VR : [%01x , %01x] (%c%c) en position %d du tableau\n", VR[0],VR[1],VR[0],VR[1],i);
+       //printf(" %d , %s\n", i,_ID_dicom_vr[i].dicom_VR);
+       
+       if (    
+          (!memcmp( VR,"OB",(size_t)2 )) || 
+          (!memcmp( VR,"OW",(size_t)2 )) || 
+          (!memcmp( VR,"SQ",(size_t)2 )) ||
+          (!memcmp( VR,"UN",(size_t)2 )) ) {
+
+       // les 2 octets suivants sont reserves
+
+               if(DEBUG) printf("IdDcmRecupLgr : les 2 octets suivants sont reserves\n");
+                                       //on les saute          
+               fseek(e->fp, 2L,SEEK_CUR);
+               
+                                       //on lit la lgr sur QUATRE octets
+
+               lgrLue=fread (&l_gr, (size_t)4,(size_t)1, e->fp);
+
+               if(sw) l_gr = _IdDcmSWAP_LONG(((guint32)l_gr),sw);
+               *skippedLength = 8;
+
+       } else {
+                                       //on lit la lgr sur DEUX octets
+
+               lgrLue=fread (&l_gr_2, (size_t)2,(size_t)1, e->fp);
+
+               if(sw) l_gr_2 = _IdDcmSWAP_SHORT((unsigned short)l_gr_2,sw);
+               
+               *longueurLue=l_gr_2;
+
+               
+               if ( l_gr_2 == 0xffff) {
+                       l_gr = 0;       
+               } else {
+                       l_gr = l_gr_2;
+               }
+               *skippedLength = 4;
+       }       
+  } else {     // Explicit VR = 0      
+
+                               //on lit la lgr sur QUATRE octets
+
+       lgrLue=fread (&l_gr, (size_t)4,(size_t)1, e->fp);
+
+       if(sw)l_gr=_IdDcmSWAP_LONG(((long)l_gr),sw);
+       *skippedLength = 4;
+  }
+  
+  *longueurLue=l_gr;
+  
+  // Traitement des curiosites sur la longueur
+  
+  if ( (int)l_gr == 0xffffffff)
+       l_gr=0; 
+       
+  if(!memcmp( VR,"SQ",(size_t)2 )) {   // ca annonce une SEQUENCE d'items ?!
+       l_gr=0;                                                 // on lira donc les items de la sequence 
+       if (DEBUG) printf(" SQ trouve : lgr %d \n",l_gr);
+  }
+       
+if (DEBUG) printf(" 2 : lgr %08x (%d) skippedLength %d\n",l_gr,l_gr, *skippedLength);
+  return(l_gr);
+}
similarity index 96%
rename from dcmlib.h
rename to src/gdcmlib.h
index 942870abafbf54e6d270d5518ebf0e3e86cdfc13..2afa1d1797b3b24c56b82b52a81bc4593d71fb35 100644 (file)
--- a/dcmlib.h
@@ -126,7 +126,19 @@ public:
 // Notes:
 // * the gdcmHeader::Set*Tag* family members cannot be defined as protected
 //   (Swig limitations for as Has_a dependency between gdcmFile and gdcmHeader)
-class gdcmHeader {
+class gdcmHeader {     
+       enum EndianType {
+               LittleEndian, 
+               BadLittleEndian,
+               BigEndian, 
+               BadBigEndian};
+       enum FileType {
+               Unknown = 0,
+               TrueDicom,
+               ExplicitVR,
+               ImplicitVR,
+               ACR,
+               ACR_LIBIDO};
 private:
        static DictSet* Dicts;  // Global dictionary container
        Dict* RefPubDict;                       // Public Dictionary
@@ -134,6 +146,11 @@ private:
        int swapcode;
        ElValSet PubElVals;             // Element Values parsed with Public Dictionary
        ElValSet ShaElVals;             // Element Values parsed with Shadow Dictionary
+       FileType filetype;
+       int sw;
+       EndianType CheckSwap();
+       void _setAcrLibido();
+       guint32 _IdDcmRecupLgr(ID_DCM_HDR *e, int sw, int *skippedLength, int *longueurLue);
 protected:
 ///// QUESTION: Maybe Print is a better name than write !?
        int write(ostream&);   
diff --git a/src/orig/dcmutil.c b/src/orig/dcmutil.c
new file mode 100644 (file)
index 0000000..1347721
--- /dev/null
@@ -0,0 +1,1266 @@
+
+#include <idio.h>
+#include <iddicom.h>
+#include <iddcm-restricted.h>
+#include <iderr.h>
+//#include <idprint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <idliste.h>
+
+#ifdef _MSC_VER
+#include <winsock.h>           // Pour ntohs - BigEndianeries -
+#else
+#include <netinet/in.h>        // Pour ntohs - BigEndianeries -
+#endif
+                                                                       
+#define LGR_ENTETE_A_LIRE 256                          // on ne lit plus que le debut
+#define DEBUG 0
+
+static char * var_itoa(void * , int );
+
+static guint32         _IdDcmRecupLgr(ID_DCM_HDR *, int, int*, int *);
+static int     _IdDcmCheckSwap(ID_DCM_HDR *);
+static int     _IdDcmLireEtStockerElement(ID_DCM_HDR *, char **, int,
+                                int, char *, int);
+static char ** _IdDcmInquireImageInfoXXX (ID_DCM_HDR *, char **);    
+
+static void _setAcrLibido(ID_DCM_HDR *);
+
+// -----------------------------------------------------------------
+
+/**
+ * \ingroup       dcm
+ * \brief         Alloue un ID_DCM_HDR
+ * @return        Pointeur sur structure Allouée, NULL si échec 
+ */
+       
+ID_DCM_HDR * IdDcmHdrAlloc () {
+       ID_DCM_HDR *e = (ID_DCM_HDR *) g_malloc0 (sizeof(ID_DCM_HDR));
+       if (!e) return e;
+       
+       e->deb = (char *) g_malloc(LGR_ENTETE_A_LIRE);
+       if (!e->deb) { 
+               g_free(e);
+               printf("Echec alloc ID_DCM_HDR\n");
+       }
+       
+       e->plist = IdLstAlloc();
+
+       if (!e->plist) {
+               g_free(e->deb);
+               g_free(e);
+               printf("Echec alloc ID_DCM_HDR->deb\n");
+               return (ID_DCM_HDR *)NULL;
+       }       
+       return(e);
+}
+
+// ------------------------------------------------------------------
+/**
+ * \ingroup       dcm
+ * \brief         Libere un ID_DCM_HDR
+ * @param e      pointeur sur le ID_DCM_HDR a liberer.
+ * @return        void 
+ */
+
+void IdDcmHdrFree (ID_DCM_HDR * e) {
+
+       if (e) {
+               if (e->deb) g_free(e->deb);
+               if (e->deb) g_free(e->plist); // LIBERER LES ELEMENTS DE LA LISTE AVANT
+               g_free(e);
+       }
+}
+
+/* =======================================================================
+ *     _IdDcmSWAP_SHORT
+ *             remet les octets dans un ordre compatible avec celui du processeur
+ *  ======================================================================= */
+
+short int _IdDcmSWAP_SHORT(short int a,int sw) {
+       if ( (sw==4321)  || (sw==2143) )  
+               a =(((a<<8) & 0x0ff00) | ((a>>8)&0x00ff));
+       return (a);
+}
+
+/* =======================================================================
+ *     _IdDcmSWAP_LONG
+ *             remet les octets dans un ordre compatible avec celui du processeur
+ *  ======================================================================= */
+
+guint32 _IdDcmSWAP_LONG(guint32 a, int sw) {
+/*       ATTENTION: il pourrait y avoir un pb pour les entiers negatifs ...
+ *                                                              
+ */
+   switch (sw) {
+       case 4321 :
+               a=(     ((a<<24) & 0xff000000) | ((a<<8)  & 0x00ff0000)    | 
+                       ((a>>8)  & 0x0000ff00) | ((a>>24) & 0x000000ff) );
+               break;
+
+       case 3412 :
+                       a=(     ((a<<16) & 0xffff0000) | ((a>>16) & 0x0000ffff) );
+               break;
+
+       case 2143 :
+               a=(    ((a<<8) & 0xff00ff00) | ((a>>8) & 0x00ff00ff)  );
+               break;
+       default :
+               printf("\n\n\n *******\n erreur code swap ?!?\n\n\n");
+               a=0;
+   }
+  return(a);
+}
+
+// -----------------------------------------------------------------------------------
+/**
+ * \ingroup       dcm
+ * \brief         renvoie un pointeur sur le ID_DCM_HDR correspondant au fichier
+ * @param filename      Nom du fichier ACR / LibIDO / DICOM
+ * @return       le ID_DCM_HDR 
+ */
+ID_DCM_HDR * IdDcmGetHeader(char *filename) {
+
+ID_DCM_HDR *e=NULL;
+_ID_DCM_ELEM * ple;
+
+       e = IdDcmHdrAlloc();
+       if(!e) {
+               printf("echec alloc HDR \n");
+               return(NULL);
+       }
+       
+       if((e->fp=fopen(filename,ID_RFILE_BIN))==0) {           // OK
+               // IdDcmHdrAFree(e);
+               printf ("echec ouverture  %s\n",filename);
+               return (NULL);
+        }
+       
+       e->filename = strdup(filename);
+        
+       fseek(e->fp, 0L, SEEK_END);
+       /*
+        * obtains the current value of the file-position    
+        * indicator for the stream pointed to by stream      
+        */
+       e->taille_fich = ftell(e->fp);
+       
+       if(DEBUG) printf("IdDcmGetHeader : lgr fich %f\n",(float)e->taille_fich); // FORMAT IMPRESSION long int ???
+       
+       rewind(e->fp);
+               
+       e->sw= _IdDcmCheckSwap(e);
+       e->__NumeroGroupePrecedent = 0; // Pour etre sur que le premier sera + grand
+       e->grPixelTrouve = 0;
+       e->PixelsTrouves = 0;
+
+       
+       while ( (ple=_IdDcmReadNextElement(e,e->sw)) ) {
+               IdLstAddLast(e->plist, ple);
+       }
+       
+       // Positionnement ACR_LIBIDO
+       
+       _setAcrLibido(e);
+               
+       fclose(e->fp);
+       return (e);
+}
+
+static void _setAcrLibido(ID_DCM_HDR *e) {
+
+_ID_DCM_ELEM * ple;
+PLIST_ELEMENT plelem;
+PLIST pl;
+
+       // Positionnement ACR_LIBIDO
+       if(DEBUG) printf("Entree ds _setAcrLibido\n");
+
+       e->ACR_LIBIDO = 0;
+       if ( e->__TrueDicom == 0) {
+               // Recognition Code  --> n'existe plus en DICOM V3 ...
+               
+               pl = e->plist;
+               plelem = IdLstFirst(pl);
+               while (plelem) {
+                       ple= IdLstPtrObj(plelem);
+                       if(DEBUG) printf("gr %04x Num %04x\n", ple->Gr, ple->Num);
+                       if(ple->Gr >  0x0008) break;            // On a depasse
+                       if(ple->Gr == 0x0008) {
+                               if(ple->Num >  0x0010) break;   // On a depasse
+                               if(ple->Num == 0x0010) {
+                                       if (  (memcmp(ple->valeurElem,"ACRNEMA_LIBIDO",14)==0)
+                                               // si c'est egal
+                                               || (memcmp(ple->valeurElem,"CANRME_AILIBOD",14)==0)) {
+                                               // en cas d'objet ACRLibido fait sr 1 autre machine) 
+                                               e->ACR_LIBIDO =1;       
+                                       }  // fin if memcmp
+                                       break;          
+                               } // fin if ple->Num==0x0010
+                       } // fin ple->Gr==0x0008
+                       plelem = IdLstNext(plelem);
+               } // fin while 
+       } // fin if TrueDicom
+       
+               if(DEBUG) printf("ACR_LIBIDO = %d\n", e->ACR_LIBIDO);
+       return;
+}
+/* ======================================================================= 
+*      _IdDcmRecupLgr
+*
+*      ACR-NEMA :      On a toujours 
+*                              GroupNumber   (2 Octets) 
+*                              ElementNumber (2 Octets) 
+*                              ElementSize   (4 Octets)
+*
+*
+*      DICOM :         On peut avoir (implicit Value Representation)
+*                              GroupNumber   (2 Octets) 
+*                              ElementNumber (2 Octets) 
+*                              ElementSize   (4 Octets)
+*
+*                      On peut avoir (explicit Value Representation)
+*                              GroupNumber         (2 Octets) 
+*                              ElementNumber       (2 Octets) 
+*                              ValueRepresentation (2 Octets) 
+*                              ElementSize         (2 Octets)
+*
+*                      ATTENTION : dans le cas ou ValueRepresentation = OB, OW, SQ, UN
+*                              GroupNumber         (2 Octets) 
+*                              ElementNumber       (2 Octets) 
+*                              ValueRepresentation (2 Octets)
+*                              zone reservee       (2 Octets) 
+*                              ElementSize         (4 Octets)
+*
+*
+*   ======================================================================= */
+/**
+ * \ingroup       dcm
+ * \brief         recupere la longueur d'un champ DICOM.
+ *                     (le fichier doit deja avoir ete ouvert,
+ *                      _IdAcrCheckSwap(ID_DCM_HDR *e) avoir ete appele)
+ *                     et la  partie 'group'  ainsi que la  partie 'elem' 
+ *                     de l'acr_element doivent avoir ete lues.
+ * @param sw                           code swap
+ * @param skippedLength     pointeur sur nombre d'octets que l'on a saute qd la lecture est finie
+ * @param longueurLue       pointeur sur longueur (en nombre d'octets) effectivement lue
+
+ * @return                             longueur retenue pour le champ 
+ */
+
+static guint32 _IdDcmRecupLgr(ID_DCM_HDR *e, int sw, int *skippedLength, int *longueurLue) {
+guint32 l_gr; 
+unsigned short int l_gr_2;
+int i, trouve;
+char VR[5];
+int lgrLue;
+
+/*
+ *   ATTENTION :
+*/
+
+int nbCode=26; // nombre d'elements dans la table de type DICOM_VR definie dans dicom.c
+
+/* ================ */
+
+// ID_DCM_HDR *e sert uniquement de passe-plat pour  __ExplicitVR
+
+
+if (e->__ExplicitVR == 1) {
+       lgrLue=fread (&VR, (size_t)2,(size_t)1, e->fp);
+       VR[2]=0;
+
+       // ATTENTION :
+       // Ce n'est pas parce qu'on a trouve UL la premiere fois qu'on respecte 
+       // Explicit VR tout le temps
+       // (cf e=film ...)
+
+       for(i=0,trouve=0;i<nbCode;i++) {
+               if(memcmp(_ID_dicom_vr[i].dicom_VR,VR,(size_t)2)==0) {
+                       (e->pleCourant)->VR=_ID_dicom_vr[i].dicom_VR;
+                       trouve=1;       
+                       break;
+               }
+       }
+
+       if ( trouve == 0) {
+
+               // On est mal : implicit VR repere
+               // mais ce n'est pas un code connu ...
+               // On reconstitue la longueur
+               
+               if(DEBUG) printf("IdDcmRecupLgr : Explicit VR, mais pas trouve de code connu\n");
+               memcpy(&l_gr, VR,(size_t)2);
+
+               lgrLue=fread ( ((char*)&l_gr)+2, (size_t)2, (size_t)1, e->fp);
+
+               if(sw) l_gr = _IdDcmSWAP_LONG(((guint32)l_gr),sw);
+               
+               if(DEBUG) printf("IdDcmRecupLgr : lgr deduite : %08x , %d\n",l_gr,l_gr);
+               
+               *longueurLue=l_gr;
+               if ( (int)l_gr == -1) { 
+                       l_gr=0;
+               }
+               *skippedLength = 4; 
+               if (DEBUG) printf(" 1 : lgr %08x (%d )skippedLength %d\n",l_gr,l_gr, *skippedLength);
+               return(l_gr);
+       }
+
+       // On repart dans la sequence 'sensee'
+
+       if(DEBUG) printf("VR : [%01x , %01x] (%c%c) en position %d du tableau\n", VR[0],VR[1],VR[0],VR[1],i);
+       //printf(" %d , %s\n", i,_ID_dicom_vr[i].dicom_VR);
+       
+       if (    
+          (!memcmp( VR,"OB",(size_t)2 )) || 
+          (!memcmp( VR,"OW",(size_t)2 )) || 
+          (!memcmp( VR,"SQ",(size_t)2 )) ||
+          (!memcmp( VR,"UN",(size_t)2 )) ) {
+
+       // les 2 octets suivants sont reserves
+
+               if(DEBUG) printf("IdDcmRecupLgr : les 2 octets suivants sont reserves\n");
+                                       //on les saute          
+               fseek(e->fp, 2L,SEEK_CUR);
+               
+                                       //on lit la lgr sur QUATRE octets
+
+               lgrLue=fread (&l_gr, (size_t)4,(size_t)1, e->fp);
+
+               if(sw) l_gr = _IdDcmSWAP_LONG(((guint32)l_gr),sw);
+               *skippedLength = 8;
+
+       } else {
+                                       //on lit la lgr sur DEUX octets
+
+               lgrLue=fread (&l_gr_2, (size_t)2,(size_t)1, e->fp);
+
+               if(sw) l_gr_2 = _IdDcmSWAP_SHORT((unsigned short)l_gr_2,sw);
+               
+               *longueurLue=l_gr_2;
+
+               
+               if ( l_gr_2 == 0xffff) {
+                       l_gr = 0;       
+               } else {
+                       l_gr = l_gr_2;
+               }
+               *skippedLength = 4;
+       }       
+  } else {     // Explicit VR = 0      
+
+                               //on lit la lgr sur QUATRE octets
+
+       lgrLue=fread (&l_gr, (size_t)4,(size_t)1, e->fp);
+
+       if(sw)l_gr=_IdDcmSWAP_LONG(((long)l_gr),sw);
+       *skippedLength = 4;
+  }
+  
+  *longueurLue=l_gr;
+  
+  // Traitement des curiosites sur la longueur
+  
+  if ( (int)l_gr == 0xffffffff)
+       l_gr=0; 
+       
+  if(!memcmp( VR,"SQ",(size_t)2 )) {   // ca annonce une SEQUENCE d'items ?!
+       l_gr=0;                                                 // on lira donc les items de la sequence 
+       if (DEBUG) printf(" SQ trouve : lgr %d \n",l_gr);
+  }
+       
+if (DEBUG) printf(" 2 : lgr %08x (%d) skippedLength %d\n",l_gr,l_gr, *skippedLength);
+  return(l_gr);
+}
+
+/* =======================================================================
+       _IdDcmReadNextElement
+
+                       lit l'acr_element courant 
+                       le fichier doit deja avoir ete ouvert, 
+                 
+   ======================================================================= */
+
+/**
+ * \ingroup       dcm
+ * \brief         lit le dicom_element suivant.
+ *                     (le fichier doit deja avoir ete ouvert,
+ *                      _IdAcrCheckSwap(ID_DCM_HDR *e) avoir ete appele)
+ * @param e      ID_DCM_HDR  dans lequel effectuer la recherche.
+ * @param sw           code swap.
+ * @return             En cas de succes, 1 
+ *                     0 en cas d'echec.
+ */
+
+_ID_DCM_ELEM * _IdDcmReadNextElement(ID_DCM_HDR * e, int sw) {
+unsigned short g;
+unsigned short n;
+guint32 l;
+long int posFich;
+int skL;
+size_t lgrLue;
+int i;
+DICOM_ELEMENTS *t;
+_ID_DCM_ELEM *nouvDcmElem;
+
+       if (DEBUG) printf(" ===> entree ds _IdDcmReadNextElement\n");
+               
+       if(e->offsetCourant ==  e->taille_fich) { // On a atteint la fin du fichier
+               if (DEBUG) printf(" On a atteint la fin du fichier\n");
+               return(NULL);
+       } else {
+               if (DEBUG) {
+                               posFich = ftell(e->fp);
+                               printf("lgrFich %f positionDsFich %f offset courant %f\n", 
+                                                       (float)e->taille_fich,
+                                                       (float)posFich,
+                                                       (float)e->offsetCourant);
+               }
+       } 
+       
+       nouvDcmElem = (_ID_DCM_ELEM *)g_malloc(sizeof(_ID_DCM_ELEM));
+       if (!nouvDcmElem) {
+               printf("Echec alloc _ID_DCM_ELEM *nouvDcmElem\n");
+               return(NULL);
+       }
+       
+       e->pleCourant = nouvDcmElem;
+       
+       // ------------------------- Lecture Num group : g
+
+       lgrLue=fread (&g, (size_t)2,(size_t)1, e->fp);
+       
+       if (feof(e->fp))  {
+               if (DEBUG) printf("_IdDcmReadNextElement : eof trouve\n");                      
+               return (NULL);
+       }
+       if (ferror(e->fp)){
+               if (DEBUG) printf(" IdDcmReadNextElement : echec lecture NumGr\n");
+               return (NULL);
+       }
+
+       if (DEBUG) printf("_IdDcmReadNextElement : "
+                                       " gr  %04x\n",g );
+                                               
+       if (sw) g=_IdDcmSWAP_SHORT(((short)g),sw);
+       
+       nouvDcmElem->Gr=g;
+       e->__NumeroGroupePrecedent =g;
+       
+       // ------------------------- Lecture Num Elem : n
+
+       lgrLue=fread (&n, (size_t)2,(size_t)1, e->fp);
+       
+       if (feof(e->fp))  {
+               if (DEBUG) printf("_IdDcmReadNextElement : eof trouve\n");                      
+               return (NULL);
+       }
+       if (ferror(e->fp)){
+               if (DEBUG) printf(" IdDcmReadNextElement : echec lecture NumElem\n");
+               return (NULL);
+       }
+       
+       if (DEBUG) printf("_IdDcmReadNextElement : "
+                                       " num %04x\n",n );
+
+       if(sw)n=_IdDcmSWAP_SHORT(((short)n),sw);
+       nouvDcmElem->Num=n;
+
+       // ------------------------- Lecture longueur element : l
+                                                               
+       l = _IdDcmRecupLgr(e, sw, &skL, &nouvDcmElem->LgrLueElem);
+                       
+       if(g==0xfffe) l=0;  // pour sauter les indicateurs de 'SQ'
+
+       nouvDcmElem->LgrElem=l;
+
+       if (DEBUG) if (n!=0) printf("_IdDcmReadNextElement : "
+                                       " gr %04x\tnum %04x\tlong %08x (%d)\n",
+                                       g,n,l,l);                               
+                                       
+       // ------------------------- Lecture Valeur element 
+               
+       nouvDcmElem->valeurElem = g_malloc(l+1);
+       if(nouvDcmElem->valeurElem) {
+               nouvDcmElem->valeurElem[l]= 0;
+       } else {        
+               if (DEBUG) printf(" IdDcmReadNextElement : echec Alloc valeurElem lgr : %d\n",l);
+               return (NULL);
+       }       
+       
+               // ------------------------ On n'amene pas en mémoire les Elem 'trop longs'
+                       
+       lgrLue=fread (nouvDcmElem->valeurElem, (size_t)l,(size_t)1, e->fp);     
+       
+       e->offsetCourant +=  2 + 2 + skL; // gr +  num + lgr
+       nouvDcmElem->Offset = e->offsetCourant;
+       e->offsetCourant += l;                                                  // debut elem suivant
+       
+
+       // ------------------------- Doit-on le Swapper ?
+       
+
+       if ((n==0) && sw)  {    // n=0 : lgr du groupe : guint32
+                       *(guint32 *) nouvDcmElem->valeurElem =
+                                       _IdDcmSWAP_LONG  ((*(guint32 *) nouvDcmElem->valeurElem),sw);  
+                       nouvDcmElem->Swap = 1;
+       } 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 */
+                                       if (DEBUG) 
+                                               printf("Consultation Dictionary DICOM g %04x n %0xx l %d\n",
+                                                               g,n,l);
+
+                                       for (t=_ID_dicom_elements; t->dicom_group!=0xffff; t++) {
+                                               if( (t->dicom_group==g) && (t->dicom_elem==n) ) {
+                                                               nouvDcmElem->VR= t->dicom_type;
+                                                               break;
+                                               }
+                                       }
+                                       if (    (strcmp(t->dicom_type,"UL") ==0) 
+                                                || (strcmp(t->dicom_type,"US") ==0)
+                                                || (strcmp(t->dicom_type,"SL") ==0) 
+                                                || (strcmp(t->dicom_type,"SS") ==0) 
+                                                || (g == 0x0028 && 
+                                                  ( n == 0x0005 || n == 0x0200) )      ) { // seuls (28,5) de vr RET
+                                                                                                                               //  et (28,200) sont des entiers
+                                                                                                                               // ... jusqu'a preuve du contraire
+                                               nouvDcmElem->Swap = 1;
+
+                                               if(l==4) { 
+                                                       *(guint32 *) nouvDcmElem->valeurElem=
+                                                               _IdDcmSWAP_LONG  ((*(guint32 *) nouvDcmElem->valeurElem),sw); 
+                                                       nouvDcmElem->valInt =
+                                                               _IdDcmSWAP_LONG  ((*(guint32 *) nouvDcmElem->valeurElem),sw);           
+                                               } else {
+                                                       if(l==2) 
+                                                   *(unsigned short *)   nouvDcmElem->valeurElem=
+                                                       _IdDcmSWAP_SHORT ((*(unsigned short *)nouvDcmElem->valeurElem),sw);
+                                                       nouvDcmElem->valShort =
+                                                       _IdDcmSWAP_SHORT ((*(unsigned short *)nouvDcmElem->valeurElem),sw);
+                                                }
+                                       }
+                               } /* fin if l==2 ==4 */
+                       } /* fin if g pair */
+               } /* fin sw */  
+       }
+       
+       
+       // ------------------------- A-t-on trouve l'info donnant le 'num groupe' des Pixels ?
+       
+                                                               
+       if (!e->grPixelTrouve) {                        // on n a pas encore trouve les pixels
+               if (g > 0x0028) {
+                               if (n > 0x0200 || g == 0x7FE0 ) {  // on a depasse (28,200)
+                                       e->grPixel  = 0x7FE0;
+                                       e->numPixel = 0x0010;
+                                       e->grPixelTrouve = 1;
+                                       if (DEBUG) printf("------------------------grPixel %04x numPixel %04x\n",
+                                                                               e->grPixel,e->numPixel);
+                               }
+                                               
+               } else {                                        // on est sur (28,200)
+                       if (g == 0x0028) {
+                               if (n == 0x0200) {
+                                       e->grPixelTrouve = 1;
+                                       for(i=0;i<4;i++)
+                                               *((char*)(&e->grPixel)+i) = *(nouvDcmElem->valeurElem+i); 
+                                       
+                                       
+                                       if (DEBUG) printf("------------------------GrPixel %04x\n",
+                                                                               e->grPixel);
+                                       
+                                       if (e->grPixel != 0x7FE0)               // Vieux pb Philips
+                                               e->numPixel = 0x1010;           // encore utile ??
+                                       else
+                                               e->numPixel = 0x0010;
+                                               if (DEBUG) printf("------------------------grPixel %04x numPixel %04x\n",
+                                                                                       e->grPixel,e->numPixel);
+                               }
+                       }       
+               }       
+       } else {                                        // on vient de trouver les pixels
+               if (g == e->grPixel) {
+                       if (n == e->numPixel) {
+                               e->PixelPosition = nouvDcmElem->Offset; 
+                               e->PixelsTrouves = 1;
+                       if (DEBUG) printf(" \t===> Pixels Trouves\n");                                  
+                       }       
+               }
+       }
+               
+       e->nbElem ++;
+       //printf("nb Elem %d\n",e->nbElem);
+       return(nouvDcmElem);
+}
+
+/* =======================================================================
+
+       _IdDcmCheckSwap
+               La seule maniere sure que l'on aie pour determiner 
+               si on est en    LITTLE_ENDIAN,     BIG-ENDIAN, 
+                                               BAD-LITTLE-ENDIAN, BAD-BIG-ENDIAN
+               est de trouver l'element qui donne la longueur d'un 'GROUP'
+               (on sait que la longueur de cet element vaut 0x00000004)
+               et de regarder comment cette longueur est codee en memoire  
+
+               Le probleme vient de ce que parfois, il n'y en a pas ...
+
+               On fait alors le pari qu'on a a faire a du LITTLE_ENDIAN propre.
+               (Ce qui est la norme -pas respectee- depuis ACR-NEMA)
+               Si ce n'est pas le cas, on ne peut rien faire.
+
+               (il faudrait avoir des fonctions auxquelles 
+                on passe le code Swap en parametre, pour faire des essais 'manuels')
+
+   ======================================================================= */
+
+static int
+_IdDcmCheckSwap(ID_DCM_HDR * e) {
+guint32  s, x=4;  // x : pour ntohs
+
+int sw;
+int lgrLue;
+char * entCur;
+char deb[LGR_ENTETE_A_LIRE];
+
+
+// On teste le processeur
+
+       if (x==ntohs(x)) {      /* si le HostByteOrder est le meme que le NetworkByteOrder  */ 
+               e->net2host = 1;
+       } else {
+               e->net2host = 0;
+       }
+       
+       //printf("\t\t\t\te->net2host %d \n",e->net2host);
+       
+/* On commence par verifier si c'est du DICOM 'actuel' */
+/*                                      -------------  */
+
+       lgrLue = fread(deb,1,LGR_ENTETE_A_LIRE,e->fp);
+
+       entCur = deb+128;
+       if(memcmp(entCur, "DICM", (size_t)4) == 0) {
+               e->__TrueDicom=1;
+               if (DEBUG) printf ("_IdDcmCheckSwap : C est du DICOM actuel \n");
+       } else {
+               e->__TrueDicom=0;
+               if (DEBUG) printf ("_IdDcmCheckSwap : Ce n'est PAS du DICOM actuel\n"); 
+       }
+
+       if(e->__TrueDicom) {
+               entCur = deb+136;       /* on saute le File Preamble (souvent a ZERO) : 128 Octets */
+                                                       /* le DICM, et le 0002, 0000                                */
+               if(memcmp(entCur, "UL", (size_t)2) == 0) {
+                       /* les 2 premiers octets de la lgr peuvent valoir UL --> Explicit VR */
+                       e->__ExplicitVR = 1;
+                       if (DEBUG)      printf ("_IdDcmCheckSwap : Explicit VR\n");
+                       } else {
+                               e->__ExplicitVR = 0;
+                       if (DEBUG)      printf ("_IdDcmCheckSwap : PAS Explicit VR\n");
+                       }
+
+               if (e->net2host == 0) { /* si le HostByteOrder est different du NetworkByteOrder  */ 
+                       sw = 0;                 /* on est sur PC ou DEC --> LITTLE-ENDIAN -> Rien a faire */
+                       if (DEBUG) printf("HostByteOrder = NetworkByteOrder\n");
+       
+               } else {                /* on est sur une Sun ou une SGI        */
+                       sw = 4321;
+                       if (DEBUG) printf("HostByteOrder != NetworkByteOrder\n");
+               }
+                
+               rewind(e->fp);
+               fseek (e->fp, 132L, SEEK_SET); //On se positionne sur le debut des info
+               e->offsetCourant=132;
+               return sw;
+
+       } /* fin TrueDicom */
+       
+/* -----  SINON ----- */
+       
+/* Si c'est de l'ACR 'propre', la lgr du premier element du groupe est FORCEMENT 4 */
+
+       entCur=deb + 4;
+       s=str2num(entCur,int);
+                
+       switch (s) {
+               case 0x00040000 :
+                       sw=3412; if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
+                       break;
+               case 0x04000000 :
+                       sw=4321; if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
+                       break;
+               case 0x00000400 :
+                       sw=2143; if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
+                       break;
+               case 0x00000004 :
+                       sw=0;    if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
+                       break;
+               default :
+                       sw = -1;
+                       if (DEBUG) printf (" Pas trouve l info de Swap; On va parier\n");
+       }
+               
+/* Si c'est de l'ACR 'pas propre', il manque la lgr du groupe          */
+                               
+       if(sw==-1) {                                            
+               /* On n'a pas trouve l'info de swap     28/11/2000 JPR                                          */
+               /* Si c'est du VRAI ACR NEMA  si on est sur une DEC ou un PC swap=0, SUN ou SGI SWAP=4321       */
+               /* si c'est du RAW, ca degagera + tard                                                          */
+         
+               if (DEBUG) printf("On force la chance \n");
+
+               if (x!=ntohs(x))        /* si le HostByteOrder est different du NetworkByteOrder  */ 
+                       sw = 0;                 /* on est sur PC ou DEC --> LITTLE-ENDIAN -> Rien a faire */
+               else
+                       sw = 4321; /* on est sur Sun ou SGI */          
+
+       }
+       rewind(e->fp);          // les info commencent au debut
+       e->offsetCourant=0;
+       return (sw);
+}
+
+
+//
+/* ================================================================== */
+//
+
+/**
+ * \ingroup       dcm
+ * \brief      renvoie dans un tableau de chaines de caracteres
+               la description des info pertinentes d'une image ACR /DCM
+               (la soixantaine de champs utiles)
+               a partir du nom du fichier
+ * 
+ * @param filename     Nom du fichier.
+ * @return             ID_DCM_HDR
+ * 
+ * 
+ * Pour avoir la liste a jour des elements renvoyes dans ce tableau,
+ * Consulter src/idacr.h et src/dicom.c
+ * 
+*/
+/* Pour rajouter une entree ici,
+
+       penser a modifier le fichier dicom.c
+       penser a modifier la fonction idacr.h
+
+       pour maintenir la coherence.
+*/
+
+char **
+IdDcmInquireImageInfoFromFile(char *filename) {
+
+       ID_DCM_HDR *e;
+       char **imageInfo;
+
+       e = IdDcmGetHeader(filename);
+
+       if (!e) {
+               printf("fichier %s : gros problème :\n", filename);
+               IdErrno = IDERR_NON_ACR_FILE;
+               return (0);
+       }
+
+       imageInfo = _IdDcmInquireImageInfoXXX(e, NULL);
+       
+       // LIBERER LE HEADER
+
+       return (imageInfo);
+}
+
+
+//
+/* ================================================================== */
+//
+
+/**
+ * \ingroup       dcm
+ * \brief      renvoie dans un tableau de chaines de caracteres
+ *             la description des info pertinentes d'une image ACR /DCM
+ *             a partir d'un ID_DCM_HDR deja fabrique  
+ *
+ * @param e    ID_DCM_HDR de l'image
+ * @return     Tableau :
+ *
+ * Pour avoir la liste a jour des elements renvoyes dans ce tableau,
+ * Consulter src/idacr.h et src/dicom.c
+ * 
+*/
+
+
+/* Pour rajouter une entree ici,
+
+       penser a modifier le fichier dicom.c
+       penser a modifier la fonction idacr.h
+
+       pour maintenir la coherence.
+*/
+
+char **
+IdDcmInquireImageInfoFromDcmHdr(ID_DCM_HDR *e)
+{
+       char **imageInfo;
+
+       if (!e) {
+               printf("ID_DCM_HDR pas alloue\n");
+               IdErrno = IDERR_NON_ACR_FILE;
+               return (0);
+       }
+
+       imageInfo = _IdDcmInquireImageInfoXXX(e, NULL);
+
+       return (imageInfo);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static char **
+_IdDcmInquireImageInfoXXX(ID_DCM_HDR *e, char **imageInfo)
+{
+
+int boolTrouveQqChose=0,trouv,k;
+
+DICOM_INFO *t;
+t = _ID_dicom_info;
+       
+       if (!imageInfo)
+               imageInfo =
+                   (char **) g_malloc0((_ID_Number_of_Items + 1) *
+                                       sizeof(char *));
+
+       for(k=0;k<_ID_Number_of_Items;k++) {
+               trouv=_IdDcmLireEtStockerElement(e, imageInfo,t[k].dicom_group, t[k].dicom_elem,
+                                  t[k].dicom_info_libelle, t[k].dicom_info_ind);
+               if(trouv) boolTrouveQqChose=1;
+       }
+
+        if(boolTrouveQqChose)
+               return (imageInfo);
+       else
+               return(0);
+}
+
+/* -----------------------------------------------------------------------
+*      ID_DCM_HDR *e :                  doit avoir ete cree   dans l'appelant
+*       char **TableauImageInfo : doit avoir ete alloue dans l'appelant; 
+*                               ses elements sont alloues dans la fonction
+*      int numGroupe :          gr et el du Tag DICOM
+*      int numElem
+*      char *nomElem :          libelle imprime si element pas trouve
+*      int position :           indice dans TableauImageInfo
+  -----------------------------------------------------------------------*/
+static int 
+_IdDcmLireEtStockerElement(ID_DCM_HDR *e, char **TableauImageInfo, int numGroupe,
+                       int numElem, char *nomElem, int position) {
+       int z;
+       char *chaine;
+
+       /*
+        * Lecture Element 
+        */
+        //if (!( chaine = _IdDcmReadElement(numGroupe, numElem, e) )) {
+       if (!( chaine = _IdDcmReadElementNoSQ(numGroupe, numElem, e) )) {
+
+               if (DEBUG)
+                       printf
+                           ("%d : _IdDcmLireEtStockerElement : "
+                            "%s (%04x,%04x) pas trouve \n",
+                            position, nomElem, numGroupe, numElem);
+
+               return (0);
+       } else {
+               if (DEBUG)
+                       printf
+                           ("%d : _IdDcmLireEtStockerElement : "
+                            "%s (%04x,%04x) \t[%s] \n",
+                            position, nomElem, numGroupe, numElem,chaine);
+
+               z = strlen(chaine);
+               while (chaine[z] == ' ') {
+                       chaine[z] = 0;
+                       z--;
+               }
+
+               TableauImageInfo[position] =
+                   (char *) g_malloc(1 + strlen(chaine));
+               strcpy(TableauImageInfo[position], chaine);
+               if (DEBUG)
+                       printf
+                           ("%d : %s (_IdDcmLireEtStockerElement : "
+                            "%04x,%04x)\t[%s]\n",
+                            position, nomElem, numGroupe, numElem,
+                            chaine);
+
+               return (1);
+       }
+}
+
+// Converts an integer represented with num_byte bytes within the
+// buffer buff to a string.
+// Refer to comp.lang.faq FAQ, question 12.21 : How can I tell how much
+// destination buffer space I'll need for an arbitrary sprintf call? How can
+// I avoid overflowing the destination buffer with sprintf? 
+
+static char * var_itoa(void * buff, int num_byte)
+{
+       char * retbuf;
+
+       // We double the recommended value since we also have to deal
+       // with long integers. Pfff...
+       retbuf = g_malloc(2 * ( (sizeof(int) * CHAR_BIT + 2) / 3 + 1 + 1));
+       switch (num_byte) {
+       case 2:
+               sprintf(retbuf, "%d",  *((int*)buff));
+               break;
+       case 4:
+               sprintf(retbuf, "%dl", *((int*)buff));
+               break;
+       default:
+               sprintf(retbuf, "var_itoa?????");
+       }
+       return retbuf;
+}
+
+
+/* =======================================================================
+       int _IdStrGetDicomTag(char * label, int *gr, int * num, char *vr)
+
+                     recherche le Dicom tag d'un libelle donne
+                       par inspection du Dictionnaire DICOM
+                          (retourne 0 si pas trouve)                        
+   ======================================================================= */
+   
+
+
+static int _IdStrGetDcmTag (char* libelle, unsigned long *gr, unsigned long *num, char **vr) {
+
+DICOM_ELEMENTS *t;
+int i;
+
+t=_ID_dicom_elements;
+
+for (i=0; t[i].dicom_group != 0xffff; i++) {
+       if( strcmp(t[i].dicom_libelle, libelle) ==0 )
+
+        {
+               *gr= t[i].dicom_group;
+               *num=t[i].dicom_elem;
+                *vr =t[i].dicom_type;
+               return(1);
+       }
+}
+return(0);
+
+}
+
+
+/**
+ * \ingroup       dcm
+ * \brief         Tente de lire un dicom_element a partir de son libelle. Le
+ *                resultat est range dans buff.
+ * @param libelle Libelle de l'acr_element a lire. Il s'agit du dernier
+ *                champ de la variable globale _ID_dicom_elements, tel que
+ *                "Group Length", "Priority" ou encore "AE Title".
+ * @param e      ID_DCM_HDR dans lequel effectuer la recherche.
+ * @param vr      DICOM_VR (cf la variable globale _ID_dicom_vr) retourne',
+ *                pour permettre a l'appelant d'interpreter le contenu de buff.
+ * @param buff    Ou placer l'acr_element en cas de succes. Si NULL, 
+ *                l'allocation est faite localement.
+ * @return        En cas de succes, le contenu de l'acr_element lu. Null
+ *                en cas d'echec.
+ */
+char *
+_IdDcmReadElementFromLabel(char *libelle, ID_DCM_HDR *e, char * vr, void *buff) { 
+       
+       int i;
+       unsigned long gr;
+       unsigned long num;
+       char * caster;
+       
+       i = _IdStrGetDcmTag (libelle, &gr, &num, &vr);
+       
+       if (i == 0) {
+               if (DEBUG) printf("champ [%s] pas trouve\n",libelle);
+               caster = g_malloc(4);
+               sprintf(caster, "???");
+               return (caster);
+               //return (NULL);
+       }
+       buff = _IdDcmReadElement(gr, num, e);
+       if (buff == 0) {
+               caster = g_malloc(4);
+               sprintf(caster, "???");
+               return (caster);
+       }
+       if ( (strcmp(vr,"UL") != 0)
+         && (strcmp(vr,"US") != 0)
+         && (strcmp(vr,"SL") != 0)
+          && (strcmp(vr,"SS") != 0)
+         && (gr != 0x0028 || 
+               ( num != 0x0005 && num != 0x0200) ) ) { 
+                                                               // les champs de vr RET sont des caract
+                                                       // sauf (28,5) et (28,200) Pixel Location
+               return((void *) strdup(buff));
+       }
+       if ( (strcmp(vr, "US") == 0)
+         || (strcmp(vr, "SS") == 0)
+          || (gr == 0x0028 && 
+               (num == 0x0005  || num == 0x0200) )     ) {     // les champs de vr RET sont des caract
+                                                                                       // sauf (28,5) et (28,200) Pixel Location
+               // Buff should contain an int16
+               caster = var_itoa(buff, 2);
+               return(caster);
+       }
+        if ( (strcmp(vr,"UL") == 0)
+          || (strcmp(vr,"SL") == 0) ) {
+               // Buff should contain a guint32
+               caster = var_itoa(buff, 2);
+               return(caster);
+       }
+       if (DEBUG) printf("impossible de passer ici, mais le compilo rale\n");
+       return (NULL);
+
+}
+
+
+//
+/* ============================================================================= */
+//
+
+
+
+/* ----------------------------------------------------------------------- */
+static void 
+_IdImprimerElement(char **TableauImageInfo, int numGroupe,
+                      int numElem, char *nomElem, int position)
+{
+       if (!TableauImageInfo[position])
+               printf("%d : %s \t(%04x,%04x)  pas trouve \n", position,
+                        nomElem, numGroupe, numElem);
+       else
+               printf("%d : %s \t(%04x,%04x)\t[%s]\n", position,
+                        nomElem, numGroupe, numElem,
+                        TableauImageInfo[position]);
+}
+
+/* ----------------------------------------------------------------------- */
+
+/**
+* \ingroup       dcm
+* \brief       imprime la description des info 'pertinentes' d'une image DICOM
+*              obtenue par IdDcmInquireImageInfoFromXXX (File/DcmHdr)
+*
+* @param TableauImageInfo      Tableau des info.
+* 
+* Pour avoir la liste a jour des DICOM Elements renvoyes par IdDcmInquireImageInfo
+* Consultez le fichier src/dicom.c
+*
+* @return              1 : OK
+*                      0 : pointeur sur Tableau NULL
+*/
+
+int
+IdDcmPrintImageInfo(char **TableauImageInfo) {
+
+int k;
+DICOM_INFO *t;
+t = _ID_dicom_info;
+
+       if (!TableauImageInfo) return(0);
+
+       for(k=0;k<_ID_Number_of_Items;k++) {
+               _IdImprimerElement(TableauImageInfo, t[k].dicom_group, 
+                                               t[k].dicom_elem, 
+                                               t[k].dicom_info_libelle, 
+                                               t[k].dicom_info_ind);
+       }
+       return (1);
+}
+
+
+
+/* ----------------------------------------------------------------------- */
+
+
+void IdDcmAffDcmHdr(ID_DCM_HDR *e, int npriv, int noffset) {
+
+
+DICOM_ELEMENTS *t = NULL;
+PLIST pl;
+PLIST_ELEMENT plelem; 
+_ID_DCM_ELEM *ple;
+
+       /* MANQUE le retrait, avant impression en %s, des caract non ASCII */
+       
+       pl=e->plist;
+       plelem = IdLstFirst(pl);
+
+       while (plelem) {
+       
+               ple= IdLstPtrObj(plelem);       // le _ID_DCM_ELEM  pointé par le PLIST_ELEMENT
+
+               if (ple->Num==0) { 
+                       if(!npriv) printf("\n"); 
+                } else { 
+                       for (t=_ID_dicom_elements; t->dicom_group!=0xffff; t++) {
+                               if( (t->dicom_group==ple->Gr) && (t->dicom_elem==ple->Num) ) break;
+                       }
+               }
+               if(!(ple->Gr%2) || !npriv) {
+
+                       if (noffset) 
+                               printf(" gr %04x  num %04x  long %d",
+                                        ple->Gr, ple->Num, ple->LgrLueElem);
+                       else
+                               printf(" gr %04x  num %04x  long %d  _offset %d",
+                                       ple->Gr, ple->Num, ple->LgrLueElem, ple->Offset);
+               }
+
+               if (ple->Num!=0) { 
+               
+                       if(ple->VR == NULL) {
+                               if(!(ple->Gr%2) || !npriv) printf("\t%s\t%s\t\t",  
+                                                       t->dicom_type, t->dicom_libelle);
+                               } else {
+                               if(!(ple->Gr%2) || !npriv) printf("\t%s\t%s\t\t",  
+                                                       ple->VR, t->dicom_libelle);                             
+                               }
+               } 
+               
+               if (ple->Num==0) {      
+                       if(!(ple->Gr%2) || !npriv){
+                                       printf("   lgr du grp = %d\n   -------\n",
+                                               str2num(ple->valeurElem,int) );
+                       }
+               } else {        
+                       switch (ple->LgrElem) { 
+                       
+                       case 2:                                         // LGR = 2
+
+                               if (     (strcmp(t->dicom_type, "US") == 0)
+                                         || (strcmp(t->dicom_type, "SS") == 0) 
+                                         || (t->dicom_group == 0x0028 
+                                         && 
+                                               (       t->dicom_elem == 0x0005  
+                                                 || t->dicom_elem == 0x0200) ) ) {
+   
+                                               if(!(ple->Gr%2) || !npriv) { 
+                                                       printf("\t  \t \t %d \tx(%04x)\n",
+                                                               str2num(ple->valeurElem,unsigned short int),
+                                                               str2num(ple->valeurElem,unsigned short int) );  
+                                               }
+                               } else {
+
+                                       if(!(ple->Gr%2) || !npriv){ 
+                                               printf("\t[%s]  \t %d \tx(%04x)\n", 
+                                                       ple->valeurElem,
+                                                       str2num(ple->valeurElem,unsigned short int), 
+                                                       str2num(ple->valeurElem,unsigned short int));
+                                       }
+                               }
+                               break;          
+               
+                       case 4 :                        // LGR = 4
+                               if (   (strcmp(t->dicom_type,"UL") == 0)
+                                   || (strcmp(t->dicom_type,"SL") == 0) ) {
+                                               if(!(ple->Gr%2) || !npriv) { 
+                                                       printf("\t  \t \t %d \tx(%08x)\n", 
+                                                               str2num(ple->valeurElem,int), 
+                                                               str2num(ple->valeurElem,int));
+                                               }       
+                               } else {
+                                       if(!(ple->Gr%2) || !npriv) { 
+                                               printf("\t[%s]  \t %d \tx(%08x)\n", 
+                                                       ple->valeurElem,
+                                                       str2num(ple->valeurElem,int), 
+                                                       str2num(ple->valeurElem,int));
+                                       }
+                               }
+                               break;
+                       
+                       default :                                                               // AUTRES LGR
+
+                               if (ple->LgrElem > 5000) { 
+                                       if(!(ple->Gr%2) || !npriv) 
+                                               printf(" --> Too Long. Not Printed...\n");
+                               } else {
+                                       if(!(ple->Gr%2) || !npriv) 
+                                               printf(" \t[%s]\n",ple->valeurElem);
+                               }
+                       }
+               }
+       plelem = IdLstNext(plelem);
+       }
+}
+
+// -----------------------------------------------------------------------------------------------
+
+/**
+ * \ingroup        dcm
+ * \brief         Verifie le caractère Acr/Dcm/LibIdo d'un fichier.
+ *
+ * @param filename     Nom du Fichier
+ * @return                     ID_DCM_HDR (ca sera fait pour plus tard) si lisible
+ *                     O sinon.
+ *
+ */
+
+ID_DCM_HDR * IdDcmIsDcmReadable(char * filename) {
+   
+   return IdDcmReadFile(filename, 0xFFFF);
+}
+
+
+// ----------------------------------------------------------------------------------------------
+ /**
+ * \ingroup        dcm
+ * \brief         Verifie le caractère Jpeg Lossless d'un fichier, a partir du DCM_HDR.
+ *
+ * @param e            ID_DCM_HDR  deja cree   
+ * @return                     1 si Jpeg Losless
+ *                     O sinon.
+ *
+ */
+int IdDcmIsJpegLossless (ID_DCM_HDR * e) {
+char * Derivation_Description;
+char * Transfert_Syntax_UID;
+char * valeur = "Compress BN JPEG Lossless";
+
+       if (!e) 
+               return (0);
+               
+       Transfert_Syntax_UID = _IdDcmReadElement(0x0002, 0x0010, e);
+       if (Transfert_Syntax_UID != NULL) {
+               if ( (memcmp(Transfert_Syntax_UID + strlen(Transfert_Syntax_UID)-2, "70", 2) == 0)
+                       ||
+                        (memcmp(Transfert_Syntax_UID + strlen(Transfert_Syntax_UID)-2, "55", 2) == 0) ) {
+                        return (1);
+                } else {       
+                               Derivation_Description = _IdDcmReadElement(0x0008, 0x2111, e);
+                               if (Derivation_Description != NULL) {
+                                       if (memcmp (Derivation_Description, valeur, strlen(valeur)) == 0)
+                                               return (1);
+                               }       
+               }
+       }
+       return (0);
+}
+
similarity index 100%
rename from test.cxx
rename to src/test.cxx