]> Creatis software - gdcm.git/blob - src/gdcmFile.cxx
Ajout fonctions
[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 printf("nbCol %d\n",nbCol);
56 printf("nbLig %d\n",nbLignes);
57
58
59         // Nombre de Frames     
60         str_nbFrames=gdcmHeader::GetPubElValByNumber(0x0028,0x0008);
61         
62         if (str_nbFrames == "gdcm::Unfound" ) {
63                 nbFrames = 1;
64         } else {
65                 nbFrames = atoi(str_nbFrames.c_str() );
66         }
67 printf("nbFrames %d\n",nbFrames);
68         
69         // Nombre de Bits Alloues pour le stockage d'un Pixel   
70         str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100);
71
72         if (str_nb == "gdcm::Unfound" ) {
73                 nb = 16;
74         } else {
75                 nb = atoi(str_nb.c_str() );
76         }
77
78 printf("nb %d\n",nb);
79
80         size_t lgrTotale = nbFrames*nbLignes*nbCol*(nb/8);
81         return (lgrTotale);
82
83 }
84
85 /////////////////////////////////////////////////////////////////
86 /**
87  * \ingroup   gdcmFile
88  * \brief amene en mémoire les Pixels d'une image NON COMPRESSEE
89  * \Aucun test n'est fait pour le moment sur le caractere compresse ou non de l'image
90  *
91  * @param rien
92  *
93  * @return      Pointeur sur la zone mémoire contenant les Pixels lus
94  */
95
96 void * gdcmFile::GetImageData (void) {
97         
98         char* _Pixels;
99         int nbLignes, nbCol;
100
101         int nbFrames, nb, nbu, highBit, signe;
102         string str_nbFrames, str_nb, str_nbu, str_highBit, str_signe;
103         
104         unsigned short int mask = 0xffff;
105                 
106         // Nombre de Lignes     
107         nbLignes=atoi(GetPubElValByNumber(0x0028,0x0010).c_str());
108         // Nombre de Colonnes   
109         nbCol   =atoi(GetPubElValByNumber(0x0028,0x0011).c_str());
110
111         // Nombre de Frames     
112         str_nbFrames=GetPubElValByNumber(0x0028,0x0008);
113
114         
115         if (str_nbFrames == "gdcm::Unfound" ) {
116                 nbFrames = 1;
117         } else {
118                 nbFrames = atoi(str_nbFrames.c_str() );
119         }
120         
121         // Nombre de Bits Alloues       
122         str_nb=GetPubElValByNumber(0x0028,0x0100);
123
124         if (str_nb == "gdcm::Unfound" ) {
125                 nb = 16;
126         } else {
127                 nb = atoi(str_nb.c_str() );
128         }
129         
130         // Nombre de Bits Utilises      
131         str_nbu=GetPubElValByNumber(0x0028,0x0101);
132
133         if (str_nbu == "gdcm::Unfound" ) {
134                 nbu = nb;
135         } else {
136                 nbu = atoi(str_nbu.c_str() );
137         }       
138         
139         // Position du Bit de Poids Fort        
140         str_highBit=GetPubElValByNumber(0x0028,0x0102);
141
142         if (str_highBit == "gdcm::Unfound" ) {
143                 highBit = nb - 1;
144         } else {
145                 highBit = atoi(str_highBit.c_str() );
146         }
147                 
148         // Signe des Pixels 0 : Unsigned
149         str_signe=GetPubElValByNumber(0x0028,0x0103);
150
151         if (str_signe == "gdcm::Unfound" ) {
152                 signe = 1;
153         } else {
154                 signe = atoi(str_signe.c_str() );
155         }
156         
157         // Longueur en Octets des Pixels a lire
158         size_t _lgrTotale = nbFrames*nbLignes*nbCol*(nb/8);
159         
160         //Pixels = (char *) g_malloc(_lgrTotale);
161         _Pixels = (char *) malloc(_lgrTotale);
162         
163         GetPixels(lgrTotale, _Pixels);
164
165         // On remet les Octets dans le bon ordre si besoin est
166         if (nb != 8) {
167                 int _sw = GetSwapCode();
168
169                 _Swap (_Pixels, _sw, _lgrTotale, nb);
170         }
171         
172         // On remet les Bits des Octets dans le bon ordre si besoin est
173         //
174         // ATTENTION :  Jamais confronté a des pixels stockes sur 32 bits 
175         //                      avec moins de 32 bits utilises
176         //                      et dont le bit de poids fort ne serait pas la ou on l'attend ...
177         //                      --> ne marchera pas dans ce cas 
178         if (nbu!=nb){
179                 mask = mask >> (nb-nbu);
180                 int l=(int)_lgrTotale/(nb/8);
181                 unsigned short *deb = (unsigned short *)_Pixels;
182                 for(int i=0;i<l;i++) {
183                                 *deb = (*deb >> (nbu-highBit-1)) & mask;
184                                 deb ++;
185                 }
186         }
187                 
188         printf ("on est sorti\n");
189         
190         // On l'affecte à un champ du dcmFile
191         
192         Pixels = _Pixels;
193         lgrTotale = _lgrTotale;
194         
195         // et on le retourne
196         // ca fait double emploi, il faudra nettoyer ça
197         
198         return (_Pixels);               
199 }
200
201
202 /////////////////////////////////////////////////////////////////
203 /**
204  * \ingroup   gdcmFile
205  * \brief amene en mémoire dans une zone précisee par l'utilisateur
206  * \les Pixels d'une image NON COMPRESSEE
207  * \Aucun test n'est fait pour le moment sur le caractere compresse ou non de l'image
208  *
209  * @param 
210  *
211  * @return      
212  */
213
214 int gdcmFile::PutImageDataHere (void* destination, size_t MaxSize) {
215         
216         void * Pixels = destination;  // pour garder le code identique avec GetImageData
217         int nbLignes, nbCol;
218
219         int nbFrames, nb, nbu, highBit, signe;
220         string str_nbFrames, str_nb, str_nbu, str_highBit, str_signe;
221         
222         unsigned short int mask = 0xffff;
223                 
224         // Nombre de Lignes     
225         nbLignes=atoi(GetPubElValByNumber(0x0028,0x0010).c_str());
226         // Nombre de Colonnes   
227         nbCol   =atoi(GetPubElValByNumber(0x0028,0x0011).c_str());
228
229         // Nombre de Frames     
230         str_nbFrames=GetPubElValByNumber(0x0028,0x0008);
231
232         
233         if (str_nbFrames == "gdcm::Unfound" ) {
234                 nbFrames = 1;
235         } else {
236                 nbFrames = atoi(str_nbFrames.c_str() );
237         }
238         
239         // Nombre de Bits Alloues       
240         str_nb=GetPubElValByNumber(0x0028,0x0100);
241
242         if (str_nb == "gdcm::Unfound" ) {
243                 nb = 16;
244         } else {
245                 nb = atoi(str_nb.c_str() );
246         }
247         
248         // Nombre de Bits Utilises      
249         str_nbu=GetPubElValByNumber(0x0028,0x0101);
250
251         if (str_nbu == "gdcm::Unfound" ) {
252                 nbu = nb;
253         } else {
254                 nbu = atoi(str_nbu.c_str() );
255         }       
256         
257         // Position du Bit de Poids Fort        
258         str_highBit=GetPubElValByNumber(0x0028,0x0102);
259
260         if (str_highBit == "gdcm::Unfound" ) {
261                 highBit = nb - 1;
262         } else {
263                 highBit = atoi(str_highBit.c_str() );
264         }
265                 
266         // Signe des Pixels 
267         str_signe=GetPubElValByNumber(0x0028,0x0103);
268
269         if (str_signe == "gdcm::Unfound" ) {
270                 signe = 1;
271         } else {
272                 signe = atoi(str_signe.c_str() );
273         }
274         
275         // Longueur en Octets des Pixels a lire
276         size_t lgrTotale = nbFrames*nbLignes*nbCol*(nb/8);
277         
278         // si lgrTotale < MaxSize ==> Gros pb . A VOIR
279         
280         lgrTotale = MaxSize;                                    // pour garder le code identique avec GetImageData
281         //Pixels = (char *) malloc(lgrTotale);  // pour garder le code identique avec GetImageData
282         
283         GetPixels(lgrTotale, Pixels);
284
285         // On remet les Octets dans le bon ordre si besoin est
286         if (nb != 8) {
287                 int _sw = GetSwapCode();
288
289                 _Swap (Pixels, _sw, lgrTotale, nb);
290         }
291         
292         // On remet les Bits des Octets dans le bon ordre si besoin est
293         //
294         // ATTENTION :  Jamais confronté a des pixels stockes sur 32 bits 
295         //                      avec moins de 32 bits utilises
296         //                      et dont le bit de poids fort ne serait pas la ou on l'attend ...
297         //                      --> ne marchera pas dans ce cas 
298         if (nbu!=nb){
299                 mask = mask >> (nb-nbu);
300                 int l=(int)lgrTotale/(nb/8);
301                 unsigned short *deb = (unsigned short *)Pixels;
302                 for(int i=0;i<l;i++) {
303                                 *deb = (*deb >> (nbu-highBit-1)) & mask;
304                                 deb ++;
305                 }
306         }
307                 
308         printf ("on est sorti\n");
309         
310         // VOIR s'il ne faudrait pas l'affecter à un champ du dcmHeader
311         
312         //return (Pixels);                              // pour garder le code identique avec GetImageData      
313         return 1; 
314 }
315
316 //
317 // Je laisse le code integral, au cas ça puisse etre reutilise ailleurs
318 //
319
320 static void _Swap(void* im, int swap, int lgr, int nb) {                     
321 guint32 s32;
322 guint16 fort,faible;
323 int i;
324
325 if(nb == 16)
326     
327         switch(swap) {
328                 case 0:
329                 case 12:
330                 case 1234:
331                         break;
332                 
333                 case 21:
334                 case 3412:
335                 case 2143:
336                 case 4321:
337
338                         for(i=0;i<lgr;i++)
339                                 ((unsigned short int*)im)[i]= ((((unsigned short int*)im)[i])>>8)
340                                                 | ((((unsigned short int*)im)[i])<<8);
341                         break;
342                         
343                 default:
344                         printf("valeur de SWAP (16 bits) non autorisee : %d\n", swap);
345         } 
346  
347 if( nb == 32 )
348
349         switch (swap) {
350                 case 0:
351                 case 1234:
352                          break;
353
354                 case 4321:
355                          for(i=0;i<lgr;i++) {
356                                 faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 4321 */
357                                 fort  =((unsigned long int*)im)[i]>>16;
358                                 fort=  (fort>>8)   | (fort<<8);
359                                 faible=(faible>>8) | (faible<<8);
360                                 s32=faible;
361                                 ((unsigned long int*)im)[i]=(s32<<16)|fort;
362                         }
363                         break;
364
365                 case 2143:
366                         for(i=0;i<lgr;i++) {
367                                 faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 2143 */
368                                 fort=((unsigned long int*)im)[i]>>16;
369                                 fort=  (fort>>8)   | (fort<<8);
370                                 faible=(faible>>8) | (faible<<8);
371                                 s32=fort; 
372                                 ((unsigned long int*)im)[i]=(s32<<16)|faible;
373                         }
374                         break;
375   
376                 case 3412:
377                         for(i=0;i<lgr;i++) {
378                                 faible=  ((unsigned long int*)im)[i]&0x0000ffff;    /* 3412 */
379                                 fort=((unsigned long int*)im)[i]>>16;                  
380                                 s32=faible; 
381                                 ((unsigned long int*)im)[i]=(s32<<16)|fort;
382                         }                 
383                         break; 
384                                 
385                 default:
386                         printf("valeur de SWAP (32 bits) non autorisee : %d\n", swap);
387         } 
388 return;
389 }
390
391
392
393
394 /////////////////////////////////////////////////////////////////
395 /**
396  * \ingroup   gdcmFile
397  * \brief Ecrit sur disque les pixels d'UNE image
398  * \Aucun test n'est fait sur l'"Endiannerie" du processeur.
399  * \ C'est à l'utilisateur d'appeler son Reader correctement
400  * \(Equivalent a IdImaWriteRawFile) 
401  *
402  * @param 
403  *
404  * @return      
405  */
406
407 int gdcmFile::WriteRawData (string nomFichier) {
408
409         FILE * fp1;
410         fp1 = fopen(nomFichier.c_str(),"wb");
411         if (fp1 == NULL) {
412                 printf("Echec ouverture (ecriture) Fichier [%s] \n",nomFichier.c_str());
413                 return (0);
414         } 
415         
416         fwrite (Pixels,lgrTotale, 1, fp1);
417         fclose (fp1);
418 }
419         
420