2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - Scilab Enterprises - Antoine ELIAS
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
19 //#include <winbase.h>
26 #include "sci_types.h"
28 #include "h5_attributeConstants.h"
29 #include "h5_readDataFromFile.h"
33 static herr_t find_attr_by_name(hid_t loc_id, const char *name, void *data)
35 return !strcmp(name, (const char *)data);
38 /************************************************************
40 Operator function. Prints the name and type of the object
43 ************************************************************/
44 static herr_t op_func(hid_t loc_id, const char *name, void *operator_data)
48 int *pDataSetId = (int*)operator_data;
51 * Get type of the object and return only datasetId
52 * through operator_data.
54 status = H5Gget_objinfo(loc_id, name, 0, &statbuf);
65 *pDataSetId = H5Dopen(loc_id, name);
76 static int readIntAttribute(int _iDatasetId, const char *_pstName)
82 if (H5Aiterate(_iDatasetId, NULL, find_attr_by_name, (void *)_pstName))
84 iAttributeId = H5Aopen_name(_iDatasetId, _pstName);
90 status = H5Aread(iAttributeId, H5T_NATIVE_INT, &iVal);
96 status = H5Aclose(iAttributeId);
106 ** WARNING : this function returns an allocated value that must be freed.
108 static char* readAttribute(int _iDatasetId, const char *_pstName)
111 hid_t iFileType, memtype, iSpace;
116 char *pstValue = NULL;
118 if (H5Aiterate(_iDatasetId, NULL, find_attr_by_name, (void *)_pstName))
120 iAttributeId = H5Aopen_name(_iDatasetId, _pstName);
121 if (iAttributeId < 0)
126 * Get the datatype and its size.
128 iFileType = H5Aget_type(iAttributeId);
129 iDim = H5Tget_size(iFileType);
130 iDim++; /* Make room for null terminator */
133 * Get dataspace and allocate memory for read buffer. This is a
134 * two dimensional attribute so the dynamic allocation must be done
137 iSpace = H5Aget_space(iAttributeId);
143 status = H5Sget_simple_extent_dims(iSpace, dims, NULL);
150 * Allocate space for string data.
152 pstValue = (char *)MALLOC((size_t) ((dims[0] * iDim + 1) * sizeof(char)));
155 * Create the memory datatype.
157 memtype = H5Tcopy(H5T_C_S1);
158 status = H5Tset_size(memtype, iDim);
168 status = H5Aread(iAttributeId, memtype, pstValue);
175 status = H5Tclose(memtype);
182 status = H5Sclose(iSpace);
189 status = H5Tclose(iFileType);
196 status = H5Aclose(iAttributeId);
207 static int checkAttribute(int _iDatasetId, char *_pstAttribute, char *_pstValue)
210 char *pstScilabClass = NULL;
212 //status = H5Giterate (_iFile, "/", NULL, op_func, &iDatasetId);
213 pstScilabClass = readAttribute(_iDatasetId, _pstAttribute);
214 if (pstScilabClass != NULL && strcmp(pstScilabClass, _pstValue) == 0)
220 FREE(pstScilabClass);
226 ** WARNING : this function returns an allocated value that must be freed.
228 char* getScilabVersionAttribute(int _iFile)
230 return readAttribute(_iFile, g_SCILAB_CLASS_SCI_VERSION);
233 int getSODFormatAttribute(int _iFile)
235 return readIntAttribute(_iFile, g_SCILAB_CLASS_SOD_VERSION);
238 int getDatasetInfo(int _iDatasetId, int* _iComplex, int* _iDims, int* _piDims)
242 H5T_class_t data_class;
243 hid_t space = H5Dget_space(_iDatasetId);
249 data_type = H5Dget_type(_iDatasetId);
250 data_class = H5Tget_class(data_type);
251 if (data_class == H5T_COMPOUND)
255 else if (data_class == H5T_REFERENCE)
257 *_iComplex = isComplexData(_iDatasetId);
264 *_iDims = H5Sget_simple_extent_ndims(space);
274 hsize_t* dims = (hsize_t*)MALLOC(sizeof(hsize_t) * *_iDims);
275 if (H5Sget_simple_extent_dims(space, dims, NULL) < 0)
282 for (i = 0 ; i < *_iDims ; i++)
284 //reverse dimensions to improve rendering in external tools
285 _piDims[i] = (int)dims[*_iDims - 1 - i];
295 int getSparseDimension(int _iDatasetId, int *_piRows, int *_piCols, int *_piNbItem)
300 //get number of item in the sparse matrix
301 getDatasetDims(_iDatasetId, _piRows, _piCols);
302 *_piNbItem = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_ITEMS);
307 static int isEmptyDataset(int _iDatasetId)
309 return checkAttribute(_iDatasetId, (char *)g_SCILAB_CLASS_EMPTY, "true");
312 int isComplexData(int _iDatasetId)
314 return checkAttribute(_iDatasetId, (char *)g_SCILAB_CLASS_COMPLEX, "true");
317 int getDatasetPrecision(int _iDatasetId, int *_piPrec)
320 char *pstScilabClass = readAttribute(_iDatasetId, g_SCILAB_CLASS_PREC);
322 if (pstScilabClass == NULL)
326 else if (strcmp(pstScilabClass, "8") == 0)
330 else if (strcmp(pstScilabClass, "u8") == 0)
332 *_piPrec = SCI_UINT8;
334 else if (strcmp(pstScilabClass, "16") == 0)
336 *_piPrec = SCI_INT16;
338 else if (strcmp(pstScilabClass, "u16") == 0)
340 *_piPrec = SCI_UINT16;
342 else if (strcmp(pstScilabClass, "32") == 0)
344 *_piPrec = SCI_INT32;
346 else if (strcmp(pstScilabClass, "u32") == 0)
348 *_piPrec = SCI_UINT32;
350 else if (strcmp(pstScilabClass, "64") == 0)
352 *_piPrec = SCI_INT64;
354 else if (strcmp(pstScilabClass, "u64") == 0)
356 *_piPrec = SCI_UINT64;
363 FREE(pstScilabClass);
367 int getVariableNames(int _iFile, char **pstNameList)
374 status = H5Gget_num_objs(_iFile, &iCount);
380 for (i = 0; i < iCount; i++)
382 if (H5Gget_objtype_by_idx(_iFile, i) == H5G_DATASET)
384 if (pstNameList != NULL)
388 iLen = (int)H5Gget_objname_by_idx(_iFile, i, NULL, iLen);
389 pstNameList[iNbItem] = (char *)MALLOC(sizeof(char) * (iLen + 1)); //null terminated
390 H5Gget_objname_by_idx(_iFile, i, pstNameList[iNbItem], iLen + 1);
398 int getDataSetIdFromName(int _iFile, char *_pstName)
400 return H5Dopen(_iFile, _pstName);
403 void closeDataSet(int _id)
411 int getDataSetId(int _iFile)
419 status = H5Giterate(_iFile, "/", NULL, op_func, &iDatasetId);
428 int getListDims(int _iDatasetId, int *_piItems)
431 * Get dataspace and dimensions of the dataset. This is a
432 * two dimensional dataset.
434 if (isEmptyDataset(_iDatasetId))
440 *_piItems = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_ITEMS);
445 int getDatasetDims(int _iDatasetId, int *_piRows, int *_piCols)
448 * Get dataspace and dimensions of the dataset. This is a
449 * two dimensional dataset.
451 if (isEmptyDataset(_iDatasetId))
458 *_piRows = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_ROWS);
459 *_piCols = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_COLS);
464 int readDoubleMatrix(int _iDatasetId, double *_pdblData)
469 status = H5Dread(_iDatasetId, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pdblData);
475 status = H5Dclose(_iDatasetId);
484 int readDoubleComplexMatrix(int _iDatasetId, double *_pdblReal, double *_pdblImg)
492 doublecomplex* pData = NULL;
495 /*define compound dataset*/
496 compoundId = H5Tcreate(H5T_COMPOUND, sizeof(doublecomplex));
497 H5Tinsert(compoundId, "real", HOFFSET(doublecomplex, r), H5T_NATIVE_DOUBLE);
498 H5Tinsert(compoundId, "imag", HOFFSET(doublecomplex, i), H5T_NATIVE_DOUBLE);
500 //get dimension from dataset
501 getDatasetInfo(_iDatasetId, &iComplex, &iDims, NULL);
502 piDims = (int*)MALLOC(sizeof(int) * iDims);
503 iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, piDims);
507 pData = (doublecomplex*)MALLOC(sizeof(doublecomplex) * iSize);
509 status = H5Dread(_iDatasetId, compoundId, H5S_ALL, H5S_ALL, H5P_DEFAULT, pData);
517 vGetPointerFromDoubleComplex(pData, iSize, _pdblReal, _pdblImg);
519 status = H5Dclose(_iDatasetId);
528 int readEmptyMatrix(int _iDatasetId)
533 status = H5Dclose(_iDatasetId);
542 int readBooleanMatrix(int _iDatasetId, int *_piData)
549 status = H5Dread(_iDatasetId, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, _piData);
555 status = H5Dclose(_iDatasetId);
564 int readStringMatrix(int _iDatasetId, char **_pstData)
569 typeId = H5Tcopy(H5T_C_S1);
570 status = H5Tset_size(typeId, H5T_VARIABLE);
577 status = H5Dread(_iDatasetId, typeId, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pstData);
583 status = H5Tclose(typeId);
589 status = H5Dclose(_iDatasetId);
598 static int readComplexPoly(int _iDatasetId, int *_piNbCoef, double **_pdblReal, double **_pdblImg)
603 //Get the datatype and its size.
605 iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, _piNbCoef);
607 //Allocate space for string data.
608 *_pdblReal = (double *)MALLOC(*_piNbCoef * sizeof(double));
609 *_pdblImg = (double *)MALLOC(*_piNbCoef * sizeof(double));
611 //Read the data and return result.
612 return readDoubleComplexMatrix(_iDatasetId, *_pdblReal, *_pdblImg);
615 static int readPoly(int _iDatasetId, int *_piNbCoef, double **_pdblData)
620 //Get the datatype and its size.
621 iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, _piNbCoef);
623 *_pdblData = (double *)MALLOC(*_piNbCoef * sizeof(double));
625 //Read the data and return result.
626 return readDoubleMatrix(_iDatasetId, *_pdblData);
629 int readCommonPolyMatrix(int _iDatasetId, char *_pstVarname, int _iComplex, int _iDims, int* _piDims, int *_piNbCoef, double **_pdblReal, double **_pdblImg)
633 char *pstVarName = 0;
634 hsize_t* piDims = NULL;
635 hobj_ref_t *pData = NULL;
639 for (i = 0 ; i < _iDims ; i++)
644 pData = (hobj_ref_t *) MALLOC(iSize * sizeof(hobj_ref_t));
649 status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, pData);
656 for (i = 0; i < iSize; i++)
659 * Open the referenced object, get its name and type.
661 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pData[i]);
664 status = readComplexPoly(obj, &_piNbCoef[i], &_pdblReal[i], &_pdblImg[i]);
668 status = readPoly(obj, &_piNbCoef[i], &_pdblReal[i]);
678 pstVarName = readAttribute(_iDatasetId, g_SCILAB_CLASS_VARNAME);
679 strcpy(_pstVarname, pstVarName);
681 status = H5Dclose(_iDatasetId);
693 int readPolyMatrix(int _iDatasetId, char *_pstVarname, int _iDims, int* _piDims, int *_piNbCoef, double **_pdblData)
695 return readCommonPolyMatrix(_iDatasetId, _pstVarname, 0, _iDims, _piDims, _piNbCoef, _pdblData, NULL);
698 int readPolyComplexMatrix(int _iDatasetId, char *_pstVarname, int _iDims, int* _piDims, int *_piNbCoef, double **_pdblReal, double **_pdblImg)
700 return readCommonPolyMatrix(_iDatasetId, _pstVarname, 1, _iDims, _piDims, _piNbCoef, _pdblReal, _pdblImg);
703 int readInteger8Matrix(int _iDatasetId, char *_pcData)
710 status = H5Dread(_iDatasetId, H5T_NATIVE_INT8, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pcData);
716 status = H5Dclose(_iDatasetId);
725 int readInteger16Matrix(int _iDatasetId, short *_psData)
732 status = H5Dread(_iDatasetId, H5T_NATIVE_INT16, H5S_ALL, H5S_ALL, H5P_DEFAULT, _psData);
738 status = H5Dclose(_iDatasetId);
747 int readInteger32Matrix(int _iDatasetId, int *_piData)
754 status = H5Dread(_iDatasetId, H5T_NATIVE_INT32, H5S_ALL, H5S_ALL, H5P_DEFAULT, _piData);
760 status = H5Dclose(_iDatasetId);
769 int readInteger64Matrix(int _iDatasetId, long long *_pllData)
776 status = H5Dread(_iDatasetId, H5T_NATIVE_INT64, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pllData);
782 status = H5Dclose(_iDatasetId);
791 int readUnsignedInteger8Matrix(int _iDatasetId, unsigned char *_pucData)
798 status = H5Dread(_iDatasetId, H5T_NATIVE_UINT8, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pucData);
804 status = H5Dclose(_iDatasetId);
813 int readUnsignedInteger16Matrix(int _iDatasetId, unsigned short *_pusData)
820 status = H5Dread(_iDatasetId, H5T_NATIVE_UINT16, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pusData);
826 status = H5Dclose(_iDatasetId);
835 int readUnsignedInteger32Matrix(int _iDatasetId, unsigned int *_puiData)
842 status = H5Dread(_iDatasetId, H5T_NATIVE_UINT32, H5S_ALL, H5S_ALL, H5P_DEFAULT, _puiData);
848 status = H5Dclose(_iDatasetId);
857 int readUnsignedInteger64Matrix(int _iDatasetId, unsigned long long *_pullData)
864 status = H5Dread(_iDatasetId, H5T_NATIVE_UINT64, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pullData);
870 status = H5Dclose(_iDatasetId);
879 int readCommonSparseComplexMatrix(int _iDatasetId, int _iComplex, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos, double *_pdblReal, double *_pdblImg)
882 hobj_ref_t pRef[3] = {0};
888 status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, pRef);
895 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[0]);
896 status = readInteger32Matrix(obj, _piNbItemRow);
903 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[1]);
904 status = readInteger32Matrix(obj, _piColPos);
911 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[2]);
915 status = readDoubleComplexMatrix(obj, _pdblReal, _pdblImg);
919 status = readDoubleMatrix(obj, _pdblReal);
927 status = H5Dclose(_iDatasetId);
936 int readSparseMatrix(int _iDatasetId, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos, double *_pdblReal)
938 return readCommonSparseComplexMatrix(_iDatasetId, 0, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, NULL);
941 int readSparseComplexMatrix(int _iDatasetId, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos, double *_pdblReal, double *_pdblImg)
943 return readCommonSparseComplexMatrix(_iDatasetId, 1, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg);
946 int readBooleanSparseMatrix(int _iDatasetId, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos)
949 hobj_ref_t pRef[2] = {0};
955 status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, pRef);
962 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[0]);
963 status = readInteger32Matrix(obj, _piNbItemRow);
972 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[1]);
973 status = readInteger32Matrix(obj, _piColPos);
980 status = H5Dclose(_iDatasetId);
988 int getScilabTypeFromDataSet(int _iDatasetId)
991 char *pstScilabClass = readAttribute(_iDatasetId, g_SCILAB_CLASS);
993 if (pstScilabClass == NULL)
997 /* HDF5 Float type + SCILAB_Class = double <=> double */
998 if (strcmp(pstScilabClass, g_SCILAB_CLASS_DOUBLE) == 0)
1000 iVarType = sci_matrix;
1002 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_STRING) == 0)
1004 iVarType = sci_strings;
1006 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_BOOLEAN) == 0)
1008 iVarType = sci_boolean;
1010 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_BOOLEAN) == 0)
1012 iVarType = sci_boolean;
1014 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_POLY) == 0)
1016 iVarType = sci_poly;
1018 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_INT) == 0)
1020 iVarType = sci_ints;
1022 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_SPARSE) == 0)
1024 iVarType = sci_sparse;
1026 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_BSPARSE) == 0)
1028 iVarType = sci_boolean_sparse;
1030 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_LIST) == 0)
1032 iVarType = sci_list;
1034 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_TLIST) == 0)
1036 iVarType = sci_tlist;
1038 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_MLIST) == 0)
1040 iVarType = sci_mlist;
1042 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_VOID) == 0)
1044 iVarType = sci_void;
1046 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_UNDEFINED) == 0)
1048 iVarType = sci_undefined;
1051 FREE(pstScilabClass);
1055 int getListItemReferences(int _iDatasetId, hobj_ref_t ** _piItemRef)
1060 getListDims(_iDatasetId, &iItem);
1062 *_piItemRef = (hobj_ref_t *) MALLOC(iItem * sizeof(hobj_ref_t));
1064 status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, *_piItemRef);
1073 int getListItemDataset(int _iDatasetId, void *_piItemRef, int _iItemPos, int *_piItemDataset)
1075 hobj_ref_t poRef = ((hobj_ref_t *) _piItemRef)[_iItemPos];
1077 *_piItemDataset = H5Rdereference(_iDatasetId, H5R_OBJECT, &poRef);
1079 if (*_piItemDataset == 0)
1087 int deleteListItemReferences(int _iDatasetId, void *_piItemRef)
1093 hobj_ref_t *poRef = (hobj_ref_t *) _piItemRef;
1098 status = H5Dclose(_iDatasetId);