3 /* =======================================================================
6 La seule maniere sure que l'on aie pour determiner
7 si on est en LITTLE_ENDIAN, BIG-ENDIAN,
8 BAD-LITTLE-ENDIAN, BAD-BIG-ENDIAN
9 est de trouver l'element qui donne la longueur d'un 'GROUP'
10 (on sait que la longueur de cet element vaut 0x00000004)
11 et de regarder comment cette longueur est codee en memoire
13 Le probleme vient de ce que parfois, il n'y en a pas ...
15 On fait alors le pari qu'on a a faire a du LITTLE_ENDIAN propre.
16 (Ce qui est la norme -pas respectee- depuis ACR-NEMA)
17 Si ce n'est pas le cas, on ne peut rien faire.
19 (il faudrait avoir des fonctions auxquelles
20 on passe le code Swap en parametre, pour faire des essais 'manuels')
22 ======================================================================= */
24 EndianType gdcmHeader::gdcmHeader()
27 guint32 x=4; // x : pour ntohs
28 bool net2host; // true when HostByteOrder is the same as NetworkByteOrder
33 char deb[LGR_ENTETE_A_LIRE];
35 // On teste le processeur
42 // On commence par verifier si c'est du DICOM 'actuel'
45 lgrLue = fread(deb,1,LGR_ENTETE_A_LIRE,e->fp);
48 if(memcmp(entCur, "DICM", (size_t)4) == 0) {
50 if (DEBUG) printf ("_IdDcmCheckSwap : C est du DICOM actuel \n");
53 if (DEBUG) printf ("_IdDcmCheckSwap : Ce n'est PAS du DICOM actuel\n");
56 if(filetype == TrueDicom) {
57 // on saute le File Preamble (souvent a ZERO) : 128 Octets
58 // + le DICM (4), et le (0002, 0000) soit 4 (136 = 128 + 4 + 4)
60 if(memcmp(entCur, "UL", (size_t)2) == 0) {
61 // les 2 premiers octets de la lgr peuvent valoir UL --> Explicit VR
62 filetype = ExplicitVR;
63 if (DEBUG) printf ("_IdDcmCheckSwap : Explicit VR\n");
65 filetype = ImplicitVR;
66 if (DEBUG) printf ("_IdDcmCheckSwap : PAS Explicit VR\n");
69 if (net2host) { // HostByteOrder is different from NetworkByteOrder
70 sw = 0; // on est sur PC ou DEC --> LITTLE-ENDIAN -> Rien a faire
71 if (DEBUG) printf("HostByteOrder = NetworkByteOrder\n");
73 } else { /* on est sur une Sun ou une SGI */
75 if (DEBUG) printf("HostByteOrder != NetworkByteOrder\n");
79 fseek (e->fp, 132L, SEEK_SET); //On se positionne sur le debut des info
85 // Pas du TrueDicom : permiere hypothese c'est de l'ACR 'propre', auquel
86 // cas la lgr du premier element du groupe est FORCEMENT 4
89 s=str2num(entCur,int);
93 sw=3412; if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
97 sw=4321; if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
101 sw=2143; if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
105 sw=0; if(DEBUG) printf("s : %08x sw : %d\n",s,sw);
110 if (DEBUG) printf (" Pas trouve l info de Swap; On va parier\n");
113 // Deuxieme hypothese : c'est de l'ACR 'pas propre' i.e. il manque
117 /* On n'a pas trouve l'info de swap 28/11/2000 JPR */
118 // Si c'est du VRAI ACR NEMA si on est sur une DEC ou un PC swap=0,
119 // SUN ou SGI SWAP=4321
120 /* si c'est du RAW, ca degagera + tard */
122 if (DEBUG) printf("On force la chance \n");
124 if (x!=ntohs(x)) // HostByteOrder is different from NetworkByteOrder
125 sw = 0; // on est sur PC ou DEC --> LITTLE-ENDIAN -> Rien a faire
127 sw = 4321; // on est sur Sun ou SGI
130 rewind(e->fp); // les info commencent au debut
135 void gdcmHeader::_setAcrLibido() {
138 PLIST_ELEMENT plelem;
141 // Positionnement ACR_LIBIDO
142 if(DEBUG) printf("Entree ds _setAcrLibido\n");
144 filetype = ACR_LIBIDO = 0;
145 if ( filetype != TrueDicom) {
146 // Recognition Code --> n'existe plus en DICOM V3 ...
149 plelem = IdLstFirst(pl);
151 ple= IdLstPtrObj(plelem);
152 if(DEBUG) printf("gr %04x Num %04x\n", ple->Gr, ple->Num);
153 if(ple->Gr > 0x0008) break; // On a depasse
154 if(ple->Gr == 0x0008) {
155 if(ple->Num > 0x0010) break; // On a depasse
156 if(ple->Num == 0x0010) {
157 if ( (memcmp(ple->valeurElem,"ACRNEMA_LIBIDO",14)==0)
159 || (memcmp(ple->valeurElem,"CANRME_AILIBOD",14)==0)) {
160 // en cas d'objet ACRLibido fait sr 1 autre machine)
164 } // fin if ple->Num==0x0010
165 } // fin ple->Gr==0x0008
166 plelem = IdLstNext(plelem);
168 } // fin if TrueDicom
173 /* =======================================================================
176 * ACR-NEMA : On a toujours
177 * GroupNumber (2 Octets)
178 * ElementNumber (2 Octets)
179 * ElementSize (4 Octets)
182 * DICOM : On peut avoir (implicit Value Representation)
183 * GroupNumber (2 Octets)
184 * ElementNumber (2 Octets)
185 * ElementSize (4 Octets)
187 * On peut avoir (explicit Value Representation)
188 * GroupNumber (2 Octets)
189 * ElementNumber (2 Octets)
190 * ValueRepresentation (2 Octets)
191 * ElementSize (2 Octets)
193 * ATTENTION : dans le cas ou ValueRepresentation = OB, OW, SQ, UN
194 * GroupNumber (2 Octets)
195 * ElementNumber (2 Octets)
196 * ValueRepresentation (2 Octets)
197 * zone reservee (2 Octets)
198 * ElementSize (4 Octets)
201 * ======================================================================= */
204 * \brief recupere la longueur d'un champ DICOM.
205 * (le fichier doit deja avoir ete ouvert,
206 * _IdAcrCheckSwap(ID_DCM_HDR *e) avoir ete appele)
207 * et la partie 'group' ainsi que la partie 'elem'
208 * de l'acr_element doivent avoir ete lues.
209 * @param sw code swap
210 * @param skippedLength pointeur sur nombre d'octets que l'on a saute qd la lecture est finie
211 * @param longueurLue pointeur sur longueur (en nombre d'octets) effectivement lue
213 * @return longueur retenue pour le champ
216 static guint32 _IdDcmRecupLgr(ID_DCM_HDR *e, int sw, int *skippedLength, int *longueurLue) {
218 unsigned short int l_gr_2;
227 int nbCode=26; // nombre d'elements dans la table de type DICOM_VR definie dans dicom.c
229 /* ================ */
231 // ID_DCM_HDR *e sert uniquement de passe-plat pour __ExplicitVR
234 if (e->__ExplicitVR == 1) {
235 lgrLue=fread (&VR, (size_t)2,(size_t)1, e->fp);
239 // Ce n'est pas parce qu'on a trouve UL la premiere fois qu'on respecte
240 // Explicit VR tout le temps
243 for(i=0,trouve=0;i<nbCode;i++) {
244 if(memcmp(_ID_dicom_vr[i].dicom_VR,VR,(size_t)2)==0) {
245 (e->pleCourant)->VR=_ID_dicom_vr[i].dicom_VR;
253 // On est mal : implicit VR repere
254 // mais ce n'est pas un code connu ...
255 // On reconstitue la longueur
257 if(DEBUG) printf("IdDcmRecupLgr : Explicit VR, mais pas trouve de code connu\n");
258 memcpy(&l_gr, VR,(size_t)2);
260 lgrLue=fread ( ((char*)&l_gr)+2, (size_t)2, (size_t)1, e->fp);
262 if(sw) l_gr = _IdDcmSWAP_LONG(((guint32)l_gr),sw);
264 if(DEBUG) printf("IdDcmRecupLgr : lgr deduite : %08x , %d\n",l_gr,l_gr);
267 if ( (int)l_gr == -1) {
271 if (DEBUG) printf(" 1 : lgr %08x (%d )skippedLength %d\n",l_gr,l_gr, *skippedLength);
275 // On repart dans la sequence 'sensee'
277 if(DEBUG) printf("VR : [%01x , %01x] (%c%c) en position %d du tableau\n", VR[0],VR[1],VR[0],VR[1],i);
278 //printf(" %d , %s\n", i,_ID_dicom_vr[i].dicom_VR);
281 (!memcmp( VR,"OB",(size_t)2 )) ||
282 (!memcmp( VR,"OW",(size_t)2 )) ||
283 (!memcmp( VR,"SQ",(size_t)2 )) ||
284 (!memcmp( VR,"UN",(size_t)2 )) ) {
286 // les 2 octets suivants sont reserves
288 if(DEBUG) printf("IdDcmRecupLgr : les 2 octets suivants sont reserves\n");
290 fseek(e->fp, 2L,SEEK_CUR);
292 //on lit la lgr sur QUATRE octets
294 lgrLue=fread (&l_gr, (size_t)4,(size_t)1, e->fp);
296 if(sw) l_gr = _IdDcmSWAP_LONG(((guint32)l_gr),sw);
300 //on lit la lgr sur DEUX octets
302 lgrLue=fread (&l_gr_2, (size_t)2,(size_t)1, e->fp);
304 if(sw) l_gr_2 = _IdDcmSWAP_SHORT((unsigned short)l_gr_2,sw);
309 if ( l_gr_2 == 0xffff) {
316 } else { // Explicit VR = 0
318 //on lit la lgr sur QUATRE octets
320 lgrLue=fread (&l_gr, (size_t)4,(size_t)1, e->fp);
322 if(sw)l_gr=_IdDcmSWAP_LONG(((long)l_gr),sw);
328 // Traitement des curiosites sur la longueur
330 if ( (int)l_gr == 0xffffffff)
333 if(!memcmp( VR,"SQ",(size_t)2 )) { // ca annonce une SEQUENCE d'items ?!
334 l_gr=0; // on lira donc les items de la sequence
335 if (DEBUG) printf(" SQ trouve : lgr %d \n",l_gr);
338 if (DEBUG) printf(" 2 : lgr %08x (%d) skippedLength %d\n",l_gr,l_gr, *skippedLength);