]> Creatis software - gdcm.git/blob - src/gdcmFile.cxx
ajout quelques fonctions gdcmFile
[gdcm.git] / src / gdcmFile.cxx
1 // gdcmFile.cxx
2
3 #include "gdcm.h"
4
5 #define DEBUG 1
6
7 static void _Swap(void* im, int swap, int lgr, int nb);
8
9 /////////////////////////////////////////////////////////////////
10 /**
11  * \ingroup   gdcmFile
12  * \brief Constructor dedicated to writing a new DICOMV3 part10 compliant
13  * \file (see SetFileName, SetDcmTag and Write)
14  * \Opens (in read only and when possible) an existing file and checks
15  * \for DICOM compliance. Returns NULL on failure.
16  * \Note: the in-memory representation of all available tags found in
17  * \the DICOM header is post-poned to first header information access.
18  * \This avoid a double parsing of public part of the header when
19  * \one sets an a posteriori shadow dictionary (efficiency can be
20  * \seen as a side effect).   
21  *
22  * @param 
23  *
24  * @return      
25  */
26  
27 gdcmFile::gdcmFile(string & filename)
28         :gdcmHeader(filename.c_str())
29 {
30         if (DEBUG) printf("On a echappe a gdcmHeader !\n");
31 }
32
33
34 /////////////////////////////////////////////////////////////////
35 /**
36  * \ingroup   gdcmFile
37  * \brief     Renvoie la longueur A ALLOUER pour recevoir les pixels de l'image
38  * \            ou DES images dans le cas d'un multiframe
39  * \            ATTENTION : il ne s'agit PAS de la longueur du groupe des Pixels        
40  * \            (dans le cas d'images compressees, elle n'a pas de sens).
41  *
42  * @param void  Rien en entree
43  *
44  * @return      longueur a allouer 
45  */
46
47 size_t gdcmFile::GetImageDataSize(void) {
48         int nbLignes, nbCol, nbFrames, nb;
49         string str_nbFrames, str_nb;
50         // Nombre de Lignes     
51         nbLignes=atoi(gdcmHeader::GetPubElValByNumber(0x0028,0x0010).c_str());
52         // Nombre de Colonnes   
53         nbCol   =atoi(gdcmHeader::GetPubElValByNumber(0x0028,0x0011).c_str());
54
55         // Nombre de Frames     
56         str_nbFrames=gdcmHeader::GetPubElValByNumber(0x0028,0x0008);
57         
58         if (str_nbFrames == "UNFOUND" ) {
59                 nbFrames = 1;
60         } else {
61                 nbFrames = atoi(str_nbFrames.c_str() );
62         }
63         
64         // Nombre de Bits Alloues pour le stockage d'un Pixel   
65         str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100);
66
67         if (str_nb == "UNFOUND" ) {
68                 nb = 16;
69         } else {
70                 nb = atoi(str_nb.c_str() );
71         }
72
73         size_t lgrTotale = nbFrames*nbLignes*nbCol*(nb/8);
74         return (lgrTotale);
75
76 }
77
78 /////////////////////////////////////////////////////////////////
79 /**
80  * \ingroup   gdcmFile
81  * \brief amene en mémoire les Pixels d'une image NON COMPRESSEE
82  * \Aucun test n'est fait pour le moment sur le caractere compresse ou non de l'image
83  *
84  * @param rien
85  *
86  * @return      Pointeur sur la zone mémoire contenant les Pixels lus
87  */
88
89 void * gdcmFile::GetImageData (void) {
90         
91         char* _Pixels;
92         int nbLignes, nbCol;
93
94         int nbFrames, nb, nbu, highBit, signe;
95         string str_nbFrames, str_nb, str_nbu, str_highBit, str_signe;
96         
97         unsigned short int mask = 0xffff;
98                 
99         // Nombre de Lignes     
100         nbLignes=atoi(GetPubElValByNumber(0x0028,0x0010).c_str());
101         // Nombre de Colonnes   
102         nbCol   =atoi(GetPubElValByNumber(0x0028,0x0011).c_str());
103
104         // Nombre de Frames     
105         str_nbFrames=GetPubElValByNumber(0x0028,0x0008);
106
107         
108         if (str_nbFrames == "UNFOUND" ) {
109                 nbFrames = 1;
110         } else {
111                 nbFrames = atoi(str_nbFrames.c_str() );
112         }
113         
114         // Nombre de Bits Alloues       
115         str_nb=GetPubElValByNumber(0x0028,0x0100);
116
117         if (str_nb == "UNFOUND" ) {
118                 nb = 16;
119         } else {
120                 nb = atoi(str_nb.c_str() );
121         }
122         
123         // Nombre de Bits Utilises      
124         str_nbu=GetPubElValByNumber(0x0028,0x0101);
125
126         if (str_nbu == "UNFOUND" ) {
127                 nbu = nb;
128         } else {
129                 nbu = atoi(str_nbu.c_str() );
130         }       
131         
132         // Position du Bit de Poids Fort        
133         str_highBit=GetPubElValByNumber(0x0028,0x0102);
134
135         if (str_highBit == "UNFOUND" ) {
136                 highBit = nb - 1;
137         } else {
138                 highBit = atoi(str_highBit.c_str() );
139         }
140                 
141         // Signe des Pixels 0 : Unsigned
142         str_signe=GetPubElValByNumber(0x0028,0x0103);
143
144         if (str_signe == "UNFOUND" ) {
145                 signe = 1;
146         } else {
147                 signe = atoi(str_signe.c_str() );
148         }
149         
150         // Longueur en Octets des Pixels a lire
151         size_t _lgrTotale = nbFrames*nbLignes*nbCol*(nb/8);
152         
153         //Pixels = (char *) g_malloc(_lgrTotale);
154         _Pixels = (char *) malloc(_lgrTotale);
155         
156         GetPixels(lgrTotale, _Pixels);
157
158         // On remet les Octets dans le bon ordre si besoin est
159         if (nb != 8) {
160                 int _sw = GetSwapCode();
161
162                 _Swap (_Pixels, _sw, _lgrTotale, nb);
163         }
164         
165         // On remet les Bits des Octets dans le bon ordre si besoin est
166         //
167         // ATTENTION :  Jamais confronté a des pixels stockes sur 32 bits 
168         //                      avec moins de 32 bits utilises
169         //                      et dont le bit de poids fort ne serait pas la ou on l'attend ...
170         //                      --> ne marchera pas dans ce cas 
171         if (nbu!=nb){
172                 mask = mask >> (nb-nbu);
173                 int l=(int)_lgrTotale/(nb/8);
174                 unsigned short *deb = (unsigned short *)_Pixels;
175                 for(int i=0;i<l;i++) {
176                                 *deb = (*deb >> (nbu-highBit-1)) & mask;
177                                 deb ++;
178                 }
179         }
180                 
181         printf ("on est sorti\n");
182         
183         // On l'affecte à un champ du dcmFile
184         
185         Pixels = _Pixels;
186         lgrTotale = _lgrTotale;
187         
188         return (_Pixels);               
189 }
190
191
192 /////////////////////////////////////////////////////////////////
193 /**
194  * \ingroup   gdcmFile
195  * \brief amene en mémoire dans une zone précisee par l'utilisateur
196  * \les Pixels d'une image NON COMPRESSEE
197  * \Aucun test n'est fait pour le moment sur le caractere compresse ou non de l'image
198  *
199  * @param 
200  *
201  * @return      
202  */
203
204 int gdcmFile::PutImageDataHere (void* destination, size_t MaxSize) {
205         
206         void * Pixels = destination;  // pour garder le code identique avec GetImageData
207         int nbLignes, nbCol;
208
209         int nbFrames, nb, nbu, highBit, signe;
210         string str_nbFrames, str_nb, str_nbu, str_highBit, str_signe;
211         
212         unsigned short int mask = 0xffff;
213                 
214         // Nombre de Lignes     
215         nbLignes=atoi(GetPubElValByNumber(0x0028,0x0010).c_str());
216         // Nombre de Colonnes   
217         nbCol   =atoi(GetPubElValByNumber(0x0028,0x0011).c_str());
218
219         // Nombre de Frames     
220         str_nbFrames=GetPubElValByNumber(0x0028,0x0008);
221
222         
223         if (str_nbFrames == "UNFOUND" ) {
224                 nbFrames = 1;
225         } else {
226                 nbFrames = atoi(str_nbFrames.c_str() );
227         }
228         
229         // Nombre de Bits Alloues       
230         str_nb=GetPubElValByNumber(0x0028,0x0100);
231
232         if (str_nb == "UNFOUND" ) {
233                 nb = 16;
234         } else {
235                 nb = atoi(str_nb.c_str() );
236         }
237         
238         // Nombre de Bits Utilises      
239         str_nbu=GetPubElValByNumber(0x0028,0x0101);
240
241         if (str_nbu == "UNFOUND" ) {
242                 nbu = nb;
243         } else {
244                 nbu = atoi(str_nbu.c_str() );
245         }       
246         
247         // Position du Bit de Poids Fort        
248         str_highBit=GetPubElValByNumber(0x0028,0x0102);
249
250         if (str_highBit == "UNFOUND" ) {
251                 highBit = nb - 1;
252         } else {
253                 highBit = atoi(str_highBit.c_str() );
254         }
255                 
256         // Signe des Pixels 
257         str_signe=GetPubElValByNumber(0x0028,0x0103);
258
259         if (str_signe == "UNFOUND" ) {
260                 signe = 1;
261         } else {
262                 signe = atoi(str_signe.c_str() );
263         }
264         
265         // Longueur en Octets des Pixels a lire
266         size_t lgrTotale = nbFrames*nbLignes*nbCol*(nb/8);
267         
268         // si lgrTotale < MaxSize ==> Gros pb . A VOIR
269         
270         lgrTotale = MaxSize;                                    // pour garder le code identique avec GetImageData
271         //Pixels = (char *) malloc(lgrTotale);  // pour garder le code identique avec GetImageData
272         
273         GetPixels(lgrTotale, Pixels);
274
275         // On remet les Octets dans le bon ordre si besoin est
276         if (nb != 8) {
277                 int _sw = GetSwapCode();
278
279                 _Swap (Pixels, _sw, lgrTotale, nb);
280         }
281         
282         // On remet les Bits des Octets dans le bon ordre si besoin est
283         //
284         // ATTENTION :  Jamais confronté a des pixels stockes sur 32 bits 
285         //                      avec moins de 32 bits utilises
286         //                      et dont le bit de poids fort ne serait pas la ou on l'attend ...
287         //                      --> ne marchera pas dans ce cas 
288         if (nbu!=nb){
289                 mask = mask >> (nb-nbu);
290                 int l=(int)lgrTotale/(nb/8);
291                 unsigned short *deb = (unsigned short *)Pixels;
292                 for(int i=0;i<l;i++) {
293                                 *deb = (*deb >> (nbu-highBit-1)) & mask;
294                                 deb ++;
295                 }
296         }
297                 
298         printf ("on est sorti\n");
299         
300         // VOIR s'il ne faudrait pas l'affecter à un champ du dcmHeader
301         
302         //return (Pixels);                              // pour garder le code identique avec GetImageData      
303         return 1; 
304 }
305
306 //
307 // Je laisse le code integral, au cas ça puisse etre reutilise ailleurs
308 //
309
310 static void _Swap(void* im, int swap, int lgr, int nb) {                     
311 guint32 s32;
312 guint16 fort,faible;
313 int i;
314
315 if(nb == 16)
316     
317         switch(swap) {
318                 case 0:
319                 case 12:
320                 case 1234:
321                         break;
322                 
323                 case 21:
324                 case 3412:
325                 case 2143:
326                 case 4321:
327
328                         for(i=0;i<lgr;i++)
329                                 ((unsigned short int*)im)[i]= ((((unsigned short int*)im)[i])>>8)
330                                                 | ((((unsigned short int*)im)[i])<<8);
331                         break;
332                         
333                 default:
334                         printf("valeur de SWAP (16 bits) non autorisee : %d\n", swap);
335         } 
336  
337 if( nb == 32 )
338
339         switch (swap) {
340                 case 0:
341                 case 1234:
342                          break;
343
344                 case 4321:
345                          for(i=0;i<lgr;i++) {
346                                 faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 4321 */
347                                 fort  =((unsigned long int*)im)[i]>>16;
348                                 fort=  (fort>>8)   | (fort<<8);
349                                 faible=(faible>>8) | (faible<<8);
350                                 s32=faible;
351                                 ((unsigned long int*)im)[i]=(s32<<16)|fort;
352                         }
353                         break;
354
355                 case 2143:
356                         for(i=0;i<lgr;i++) {
357                                 faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 2143 */
358                                 fort=((unsigned long int*)im)[i]>>16;
359                                 fort=  (fort>>8)   | (fort<<8);
360                                 faible=(faible>>8) | (faible<<8);
361                                 s32=fort; 
362                                 ((unsigned long int*)im)[i]=(s32<<16)|faible;
363                         }
364                         break;
365   
366                 case 3412:
367                         for(i=0;i<lgr;i++) {
368                                 faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 3412 */
369                                 fort=((unsigned long int*)im)[i]>>16;                  
370                                 s32=faible; 
371                                 ((unsigned long int*)im)[i]=(s32<<16)|fort;
372                         }                 
373                         break; 
374                                 
375                 default:
376                         printf("valeur de SWAP (32 bits) non autorisee : %d\n", swap);
377         } 
378 return;
379 }
380
381
382
383
384 /////////////////////////////////////////////////////////////////
385 /**
386  * \ingroup   gdcmFile
387  * \brief Ecrit sur disque les pixels d'UNE image
388  * \Aucun test n'est fait sur l'"Endiannerie" du processeur.
389  * \ C'est à l'utilisateur d'appeler son Reader correctement
390  * \(Equivalent a IdImaWriteRawFile) 
391  *
392  * @param 
393  *
394  * @return      
395  */
396
397 int gdcmFile::WriteRawData (string nomFichier) {
398
399         FILE * fp1;
400         fp1 = fopen(nomFichier.c_str(),"wb");
401         if (fp1 == NULL) {
402                 printf("Echec ouverture (ecriture) Fichier [%s] \n",nomFichier.c_str());
403                 return (0);
404         } 
405         
406         fwrite (Pixels,lgrTotale, 1, fp1);
407         fclose (fp1);
408 }
409         
410