Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals

acrread.c

Go to the documentation of this file.
00001 /************************************************************************* 00002 * $Id: acrread.c,v 1.1 2005/09/09 08:22:21 bellet Exp $ 00003 ************************************************************************** 00004 This software is governed by the CeCILL license under French law and 00005 abiding by the rules of distribution of free software. You can use, 00006 modify and/ or redistribute the software under the terms of the CeCILL 00007 license as circulated by CEA, CNRS and INRIA at the following URL 00008 "http://www.cecill.info". 00009 00010 As a counterpart to the access to the source code and rights to copy, 00011 modify and redistribute granted by the license, users are provided only 00012 with a limited warranty and the software's author, the holder of the 00013 economic rights, and the successive licensors have only limited 00014 liability. 00015 00016 In this respect, the user's attention is drawn to the risks associated 00017 with loading, using, modifying and/or developing or reproducing the 00018 software by the user in light of its specific status of free software, 00019 that may mean that it is complicated to manipulate, and that also 00020 therefore means that it is reserved for developers and experienced 00021 professionals having in-depth computer knowledge. Users are therefore 00022 encouraged to load and test the software's suitability as regards their 00023 requirements in conditions enabling the security of their systems and/or 00024 data to be ensured and, more generally, to use and operate it in the 00025 same conditions as regards security. 00026 00027 The fact that you are presently reading this means that you have had 00028 knowledge of the CeCILL license and that you accept its terms. 00029 00030 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de 00031 l'Image). All rights reserved. See License.txt for details. 00032 00033 Version 1.0 05/09/2005 00034 *************************************************************************/ 00035 00036 /************************************************************************* 00037 * * PROJET : libido 00038 * NOM DU MODULE : readacr.c * TYPE : fonction 00039 * AUTEUR : c.odet * CREATION : 07/05/1992 00040 * VERSION : * REVISION : 00041 * LANGAGE : C * 00042 * * 00043 ******************************************** ****************************** 00044 * 00045 * Description : Lit un objet LIBIDO dans un fichier 00046 * au format ACRNEMA modifie URA1216 00047 ************************************************************************** 00048 * 00049 * MODULES UTILISES : 00050 * 00051 ************************************************************************** 00052 * | | 00053 * REVISIONS : DATE | AUTEUR | DESCRIPTION 00054 *---------------------|--------------|------------------------------------ 00055 * 16/06/92 | B. BARBIER | Insertion Libido 00056 * 15/9/92 | "" | V1.2-5 normalisation des noms 00057 * 01/10/92 | B. Barbier | V1.2-5 : normalisation des noms 00058 * 08/10/92 | CO | V1.3 changement de structure 00059 * 10/11/94 JPR prise en compte des Signaux 00060 * 25/01/95 JPR prise en compte types non UCHAR 00061 * 21/04/95 CO complexes Ima 00062 22 04 95 JPR prise en compte types non Reel 00063 29 04 95 JPR IdAcrInquireInfo 00064 16 06 95 JPR IdAcrInquirePixelSize 00065 3 07 95 JPR remplacement elem non-ACR 28,105 00066 par 28,199 pour compatibilite images 00067 Phillips 00068 25/10/95 JPR _IdAcrCheckType pour rationnaliser 00069 l'usine a gaz... 00070 8/01/96 JPR Lecture des Objets CONTOUR 00071 5/02/96 JPR UsedNbX ... 00072 6/02/96 JPR IdAcrInquireType (pour test swap) 00073 6/5/96 CO Initialisation NX,NY,NZ dans IdAcrInquireInfo 00074 04/09/96 JPR+ GB VRAIE prise en compte de nbu et hightBit 00075 3/2/97 JPR Prise en compte champ _message 00076 7/2/97 JPR PROBLEME pour les elements 'chaine de caract' : 00077 Ils doivent etre alloues 00078 AVANT l'appel de IdAcrReadElement 00079 19/2/97 BB Read dans GetSliceThickness 00080 20/2/97 JPR Verif entete 00081 17/4/97 JPR Ajout SEQUENCE 00082 9/10/97 JPR IdAcrInquireInfoTot : correction pb sur NT des SEQ 00083 20/4/98 JPR Modif IdIrmGetAndRenameDirContents 00084 pour pb inscription Xtiple si renomage... 00085 21/4/98 JPR Correction confusion CNT et SIG en lecture ACR 00086 00087 19/5/98 JPR IdDcmCVReadFile pour DICOM CardioVasc 00088 20/5/98 JPR Elagage IdAcrReadFile 00089 27/5/98 JPR IdAcrInquireInfoTot2, pour DICOM CardioVasc 00090 15/12/98 JPR Erreur ds dimX dimY pour les VRAIES images ACR 00091 (rectangulaires) 00092 19/2/99 Djamal Boukerroui IdAcrReadFile : correction code retour si 00093 erreur dans IdDcmCVReadFile 00094 00095 19/3/99 JPR Alloc dynamique pour les _message monstrueux 00096 29/6/99 JPR Correction Swap pour CardioVasc sur Dec 00097 30/6/99 JPR Modif _IdAcrGetPixelOffset pour SGI 00098 1/07/99 JPR Prise en compte RGB DICOM 00099 24/08/99 JPR Ajout IdAcrInquireInfoTot3 (renvoie le codeSwap) 00100 15/10/99 Djamal Boukerroui Pb indicateur de fin du champ _message, a la relecture 00101 21/10/99 JPR Pb lgr message si fichier non LibIDO 00102 24-01-2000 FB initialisations 00103 09-08-2000 JPR Modif lecture lgr pour Philips single Frame (PAPYRUS-like) 00104 31-08-2000 JPR Prise en compte Nb Bits stored = 12 dans _IdAcrCheckType 00105 23-06-2001 JPR j'enleve la prise en compte ERRONNEE de nbu et hightBit 00106 00107 00108 POURRIEZ-VOUS EVITER DE VIRER CES COMMENTAIRES. 00109 MERCI 00110 00111 JPRx 00112 00113 **************************************************************************/ 00114 00115 00116 #include <string.h> // For strlen 00117 #include "idio.h" 00118 #include "idprint.h" 00119 #include "idacr-private.h" 00120 #include "iddcm.h" 00121 00122 static int DEBUG=0; 00123 00124 /* 00125 Rappels 00126 ------- 00127 00128 #define TY_CHAR ( 0<<4) 00 00129 #define TY_FLOAT ( 1<<4) 10 00130 #define TY_DOUBLE ( 2<<4) 20 00131 #define TY_COMPLEX ( 3<<4) 30 00132 #define TY_RGB ( 4<<4) 40 00133 #define TY_SHORT ( 5<<4) 50 00134 #define TY_LONG ( 6<<4) 60 00135 #define TY_UCHAR ( 7<<4) 70 00136 #define TY_USHORT ( 8<<4) 80 00137 #define TY_COMPLEX_DOUBLE ( 9<<4) 90 00138 #define TY_COMPLEX_FLOAT (10<<4) a0 00139 #define TY_COMPLEX_CHAR (11<<4) b0 00140 #define TY_COMPLEX_UCHAR (12<<4) c0 00141 #define TY_COMPLEX_SHORT (13<<4) d0 00142 #define TY_COMPLEX_USHORT (14<<4) e0 00143 #define TY_COMPLEX_LONG (15<<4) f0 00144 #define TY_BIT (16<<4) 100 00145 #define TY_IDPOINT (17<<4) 110 00146 #define TY_FACE (18<<4) 120 00147 #define TY_POINTER (19<<4) 130 00148 #qdefine TY_ULONG (20<<4) 140 00149 #define TY_COMPLEX_ULONG (21<<4) 150 00150 00151 #define TY_IDXPOINT_CHAR (22<<4) 160 00152 #define TY_IDXPOINT_UCHAR (23<<4) 170 00153 #define TY_IDXPOINT_FLOAT (24<<4) 180 00154 #define TY_IDXPOINT_DOUBLE(25<<4) 190 00155 #define TY_IDXPOINT_SHORT (26<<4) 1a0 00156 #define TY_IDXPOINT_USHORT(27<<4) 1b0 00157 #define TY_IDXPOINT_LONG (28<<4) 1c0 00158 #define TY_IDXPOINT_ULONG (29<<4) 1d0 00159 00160 #define TY_COLOR (30<<4) 1fo 00161 */ 00162 00163 #include <stdio.h> 00164 #include <stdlib.h> // For atoi 00165 #include "idgen.h" 00166 #include "idsig.h" 00167 #include "idcnt.h" 00168 #include "idima.h" 00169 #include "idvol.h" 00170 #include "idseq.h" 00171 #include "idacr.h" 00172 #include "idacr-restricted.h" 00173 #include "iderr.h" 00174 00175 00176 int _IdAcrRecupLgr (FILE *fp, int *); 00177 int _IdAcrIsAcrLibido (FILE *fp,char *bufbid); 00178 00179 00180 short int SWAP_SHORT (short int); 00181 long int SWAP_LONG (long int); 00182 00183 static int ACR_LIBIDO; 00184 00185 static int rgb; 00186 00187 static int sw; 00188 static char * _message; 00189 00190 extern int __ID_CardioVascCurieux; 00191 extern int __ID_offset; 00192 extern int __Papyrus; 00193 extern unsigned short int __NumeroGroupePrecedent; 00194 extern int __TrueDicom; 00195 extern int __ExplicitVR; 00196 00197 00198 /* FUNCTION DESCRIPTION ************************************************** 00199 * 00200 * IdDcmCVReadFile (fonction) 00201 * 00202 * RESUME: Lecture d'un fichier de type DICOM MultiFrame. 00203 * 00204 * DESCRIPTION: Lecture d'un fichier de type DICOM MultiFrame. 00205 * 00206 * A L'ATTENTION DES Kamikazes Creatissiens : 00207 * La fonction IdAcrReadFile (supposee lire des fichiers 'ACR LibIDO') 00208 * a evolue au fil des ans, en fonction des choses 00209 * que l'on a considere comme utiles de rajouter dans NOTRE entete. 00210 * Puis, on a eu de 'vrais' fichiers ACR-NEMA, V2 puis V3. 00211 * Puis des fichiers DICOM single-frame. 00212 * Puis des fichiers DICOM multiframe. 00213 * A ajouter a ca, des particularites a la limite de la mauvaise foi, 00214 * dependant des constructeurs... 00215 * 00216 * DONC : 00217 * 00218 * Ne perdez pas votre temps a essayer de comprendre POURQUOI ... 00219 * La reponse est : PARCE QUE ! 00220 * 00221 * 00222 * SYNTAXE: PPIMAGE tabIm[] = IdDcmCVReadFile (char * filename, int numPremiereImage, int numDerniereImage); 00223 * 00224 * RETOUR: type : void ** 00225 * role : Pointeur vers un tableau d'objets 00226 * 00227 * PARAMETRES: 00228 * nom : filename 00229 * type : char * 00230 * role : Nom du fichier DICOM MultiFrame 00231 * 00232 * nom : typeObj 00233 * type : int 00234 * role : Type de l'object a lire (IMA_UCHAR, SIG_CHAR, ...). 00235 * 00236 * nom : numPremiereImage 00237 * type : int 00238 * role : Num premiere image a lire (si -1 -ou 0- on commence a la premiere). 00239 * 00240 * nom : numDerniereImage 00241 * type : int 00242 * role : Num derniere image a lire (si -1 -ou 0- on fini a la derniere). 00243 * 00244 * FICHIER: readacr.c 00245 * 00246 ******************************************************** END DESCRIPTION */ 00247 00248 /* JPR, pour eviter de dupliquer le source */ 00249 00250 #define CCS(Type) \ 00251 if(!fread(&((Type)psi)[0],IdSigDimX(psi)*IdSizeOfType(psi),1,fp)) \ 00252 \ 00253 { \ 00254 IdSigFree(psi); \ 00255 IdErrPrintf("echec en lecture Signal\n");\ 00256 return(0); \ 00257 } 00258 00259 #define CCC(Type) \ 00260 if(!fread(&((Type)pco)[0],IdCntDimX(pco)*IdSizeOfType(pco),1,fp)) \ 00261 \ 00262 { \ 00263 IdCntFree(pco); \ 00264 IdErrPrintf("echec en lecture Contour\n"); \ 00265 return(0); \ 00266 } 00267 00268 /* pour les anciens codage de contour */ 00269 #define CCC2(Type) \ 00270 if(!fread(&((Type)pco)[0],IdCntDimX(pco)*IdSizeOfType(pco)>>1,1,fp))\ 00271 \ 00272 { \ 00273 IdCntFree(pco); \ 00274 IdErrPrintf("echec en lecture Contour\n"); \ 00275 return(0); \ 00276 } 00277 00278 #define CCI(Type,TailleType) \ 00279 { \ 00280 if (vector != NULL) { /* on a une contrainte de rapidite */ \ 00281 if(!fread(vector,(int)dim[0]*(int)dim[1]*TailleType,1,fp)){ \ 00282 IdPrintf("echec en lecture Image dans Vecteur \n"); \ 00283 return(0); \ 00284 } \ 00285 } else { \ 00286 for(i=0;i<IdImaDimY(pim);i++){ \ 00287 if(!fread(((Type)pim)[i],IdImaDimX(pim)*IdSizeOfType(pim),1,fp)) { \ 00288 IdPrintf("echec en lecture Image [i : %d] lgr de %d \n", \ 00289 i,IdImaDimX(pim)*IdSizeOfType(pim)); \ 00290 IdImaFree(pim); \ 00291 return(0); \ 00292 } \ 00293 } \ 00294 } \ 00295 } \ 00296 00297 #define CCV(Type) \ 00298 for(j=0;j<IdVolDimZ(pvo);j++) \ 00299 for(i=0;i<IdVolDimY(pvo);i++) \ 00300 if(!fread(((Type)pvo)[j][i],IdVolDimX(pvo)*IdSizeOfType(pvo),1,fp)) \ 00301 { \ 00302 IdVolFree(pvo); \ 00303 IdErrPrintf("echec en lecture Volume\n"); \ 00304 return(0); \ 00305 } 00306 00307 #define CCQ(Type) \ 00308 for(k=0;k<IdSeqDimT(pse);k++) \ 00309 for(j=0;j<IdSeqDimZ(pse);j++) \ 00310 for(i=0;i<IdSeqDimY(pse);i++) \ 00311 if(!fread(((Type)pse)[k][j][i],IdSeqDimX(pse)*IdSizeOfType(pse),1,fp)) \ 00312 { \ 00313 IdSeqFree(pse); \ 00314 IdErrPrintf("echec en lecture Sequence\n");\ 00315 return(0); \ 00316 } 00317 00318 //------------------------------------------------------------------------- 00319 // 00320 // IdAcrReadFileIntoVector est un sur-ensemble de IdAcrReadFile 00321 // 00322 00360 void *IdAcrReadFileIntoVector(char *filename, int type, int premIm, int dernIm, void * vector) { 00361 00362 return IdDcmReadFileIntoVector(filename, type, premIm, dernIm, vector) ; 00363 return (NULL); 00364 } 00365 00366 00367 00368 /* FUNCTION DESCRIPTION ************************************************** 00369 * 00370 * IdAcrInquireInfoTot4 (fonction) 00371 * 00372 * RESUME: Retourne diverses info stockees dans l'entete ACRNEMA. 00373 * 00374 * DESCRIPTION: Retourne des info sur l'objet stocke dans un fichier ACRNEMA. 00375 * Remplace IdAcrInquireInfo, qui etait incomplet 00376 * 00377 * SYNTAXE: int retCode = IdAcrInquireInfoTot4 (char *filename, int *typObj, *typLibido, int *typData, int *NX, int *NY, int *NZ, int *NT, int *tailleEntete, int *nbFrames, int* nb, int *nbu, int *hb, int *sign); 00378 * 00379 * RETOUR: type : int 00380 * role : 0: echec 1: succes. 00381 * 00382 * PARAMETRES: 00383 * nom : filename 00384 * type : char * 00385 * role : Nom du fichier ACRNEMA 00386 * 00387 * nom : typeObj 00388 * type : int * 00389 * role : type d'objet (SIG, IMA, VOL, CNT, ... 00390 * 00391 * nom : typLibido 00392 * type : int * 00393 * role : type d'objet (TY_DOUBLE, TY_UCHAR, TY_COMPLEX_DOUBLE ... 00394 * 00395 * Si l'on veut fabriquer, a partir de ce type LibIDO un objet d'un autre type d'objet 00396 * (p ex, on a lu un VOLUME, on veut fabriquer une IMAGE de meme type) 00397 * On fera : 00398 * typeIma=typeLibido | IMA; 00399 * 00400 * nom : typData 00401 * type : int * 00402 * role : type de Donnees LibIDO de l'objet (SIG_DOUBLE, IMA_UCHAR, VOL_COMPLEX_DOUBLE, ... 00403 * nom : NX 00404 * type : int * 00405 * role : taille en X de l'objet (SIG, IMA, VOL, SEQ seulement) 00406 * 00407 * nom : NY 00408 * type : int * 00409 * role : taille en Y de l'objet (IMA, VOL, SEQ seulement) 00410 * 00411 * nom : NZ 00412 * type : int * 00413 * role : taille en Z de l'objet (VOL, SEQ seulement) 00414 * 00415 * nom : NT 00416 * type : int * 00417 * role : taille en T de l'objet (SEQ seulement) 00418 * 00419 * nom : tailleEntete 00420 * type : int * 00421 * role : taille, en octets, de l'entete a sauter 00422 * 00423 * nom : nbFrames 00424 * type : int * 00425 * role : nb d'images, ds le cas DICOM CardioVasc 00426 * 00427 * nom : codeSwap 00428 * type : int * 00429 * role : code de swap des octets 00430 * 00431 * nom : nb 00432 * type : int * 00433 * role : nombre de bits alloues 00434 * 00435 * nom : nbu 00436 * type : int * 00437 * role : nombre de bits utiles 00438 * 00439 * nom : hb 00440 * type : int * 00441 * role : Bit de poids fort 00442 * 00443 * nom : sign 00444 * type : int * 00445 * role : signe des pixels 00446 * 00447 * 00448 * 00449 * FICHIER: readacr.c 00450 * 00451 ******************************************************** END DESCRIPTION */ 00452 00453 00486 int IdAcrInquireInfoTot4 ( char * filename, 00487 unsigned short int *typObj, 00488 unsigned short int *typLibido, 00489 unsigned short int *typData, 00490 int *NX, 00491 int *NY, 00492 int *NZ, 00493 int *NT, 00494 int *offset, 00495 int *nbFrames, 00496 int *codeSwap, 00497 int *bitsAllocated, 00498 int *bitsStored, 00499 int *highBit, 00500 int *signe) 00501 { 00502 FILE *fp; 00503 short int ndim,nb,nbu,hb,ty; 00504 short int dim[4]; 00505 int i /* ,sw */ ; /* sw en Global */ 00506 char bufbid[150]; 00507 long int nbCarLus; 00508 00509 if((fp=fopen(filename,ID_RFILE_BIN))==0) { 00510 IdErrno=IDERR_OPEN_FAILED; 00511 IdErrPrintf ("echec ouverture %s\n",filename); 00512 return (0); 00513 } else 00514 sw=_IdAcrCheckSwap(fp); 00515 00516 if(sw==-1) { 00517 IdErrno=IDERR_NON_ACR_FILE; 00518 fclose ( fp ); 00519 return (0); 00520 } 00521 00522 *codeSwap=sw; 00523 00524 if ( __ID_CardioVascCurieux == 1) { 00525 printf("ID_CardioVascCurieux : 2\n"); 00526 fseek(fp,0L,SEEK_SET); /* pas trouve 08,00; on se met au debut */ 00527 } else { 00528 ACR_LIBIDO = _IdAcrIsAcrLibido (fp,bufbid); 00529 } 00530 00531 *typData=0; 00532 nbCarLus=_IdAcrReadElement(0x0028,0x0004,fp,bufbid); 00533 00534 if(nbCarLus!=0) { /* RGB */ 00535 00536 bufbid[nbCarLus]=0; 00537 00538 if ( (memcmp(bufbid,"RGB ",4)==0) 00539 || 00540 (memcmp(bufbid,"B RG",4)==0) 00541 || 00542 (memcmp(bufbid," BGR",4)==0) 00543 || 00544 (memcmp(bufbid,"GR B",4)==0) ) { 00545 00546 *typData=TY_RGB; 00547 IdPrintf ("Image RGB !\n"); 00548 } 00549 00550 } 00551 /* JPR 27-05-98*/ 00552 00553 /* Lecture dimension de l'espace */ 00554 if (!_IdAcrReadElement(0x0028,0x0005,fp,&ndim)) { 00555 ndim=2; 00556 } 00557 /* JPR */ 00558 if(ndim>4) { 00559 IdPrintf (" Nb de Dimensions incorrect : %d\n", ndim); 00560 fclose ( fp ); 00561 return(0); 00562 } 00563 00564 /* Lecture nbFrames pour CardioVasc */ 00565 00566 if ((nbCarLus=_IdAcrReadElement(0x0028,0x0008,fp,bufbid))==0) { 00567 *nbFrames=1; 00568 } else 00569 *nbFrames=atoi(bufbid); /* c'est des caracteres type : IS, pas un short int */ 00570 00571 for(i=0;i<ndim;i++) 00572 if(!_IdAcrReadElement(0x0028,0x0010+i,fp,&dim[i])) { 00573 00574 IdErrno=IDERR_NON_ACR_FILE; 00575 fclose ( fp ); 00576 return (0); 00577 } 00578 00579 if (ACR_LIBIDO!=1) { /* si c'est une VRAIE image ACR */ 00580 /* on permutte NX et NY ds l'entete LibIDO */ 00581 int secuDim; 00582 secuDim = dim[0]; 00583 dim[0] = dim[1]; 00584 dim[1] = secuDim; 00585 } 00586 00587 *NT = *NZ = *NY = *NX = 1; /* CO 6/5/96 */ 00588 switch(ndim) { 00589 case 4: *NT=dim[3]; 00590 case 3: *NZ=dim[2]; 00591 case 2: *NY=dim[1]; 00592 case 1: *NX=dim[0]; 00593 } 00594 00595 switch (ndim) { 00596 case 1: *typObj=SIG; break; 00597 case 2: *typObj=IMA; break; 00598 case 3: *typObj=VOL; break; 00599 case 4: *typObj=SEQ; break; 00600 default: { 00601 IdErrno=IDERR_NON_ACR_FILE; 00602 fclose ( fp ); 00603 return (0); 00604 } 00605 } 00606 /* nombre de bits par pixels (Bits Allocated) */ 00607 if(!_IdAcrReadElement(0x0028,0x0100,fp,&nb)) { 00608 00609 IdErrno=IDERR_NON_ACR_FILE; 00610 fclose ( fp ); 00611 return (0); 00612 } 00613 *bitsAllocated = nb; 00614 /* nombre de bits utiles (Bits Stored) */ 00615 if(!_IdAcrReadElement(0x0028,0x0101,fp,&nbu)) { 00616 00617 nbu=nb; 00618 } 00619 *bitsStored = nbu; 00620 /* Bit de poids fort (High Bit ) */ 00621 if(!_IdAcrReadElement(0x0028,0x0102,fp,&hb)) { 00622 00623 hb=nbu-1; 00624 } 00625 *highBit = hb; 00626 00627 /* type 'signe' ou 'non signe ' **/ 00628 if(!_IdAcrReadElement(0x0028,0x0103,fp,&ty)) { 00629 00630 ty=0; 00631 } 00632 *signe = ty; 00633 /* 00634 if (*typData != TY_RGB) { 00635 *typData=_IdAcrCheckType(fp, bufbid, (int)ty, (int)nb, *typObj); 00636 } 00637 *typLibido = *typData & TY_SIZE; 00638 */ 00639 00640 *typLibido=_IdAcrCheckType(fp, bufbid, (int)ty, (int)nb, *typObj); 00641 00642 *typData = *typLibido & TY_SIZE; 00643 00644 00645 /* IdPrintf (" typData %x\n",*typData); */ 00646 00647 *offset = _IdAcrGetPixelOffset(fp); 00648 00649 fclose ( fp ); 00650 00651 return 1; 00652 } 00653 00654 /* FoNCTION DESCRIPTIoN ************************************************** 00655 * 00656 * _IdAcrGetPixelOffset (fonction) 00657 * 00658 * ReSUME: Retourne l'offset pour atteindre le groupe des Pixels stocke dans l'entete ACRNEMA. 00659 * 00660 * DeSCRIPTION: Retourne l'offset pour atteindre le groupe des Pixels stocke dans l'entete ACRNEMA.. 00661 * 00662 * SyNTAXE: long offset = _IdAcrGetPixelOffset(fp) 00663 * 00664 * 00665 * FICHIER: readacr.c 00666 * 00667 * fseek(fp,4L,SEEK_SET); SEEK_SET = 0 00668 * fread(&bili2,4,1,fp); lgr groupe : 0000 0004 JPR 00669 * sw=_IdAcrTestSwap(bili2); JPR 00670 * 00671 * 00672 * EXEMPLE: 00673 * 00674 ******************************************************** END DESCRIPTIoN */ 00675 00676 00677 long _IdAcrGetPixelOffset(FILE *fp) 00678 { 00679 unsigned short g,gr; 00680 unsigned short n,num; 00681 int l; 00682 int flag; 00683 int skL; 00684 int lgrTot=__ID_offset; 00685 00686 int __cas_de_fou_Philips =0; 00687 00688 if (DEBUG) 00689 IdPrintf (" _IdAcrGetPixelOffset : __ID_offset = %d\n",__ID_offset); 00690 00691 00692 /* --- pour remettre le pointeur de fichier d'applomb --- */ 00693 /* --- et pour positionner __ID_offset --- */ 00694 /* pas tres elegant --> trouver autre chose ? --- */ 00695 sw=_IdAcrCheckSwap(fp); 00696 00697 if (DEBUG) 00698 IdPrintf (" \n_IdAcrGetPixelOffset : sortie _IdAcrCheckSwap\n\n"); 00699 00700 if ( __ID_CardioVascCurieux == 1) 00701 { 00702 printf("ID_CardioVascCurieux : 3\n"); 00703 if (DEBUG) 00704 IdPrintf(" _IdAcrGetPixelOffset : __ID_CardioVascCurieux = 1\n"); 00705 fseek(fp,0L,SEEK_SET); 00706 } 00707 00708 // ------- 00709 00710 if(!_IdAcrReadElement(0x0028,0x0200,fp,&gr)) 00711 gr=0x7FE0; // Par defaut 00712 if (DEBUG) 00713 IdPrintf (" _IdAcrGetPixelOffset : numGrPixels %x\n",gr); 00714 00715 if (!(gr==0x7FE0)) 00716 num=0x1010; // Special PHILIPS 00717 else 00718 num=0x0010; 00719 00720 if (__ID_CardioVascCurieux == 1) { 00721 num=0x0010; // Special PHILIPS 00722 printf("ID_CardioVascCurieux : 4\n"); 00723 } 00724 00725 if (DEBUG) 00726 IdPrintf (" _IdAcrGetPixelOffset : numEltPixels %x\n",num); 00727 00728 // ------- 00729 00730 if (DEBUG) 00731 IdPrintf(" _IdAcrGetPixelOffset : Recherche gr %x num" 00732 "%x (swapping %d)\n",gr,num,sw); 00733 00734 /* --- pour remettre le pointeur de fichier d'applomb --- */ 00735 /* pas tres elegant --> trouver autre chose ? --- */ 00736 sw=_IdAcrCheckSwap(fp); 00737 00738 if (DEBUG) 00739 IdPrintf (" _IdAcrGetPixelOffset : sortie _IdAcrCheckSwap\n"); 00740 00741 if ( __ID_CardioVascCurieux == 1) 00742 { 00743 printf("ID_CardioVascCurieux : 5\n"); 00744 if (DEBUG) 00745 IdPrintf(" _IdAcrGetPixelOffset : __ID_CardioVascCurieux = 1\n"); 00746 fseek(fp,0L,SEEK_SET); 00747 } 00748 00749 if (DEBUG) 00750 IdPrintf (" \n_IdAcrGetPixelOffset : On lance le comptage\n\n"); 00751 00752 l=0; 00753 flag=0; 00754 00755 00756 while(fread(&g,2,1,fp)) { 00757 if(sw) 00758 g=SWAP_SHORT(((short)g)); 00759 fread(&n,2,1,fp); 00760 if(sw) 00761 n=SWAP_SHORT(((short)n)); 00762 l= _IdAcrRecupLgr(fp, &skL); 00763 if (DEBUG) 00764 IdPrintf(" _IdAcrGetPixelOffset : fread g %x " 00765 "n %x l %d 0x%08x\n",g,n,l,l); 00766 00767 if((g==gr)&&(n==num)) { 00768 // on est sur l'element recherche 00769 lgrTot = lgrTot + 2 +2 + skL; 00770 00771 if (DEBUG) 00772 IdPrintf("_IdAcrGetPixelOffset : sortie avec offset %d\n", 00773 lgrTot); 00774 return lgrTot; 00775 00776 } else if( ( (g>gr)||((gr==g)&&(n>num)) ) && 00777 ( g < 0xff00 ) // cas de fou Phiplips 00778 ) { 00779 // on a depasse l'element 00780 IdPrintf("_IdAcrGetPixelOffset : Kross Katastrof : on a depasse" 00781 " le groupe des Pixels :-( \n"); 00782 } else { // on saute a l'element suivant 00783 if (g>0xff00) { 00784 if (DEBUG)IdPrintf("_IdAcrGetPixelOffset : cas de fou Phiplips\n"); 00785 __cas_de_fou_Philips=1; 00786 } 00787 fseek(fp,l,SEEK_CUR); 00788 lgrTot = lgrTot + l +2 +2 +skL; 00789 if (DEBUG) 00790 IdPrintf("_IdAcrGetPixelOffset : on saute a " 00791 "l ele sv : lgrTot (part) %d\n", 00792 lgrTot); 00793 } 00794 } // While 00795 return(0); 00796 } 00797 00798 /* ----------------------------------------------------------------------- */ 00799 00809 long IdAcrGetPixelOffsetFromFile(char *filename) 00810 { 00811 FILE *fp; 00812 long result; 00813 if((fp=fopen(filename,ID_RFILE_BIN))==0) { 00814 IdErrPrintf ("echec ouverture %s\n", filename); 00815 return (0); 00816 } 00817 result = _IdAcrGetPixelOffset(fp); 00818 fclose(fp); 00819 return result; 00820 } 00821 00822 00823 /* ----------------------------------------------------------------------- */ 00824 00825 00854 void *IdAcrReadFile(char * filename, int type) 00855 { 00856 void ** tabObj=NULL; 00857 00858 tabObj=IdAcrReadFileIntoVector(filename, type,-2, -2, NULL); 00859 00860 if (tabObj==NULL) 00861 return (NULL); 00862 else 00863 return(tabObj[0]); 00864 } 00865 00866 00867 //------------------------------------------------------------------------- 00868 // 00869 // IdDcmCVReadFile est une encapsulation de IdAcrReadFileIntoVector 00870 // 00871 00904 void *IdDcmCVReadFile(char * filename, int type, int numPremIm, int numDernIm) 00905 { 00906 void ** tabObj=NULL; 00907 00908 tabObj=IdAcrReadFileIntoVector(filename,type, numPremIm, numDernIm, NULL); 00909 00910 if (tabObj==NULL) 00911 return (NULL); 00912 else 00913 return(tabObj[0]); 00914 } 00915 00916 00917 /* FUNCTION DESCRIPTION ************************************************** 00918 00919 IdAcrInquireHeader (fonction) 00920 00921 RESUME: Retourne TOUTES les info stockees dans l'entete ACRNEMA. 00922 00923 DESCRIPTION: Retourne TOUTES les info sur l'objet stocke dans un fichier ACRNEMA. 00924 sous forme d'une liste d'ACR_ELEMENT. 00925 la 'valeur' de chaque element est suivie d'un ZERO binaire, 00926 car il est IMPOSSIBLE ( pour IdAcrInquireHeader) de savoir, 00927 dans le cas d'un element d'un groupe prive (impair), 00928 si un element de longueur 2 est un UNSIGNED SHORT INT ou un CHAR *... 00929 si un element de longueur 4 est un UNSIGNED LONG ou un CHAR *... 00930 00931 L'utilisateur desirant connaitre connaitre la valeur d'un element particulier 00932 saura, en consultant le 'Conformance Statement' de l'imageur sur lequel il travaille 00933 le type de cet element. 00934 il procedera alors comme suit: 00935 00936 unsigned short int gr =0x0010; .. par exemple .. 00937 unsigned short int num=0x0010; 00938 ACR_ELEMENT *elem=_IdAcrFindElement(liste,gr,num); 00939 uint32_t lgr = elem->length; 00940 00941 Selon que : 00942 00943 c'est un char * de lgr !=2, !=4 00944 On l'utilisera directement : printf("%s\n",elem->value); 00945 00946 c'est un char * de lgr =4 00947 On le Swappera : *(long *)elem->value=SWAP_LONG((*(long*)elem->value)); 00948 printf("%s\n",elem->value); 00949 c'est un char * de lgr =2 00950 On le Swappera : *(long *)elem->value=SWAP_SHORT((*(long*)elem->value)); 00951 printf("%s\n",elem->value); 00952 c'est un short int 00953 On le castera : unsigned short int x = *(short int *) elem->value; 00954 00955 c'est un long int 00956 On le castera : unsigned long x = *(unsigned long *) elem->value; 00957 00958 Bon... 00959 On a vu pire... 00960 00961 SYNTAXE: ACR_ELEMENT *liste = IdAcrInquireHeader (char *filename, int mode); 00962 00963 RETOUR: type : ACR_ELEMENT * 00964 role : liste d'ACR_ELEMENT 00965 00966 PARAMETRES: 00967 nom : filename 00968 type : char * 00969 role : Nom du fichier ACRNEMA 00970 00971 nom : mode 00972 type : integer 00973 role: 00974 mode= 0 : on NE CHARGE PAS les Elements 'longs' (>5000) , 00975 1 : on charge EGALEMENT les Elements 'longs' (>5000) , 00976 2 : on NE charge PAS les Groupes Shadow (ni Elts Longs) 00977 00978 00979 FICHIER : readacr.c 00980 00981 00982 ******************************************************** END DESCRIPTION */ 00983 01029 ACR_ELEMENT * IdAcrInquireHeader(char *filename, int mode) 01030 { 01031 FILE * fp; 01032 ACR_ELEMENT *p, *liste=NULL; 01033 01034 if((fp=fopen(filename,ID_RFILE_BIN))==0) { 01035 IdErrPrintf ("echec ouverture %s\n",filename); 01036 return (NULL); 01037 } 01038 sw= _IdAcrCheckSwap(fp); 01039 01040 if (__ID_CardioVascCurieux) { 01041 fseek(fp,0L,SEEK_SET); 01042 printf("ID_CardioVascCurieux : 6\n"); 01043 } 01044 01045 if(sw==-1) { 01046 IdErrPrintf ("fichier %s non ACR\n",filename); 01047 IdErrno=IDERR_NON_ACR_FILE; 01048 return (NULL); 01049 } 01050 __NumeroGroupePrecedent = 0; /*Pour etre sur que le premier sera + grand */ 01051 01052 while ( (p=_IdAcrReadNextElement(fp,mode)) ) { 01053 if (mode==2) { 01054 if(!(p->group%2)) { 01055 liste=_IdAcrAppendElement(liste,p); 01056 } 01057 } else { 01058 liste=_IdAcrAppendElement(liste,p); 01059 } 01060 } 01061 return (liste); 01062 } 01063 01064 01065 /* 01066 * ------------------------------------------------------------------------------------------------------ 01067 */ 01068 01069 /* ------------------------------------------------------------ */ 01070 /* A partir d'un fichier Acr deja ouvert, */ 01071 /* ds lequel on deja lu bufbid (8,10) */ 01072 /* et ty (signe : ( 28,103) */ 01073 /* on cherche le type stocke ( 28,105 ou 28,199 ) */ 01074 /* ou le type deduit ( a partir de nb et de ty ) */ 01075 /* */ 01076 /* retourne -1 si rien trouve ou rien deduit */ 01077 /* ------------------------------------------------------------ */ 01078 01079 short int _IdAcrCheckType(FILE * fp, char * bufbid, int ity, int inb, int itypObj) 01080 { 01081 long int lgrMessage; 01082 short int typ; 01083 short int ty=ity; 01084 short int nb=inb; 01085 short int typObj=itypObj; 01086 01087 01088 if (nb==12) nb=8; 01089 01090 typ= -1; 01091 if ( (memcmp(bufbid,"ACRNEMA_LIBIDO",14)==0) /* si c'est egal */ 01092 || 01093 (memcmp(bufbid,"CANRME_AILIBOD",14)==0) /* (en cas d'objet ACRLibido fait sr 1 autre machine) */ 01094 ) { 01095 if (DEBUG) IdPrintf ("on a trouve ACR LIBIDO\n"); 01096 01097 if (!_IdAcrReadElement(0x0028,0x0105,fp,&typ)) /* on cherche 28,105 */ 01098 _IdAcrReadElement(0x0028,0x0199,fp,&typ) ; /* si pas trouve on cherche 28,199 */ 01099 if (DEBUG) IdPrintf ("type lu sur disque %x\n",typ); 01100 } 01101 01102 if (typ==-1) { /* on n a rien trouve (ce n'EST PAS un fichier ACR-LibIDO nouvelle version) */ 01103 01104 /* debut usine a gaz */ 01105 01106 if((nb==TA_TY_UCHAR*8) && (ty==0))typ = typObj | TY_UCHAR; /* JPR */ 01107 else if((nb==TA_TY_CHAR*8) && (ty==1))typ = typObj | TY_CHAR; 01108 else if((nb==TA_TY_USHORT*8)&& (ty==0))typ = typObj | TY_USHORT; 01109 else if((nb==TA_TY_SHORT*8) && (ty==1))typ = typObj | TY_SHORT; 01110 else if((nb==TA_TY_ULONG*8) && (ty==0))typ = typObj | TY_ULONG; 01111 else if((nb==TA_TY_LONG*8) && (ty==1))typ = typObj | TY_LONG; 01112 01113 /* ATTENTION : les representations internes des types FLOAT et DOUBLE 01114 sont machine-dependent 01115 */ 01116 01117 /* les anciens float et doubles n etaient pas signes.... */ 01118 01119 else if ((nb==TA_TY_FLOAT*8) /* && (ty==1) */ ) typ = typObj | TY_FLOAT; 01120 else if ((nb==TA_TY_DOUBLE*8)/* && (ty==1) */ ) typ = typObj | TY_DOUBLE; /* JPR */ 01121 else if ((nb==3*TA_TY_UCHAR*8)&&(ty==0)) typ = typObj | TY_RGB; /*BB 6-JUL-1992 */ 01122 else if ((nb==TA_TY_COMPLEX_DOUBLE*8)) typ = typObj | TY_COMPLEX_DOUBLE; 01123 01124 if (DEBUG) IdPrintf ("Entete : nb=%d typObj=%x; Type deduit=%x\n", 01125 nb,typObj,typ); 01126 01127 /* ce N'EST PAS un fichier LibIDO */ 01128 01129 _message=(char *)malloc(10); /* pour eviter des soucis ulterieurs */ 01130 lgrMessage=0; 01131 01132 } else { /* fin usine a gaz */ 01133 01134 /* C'EST un fichier LibIDO */ 01135 /* on regarde si 'message' contient qq chose */ 01136 01137 lgrMessage= _IdAcrGetElementLength(0x0028,0x0198,fp); 01138 if (lgrMessage !=0) { 01139 if (DEBUG) IdPrintf ("lgrMessage %ld\n", lgrMessage); 01140 _message=(char *)malloc(lgrMessage+1); 01141 if (!_message) { 01142 IdErrPrintf("Impossible d allouer de la place pour _message ...\n"); 01143 _message=(char *)malloc(10); /* pour eviter des soucis ulterieurs */ 01144 } 01145 else 01146 01147 _IdAcrReadElement(0x0028,0x0198,fp,_message) ; /* on cherche 28,198 JPR */ 01148 } 01149 else 01150 _message=(char *)malloc(10); /* pour eviter des soucis ulterieurs */ 01151 } 01152 _message[lgrMessage]='\0'; /* Djamal Boukerroui */ 01153 01154 return typ; 01155 } 01156 01157 01158 01159 01160 01161 01162 /* FUNCTION DESCRIPTION ************************************************** 01163 01164 IdAcrInquireInfo (fonction) 01165 IdAcrInquireInfoTot (fonction) 01166 IdAcrInquireInfoTot2 (fonction) 01167 IdAcrInquireInfoTot3 (fonction) 01168 01169 RESUME: Retourne diverses info stockees dans l'entete ACRNEMA. 01170 01171 DESCRIPTION: NE PLUS UTILISER !! Retourne des info sur l'objet stocke dans un fichier ACRNEMA. 01172 01173 Remplace par IdAcrInquireInfoTot4, car incomplet 01174 On doit le laisser, car est peut etre utilise par de vieux programmes 01175 01176 ******************************************************** END DESCRIPTION */ 01177 01178 int IdAcrInquireInfo ( char * filename,unsigned short int *typObj,unsigned short int *typData,int *NX,int *NY,int *NZ,int *offset ) 01179 { 01180 unsigned short int typLibido; 01181 int NT; 01182 int nbFrames; 01183 int codeSwap; 01184 int nb; 01185 int nbu; 01186 int hb; 01187 int signe; 01188 return ( IdAcrInquireInfoTot4 ( filename,typObj,&typLibido,typData,NX,NY,NZ,&NT,offset,&nbFrames,&codeSwap,&nb,&nbu,&hb,&signe ) ); 01189 01190 } 01191 01192 /* -------------------- */ 01193 01194 int IdAcrInquireInfoTot ( char * filename, unsigned short int *typObj, unsigned short int *typLibido, unsigned short int *typData, int *NX, int *NY, int *NZ, int *NT, int *offset ) 01195 { 01196 int nbFrames; 01197 int codeSwap; 01198 int nb; 01199 int nbu; 01200 int hb; 01201 int signe; 01202 return ( IdAcrInquireInfoTot4 ( filename,typObj,typLibido,typData,NX,NY,NZ,NT,offset,&nbFrames,&codeSwap,&nb,&nbu,&hb,&signe ) ); 01203 } 01204 01205 /* -------------------- */ 01206 01207 int IdAcrInquireInfoTot2 ( char * filename, unsigned short int *typObj, unsigned short int *typLibido, unsigned short int *typData, int *NX, int *NY, int *NZ, int *NT, int *offset, int *nbFrames ) 01208 { 01209 int codeSwap; 01210 int nb; 01211 int nbu; 01212 int hb; 01213 int signe; 01214 return ( IdAcrInquireInfoTot4 ( filename,typObj,typLibido,typData,NX,NY,NZ,NT,offset,nbFrames,&codeSwap,&nb,&nbu,&hb,&signe ) ); 01215 } 01216 01217 /* -------------------- */ 01218 01219 int IdAcrInquireInfoTot3 ( char * filename, unsigned short int *typObj, unsigned short int *typLibido, unsigned short int *typData, int *NX, int *NY, int *NZ, int *NT, int *offset, int *nbFrames, int *codeSwap ) 01220 { 01221 int nb; 01222 int nbu; 01223 int hb; 01224 int signe; 01225 return ( IdAcrInquireInfoTot4 ( filename,typObj,typLibido,typData,NX,NY,NZ,NT,offset,nbFrames,codeSwap,&nb,&nbu,&hb,&signe ) ); 01226 } 01227 01228 01229 /* -------------------- */ 01230 01231 int _IdAcrIsAcrLibido(FILE *fp,char *bufbid) 01232 { 01233 if ( __TrueDicom == 0) { 01234 // Recognition Code --> n'existe plus en DICOM V3 ... 01235 // 01236 // ACR_NEMA 1.0 ou ACRNEMA_LIBIDO_1.1 01237 // On le lit ici pour eviter de revenir en arriere 01238 01239 if(_IdAcrReadElement(0x0008,0x0010,fp,bufbid)!=0) { 01240 01241 if ( (memcmp(bufbid,"ACRNEMA_LIBIDO",14)==0) 01242 // si c'est egal 01243 || (memcmp(bufbid,"CANRME_AILIBOD",14)==0)) 01244 // en cas d'objet ACRLibido fait sr 1 autre machine) 01245 return(1); 01246 } 01247 } 01248 01249 return(0); 01250 } 01251 01252 01253 /* -------------------- */ 01254 01255 void _IdAcrPositionSwap(FILE* fp) 01256 { 01257 sw = _IdAcrCheckSwap(fp); 01258 }

Generated on Wed Oct 19 09:28:32 2005 for SIMRI3D by doxygen 1.3.7