Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/med.git] / src / MEDWrapper / V2_1 / Core / MEDdatasetNumLire.cxx
1 /*************************************************************************
2 * COPYRIGHT (C) 1999 - 2002  EDF R&D
3 * THIS LIBRARY IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
4 * IT UNDER THE TERMS OF THE GNU LESSER GENERAL PUBLIC LICENSE 
5 * AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION; 
6 * EITHER VERSION 2.1 OF THE LICENSE, OR (AT YOUR OPTION) ANY LATER VERSION.
7 *  
8 * THIS LIBRARY IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
9 * WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
11 * LESSER GENERAL PUBLIC LICENSE FOR MORE DETAILS.
12 *
13 * YOU SHOULD HAVE RECEIVED A COPY OF THE GNU LESSER GENERAL PUBLIC LICENSE
14 * ALONG WITH THIS LIBRARY; IF NOT, WRITE TO THE FREE SOFTWARE FOUNDATION,
15 * INC., 59 TEMPLE PLACE, SUITE 330, BOSTON, MA 02111-1307 USA
16 *
17 *************************************************************************/
18
19 #include "med.hxx"
20 #include "med_outils.hxx"
21 #include <stdlib.h>
22 #include "hdf5_version2api.hxx"
23
24 /*
25  * - Nom de la fonction : _MEDdatasetNumLire
26  * - Description : lecture d'un dataset tableau numerique
27  * - Parametres :
28  *     - pere (IN)     : l'ID de l'objet HDF pere ou placer l'attribut
29  *     - nom  (IN)     : le nom du dataset
30  *     - type (IN)     : type numerique MED
31  *     - interlace (IN) : Choix du type d'entrelacement demandé par l'appelant { MED_FULL_INTERLACE(x1,y1,z1,x2,...)) , MED_NO_INTERLACE(x1,x2,y1,y2,z1,z2) }
32  *       - nbdim   (IN) : Dimension des éléments
33  *       - fixdim  (IN) : MED_ALL ou n° de la dimension a enregistrer à partir de 1..oo
34  *     - psize     (IN) : Taille du profil à utiliser, MED_NOPF si pas de profil
35  *       - pfltab  (IN) : Tableau contenant les n° déléments à traiter (1....oo)
36  *       - pflmod  (IN) : PARAMETRE A AJOUTER : Indique comment lire les informations en mémoire { MED_COMPACT, MED_GLOBALE }. 
37  *       - ngauss  (IN) : Nombre de points de GAUSS par élément
38  *     - val  (OUT)    : valeurs du tableau
39  * - Resultat : 0 en cas de succes, -1 sinon
40  *  Equivalent à l'ancienne routine si .....,MED_NO_INTERLACE,1,MED_ALL,MED_NOPF,0,1 (peu importe),....
41  */ 
42
43 namespace med_2_1{
44
45 med_err 
46 _MEDdatasetNumLire(med_idt pere,char *nom,med_type_champ type,
47                    med_mode_switch interlace, med_size nbdim, med_size fixdim, 
48                    med_size psize, med_ssize * pfltab, med_int ngauss,
49                    unsigned char *val)
50 {
51   med_idt    dataset, dataspace = 0, memspace = 0;
52 #ifdef HDF_NEW_API
53   med_size  start_mem[1],start_data[1],*pflmem=0,*pfldsk=0;
54 #else
55   med_ssize  start_mem[1],start_data[1],*pflmem=0,*pfldsk=0;
56 #endif
57   med_size   stride[1],count[1],pcount[1],size[1],pflsize[1];
58   med_err    ret;
59   int        i,j,index,type_hdf;
60   hid_t      datatype;
61   size_t     typesize;
62   int        dim, firstdim, dimutil, lastdim;
63   med_mode_profil pflmod;
64
65   /* Verify fixdim is between [0, nbdim] ( 0 is MED_ALL ) */
66   if ( ( fixdim < 0 ) || ( fixdim > nbdim ) ) 
67     return -1;
68  
69   /* block pflmod to MED_COMPACT (until med2.2) */
70   pflmod = MED_COMPACT;
71
72   switch(type)
73     {
74     case MED_REEL64 :
75       /* 1) IA32 is LE but due to an (?HDF convertion BUG?) when using H5T_NATIVE_DOUBLE/MED_REEL64? under PCLINUX
76             the file read under SGI is incorrect
77          2) Compaq OSF/1 is LE, since we force SGI64,SUN4SOL2,HP to write double in LE even if they are BE, mips OSF/1 must be BE
78          REM  : Be careful of compatibility between MED files when changing this (med2.2)
79          3) PPRO_NT is added for med2.1.6 support under Win32 */
80 #if defined(PCLINUX) || defined(OSF1) || defined(PPRO_NT) || defined(PCLINUX64) || defined(PCLINUX64_32)
81       type_hdf = H5T_IEEE_F64BE;
82 #else 
83       type_hdf = H5T_IEEE_F64LE;
84 #endif
85       break;
86
87     case MED_INT32 :
88       type_hdf = H5T_NATIVE_INT;
89       break;
90
91     case MED_INT64 :
92       type_hdf = H5T_NATIVE_LONG;
93       break;
94
95     default :
96       return -1;
97     }
98
99   /* Ouverture du Dataset à lire */
100   if ((dataset = H5Dopen(pere,nom)) < 0)
101     return -1;
102
103   /* Interrogation de la taille du dataset */
104   if ( (datatype  = H5Dget_type(dataset )) < 0) return -1;
105   if ( (typesize  = H5Tget_size(datatype)) < 0) return -1;
106   size[0] = H5Dget_storage_size(dataset) / typesize; 
107   if ( H5Tclose(datatype) < 0) return -1;
108
109   /* Create dataspace */
110   if ((dataspace = H5Screate_simple(1,size,NULL)) < 0)
111     return -1;
112   
113   switch(interlace)
114     {
115     case MED_FULL_INTERLACE :
116
117       /*Initialisation des indices de boucle du traitement de l'entrelacement en fonction de la dimension fixee*/
118       if ( fixdim != MED_ALL) 
119         { 
120           firstdim = (int)fixdim-1;
121           lastdim  = (int)fixdim;
122           dimutil  = 1;
123         } else  {
124           firstdim = 0;
125           lastdim = (int)nbdim;
126           dimutil  = (int)nbdim; 
127         }
128
129       count [0] = (*size)/(nbdim);
130       
131
132       /*rem: Pas de vérification de l'assertion (*size)=n*nbdim */
133       if ( psize == MED_NOPF ) {  
134
135       /* Creation d'un data space mémoire de dimension 1, de longeur size, et de longeur maxi size */
136       if ( (memspace = H5Screate_simple (1, size, NULL)) <0)
137         return -1;
138
139         stride[0] = nbdim;  
140
141         for (dim=firstdim; dim < lastdim; dim++) {
142                   
143           start_mem[0] = dim;
144           if ( (ret = H5Sselect_hyperslab (memspace, H5S_SELECT_SET, start_mem, stride, 
145                                            count, NULL)) <0)
146             return -1; 
147           
148           start_data[0] = dim*count[0];
149           if ( (ret = H5Sselect_hyperslab (dataspace, H5S_SELECT_SET, start_data, NULL, 
150                                            count, NULL)) <0)
151             return -1; 
152           
153           if ((ret = H5Dread(dataset,type_hdf,memspace,dataspace,
154                              H5P_DEFAULT, val)) < 0)
155             return -1;
156         }
157         
158       } else {
159
160         pflsize [0] = psize*ngauss*nbdim;
161         pcount  [0] = psize*ngauss*dimutil;
162 #ifdef HDF_NEW_API
163         pflmem     = (med_size *) malloc (sizeof(med_size)*(size_t)pcount[0]);
164         pfldsk     = (med_size *) malloc (sizeof(med_size)*(size_t)pcount[0]);
165 #else
166         pflmem     = (med_ssize *) malloc (sizeof(med_ssize)*(size_t)pcount[0]);
167         pfldsk     = (med_ssize *) malloc (sizeof(med_ssize)*(size_t)pcount[0]);
168 #endif
169         
170         switch(pflmod)
171           { /* switch pflmod pour FULL_INTERLACE*/
172           case MED_GLOBALE :
173
174             /* Creation d'un data space mémoire de dimension 1, de longeur size, et de longeur maxi size */
175             if ( (memspace = H5Screate_simple (1, size, NULL)) <0)
176               return -1;
177
178             for (dim=firstdim; dim < lastdim; dim++) {
179               
180               for (i=0; i < psize; i++)              /* i balaye les élements du profil */
181                 for (j=0; j < ngauss; j++) {         
182                   index = i*ngauss+j + (dim-firstdim)*((int)psize*ngauss);
183                   pflmem[index] = (pfltab[i]-1)*ngauss*nbdim + j*nbdim+dim;
184                   pfldsk[index] = dim*count[0] + (pfltab[i]-1)*ngauss+j;             
185                 }
186             }
187             
188 #ifdef HDF_NEW_API2
189             if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, (size_t)pcount[0], (const hsize_t *) pflmem ) ) <0) 
190               return -1; 
191             
192             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, (size_t)pcount[0], (const hsize_t *) pfldsk ) ) <0) 
193               return -1; 
194 #elif defined HDF_NEW_API
195             if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, (size_t)pcount[0], (const hsize_t **) pflmem ) ) <0) 
196               return -1; 
197             
198             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, (size_t)pcount[0], (const hsize_t **) pfldsk ) ) <0) 
199               return -1; 
200 #else
201             if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, (size_t)pcount[0], (const hssize_t **) pflmem ) ) <0) 
202               return -1; 
203             
204             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, (size_t)pcount[0], (const hssize_t **) pfldsk ) ) <0) 
205               return -1; 
206 #endif
207             
208             break;
209         
210           case MED_COMPACT :
211         
212             /* Creation d'un data space mémoire de dimension 1, de la longeur du profil          */
213             /* La dimension utilisée est ici nbdim, même pour un profil compact on suppose       */
214             /*  que l'utilisateur a toutes les coordonées stockées, même si il en demande qu'une */ 
215             
216             if ( (memspace = H5Screate_simple (1, pflsize, NULL)) <0)
217               return -1;
218             
219             for (dim=firstdim; dim < lastdim; dim++) {
220               
221               for (i=0; i < psize; i++)              /* i balaye les élements du profil */
222                 for (j=0; j < ngauss; j++) {         
223                   index = i*ngauss+j + (dim-firstdim)*((int)psize*ngauss);
224                   pflmem[index] = i*ngauss*nbdim + j*nbdim+dim;
225                   pfldsk[index] = dim*count[0] + (pfltab[i]-1)*ngauss+j;             
226                 }             
227             }
228             
229 #ifdef HDF_NEW_API2
230             if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, (size_t)pcount[0], (const hsize_t *) pflmem ) ) <0) 
231               return -1; 
232             
233             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, (size_t)pcount[0], (const hsize_t *) pfldsk ) ) <0) 
234               return -1; 
235 #elif defined HDF_NEW_API
236             if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, (size_t)pcount[0], (const hsize_t **) pflmem ) ) <0) 
237               return -1; 
238             
239             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, (size_t)pcount[0], (const hsize_t **) pfldsk ) ) <0) 
240               return -1; 
241 #else
242             if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, (size_t)pcount[0], (const hssize_t **) pflmem ) ) <0) 
243               return -1; 
244             
245             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, (size_t)pcount[0], (const hssize_t **) pfldsk ) ) <0) 
246               return -1; 
247 #endif
248             
249             break;
250
251           default :
252             return -1; 
253           }
254         
255         if ((ret = H5Dread(dataset,type_hdf,memspace,dataspace,H5P_DEFAULT, val)) < 0)
256           return -1;
257         
258         free(pflmem);
259         free(pfldsk);
260       }
261      
262       break;
263       
264     case MED_NO_INTERLACE :
265
266       /*Initialisation des indices de boucle du traitement de l'entrelacement en fonction de la dimension fixee*/
267
268       count[0] = (*size)/nbdim;
269       
270       if ( psize == MED_NOPF ) {  
271         
272         if ( fixdim != MED_ALL) 
273           start_data[0] = (fixdim-1)*count[0];
274         else {
275           count[0] = *size;
276           start_data[0] =  0;
277         };
278         
279         if ( (ret = H5Sselect_hyperslab (dataspace, H5S_SELECT_SET, start_data, NULL, 
280                                          count, NULL)) <0)
281           return -1; 
282         
283         if ((ret = H5Dread(dataset,type_hdf,dataspace,dataspace,
284                            H5P_DEFAULT, val)) < 0)
285           return -1;
286         
287       } else {
288
289         if ( fixdim != MED_ALL) 
290           { 
291             firstdim = (int)fixdim-1;
292             lastdim  = (int)fixdim;
293             dimutil  = 1;
294           } else        {
295             firstdim = 0;
296             lastdim  = (int)nbdim;
297             dimutil  = (int)nbdim; 
298           }
299
300         pflsize [0] = psize*ngauss*nbdim;       
301         pcount  [0] = psize*ngauss*dimutil; /* nom pas très coherent avec count !!! A revoir */      
302 #ifdef HDF_NEW_API
303         pfldsk      = (med_size *) malloc(sizeof(med_size)*(size_t)pcount[0]);
304 #else
305         pfldsk      = (med_ssize *) malloc(sizeof(med_ssize)*(size_t)pcount[0]);
306 #endif
307         
308         switch(pflmod)
309           { /*switch plfmod pour NO_INTERLACE */
310           case MED_GLOBALE :
311             
312             for (dim=firstdim; dim < lastdim; dim++) {
313               
314               for (i=0; i < psize; i++)              /* i balaye le nbre d'élements du profil                */
315                 for (j=0; j < ngauss; j++) { 
316                   index = i*ngauss+j + (dim-firstdim)*((int)psize*ngauss);
317                   pfldsk[index] = dim*count[0]+(pfltab[i]-1)*ngauss+j;      
318                 }
319             }
320             
321 #ifdef HDF_NEW_API2
322             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,(size_t)pcount[0], (const hsize_t *) pfldsk ) ) <0) 
323               return -1;
324 #elif defined HDF_NEW_API
325             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,(size_t)pcount[0], (const hsize_t **) pfldsk ) ) <0) 
326               return -1;
327 #else
328             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,(size_t)pcount[0], (const hssize_t **) pfldsk ) ) <0) 
329               return -1;
330 #endif
331             
332             if ((ret = H5Dread(dataset,type_hdf,dataspace,dataspace,H5P_DEFAULT, val)) < 0)
333               return -1;
334               
335             break;
336             
337           case MED_COMPACT :
338             
339             /* Creation d'un data space mémoire de dimension 1, de la longeur du profil          */
340             /* La dimension utilisée est ici nbdim, même pour un profil compact on suppose       */
341             /*  que l'utilisateur a toutes les coordonées stockées, même si il en demande qu'une */ 
342
343             if ( (memspace = H5Screate_simple (1, pflsize, NULL)) <0)
344               return -1;
345
346 #ifdef HDF_NEW_API
347             pflmem     = (med_size *) malloc (sizeof(med_size)*(size_t)pcount[0]);
348 #else
349             pflmem     = (med_ssize *) malloc (sizeof(med_ssize)*(size_t)pcount[0]);
350 #endif
351             
352             /* Le profil COMPACT est contigüe, mais il est possible que l'on selectionne uniquemenent une dimension*/
353
354             index = 0;
355             for (dim=firstdim; dim < lastdim; dim++) {
356               
357               for (i=0; i < psize; i++)              /* i balaye le nbre d'élements du profil                */
358                 for (j=0; j < ngauss; j++) {
359 //                index = i*ngauss+j + (dim-firstdim)*(psize*ngauss);
360 //                pflmem[index] = dim*(psize*ngauss) + (pfltab[i]-1)*ngauss+j;
361 //                pfldsk[index] = dim*count[0]  + (pfltab[i]-1)*ngauss+j;           
362                   pflmem[index] = ( (dim*psize) + i )*ngauss + j;
363                   pfldsk[index] = dim*count[0]  + (pfltab[i]-1)*ngauss+j;
364                   index++;          
365                 }
366             }
367             
368 #ifdef HDF_NEW_API2
369             if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, (size_t)pcount[0], (const hsize_t *) pflmem ) ) <0) 
370               return -1; 
371             
372             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,(size_t)pcount[0], (const hsize_t *) pfldsk ) ) <0) 
373               return -1;          
374 #elif defined HDF_NEW_API
375             if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, (size_t)pcount[0], (const hsize_t **) pflmem ) ) <0) 
376               return -1; 
377             
378             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,(size_t)pcount[0], (const hsize_t **) pfldsk ) ) <0) 
379               return -1;          
380 #else
381             if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, (size_t)pcount[0], (const hssize_t **) pflmem ) ) <0) 
382               return -1; 
383             
384             if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,(size_t)pcount[0], (const hssize_t **) pfldsk ) ) <0) 
385               return -1;          
386 #endif
387             
388             if ((ret = H5Dread(dataset,type_hdf,memspace,dataspace,H5P_DEFAULT, val)) < 0)
389               return -1;
390             
391             break;
392             
393           default :
394             return -1;      
395             
396           }
397         
398         free(pfldsk);
399                 
400       };
401       
402       break;
403       
404     default :
405       return -1;
406     }
407   
408   
409
410   if (memspace) 
411     if ((ret = H5Sclose(memspace)) < 0)
412       return -1;
413
414   if ((ret = H5Sclose(dataspace)) < 0)
415     return -1;
416   
417   if ((ret = H5Dclose(dataset)) < 0)
418     return -1;      
419
420   return 0;
421 }
422
423 }