+++ /dev/null
-
-#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);
-}
-