From a01002f62b32293c44f20effbba6ff3f55d97901 Mon Sep 17 00:00:00 2001 From: Balint Cristian Date: Wed, 6 Jan 2016 08:02:59 +0200 Subject: [PATCH] Bugfix & Enhance: Fix close() issue and add H5_GETCHUNKDIMS option. --- modules/hdf/include/opencv2/hdf/hdf5.hpp | 9 +++-- modules/hdf/src/hdf5.cpp | 48 ++++++++++++++++++------ 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/modules/hdf/include/opencv2/hdf/hdf5.hpp b/modules/hdf/include/opencv2/hdf/hdf5.hpp index e6f83a7ad..65dd2d84f 100644 --- a/modules/hdf/include/opencv2/hdf/hdf5.hpp +++ b/modules/hdf/include/opencv2/hdf/hdf5.hpp @@ -63,7 +63,7 @@ public: CV_WRAP enum { - H5_UNLIMITED = -1, H5_NONE = -1, H5_GETDIMS = 100, H5_GETMAXDIMS = 101, + H5_UNLIMITED = -1, H5_NONE = -1, H5_GETDIMS = 100, H5_GETMAXDIMS = 101, H5_GETCHUNKDIMS = 102, }; virtual ~HDF5() {} @@ -278,7 +278,9 @@ public: actual dataset dimensions. Using H5_GETMAXDIM flag will get maximum allowed dimension which normally match actual dataset dimension but can hold H5_UNLIMITED value if dataset was prepared in **unlimited** mode on some of its dimension. It can be useful to check existing dataset dimensions before overwrite it as whole or subset. - Trying to write with oversized source data into dataset target will thrown exception. + Trying to write with oversized source data into dataset target will thrown exception. The H5_GETCHUNKDIMS will + return the dimension of chunk if dataset was created with chunking options otherwise returned vector size + will be zero. */ CV_WRAP virtual vector dsgetsize( String dslabel, int dims_flag = HDF5::H5_GETDIMS ) const = 0; @@ -488,7 +490,8 @@ public: Using H5_GETMAXDIM flag will get maximum allowed dimension which normally match actual dataset dimension but can hold H5_UNLIMITED value if dataset was prepared in **unlimited** mode. It can be useful to check existing dataset dimension before overwrite it as whole or subset. Trying to write with oversized source data into dataset target will thrown - exception. + exception. The H5_GETCHUNKDIMS will return the dimension of chunk if dataset was created with chunking options otherwise + returned vector size will be zero. */ CV_WRAP virtual int kpgetsize( String kplabel, int dims_flag = HDF5::H5_GETDIMS ) const = 0; diff --git a/modules/hdf/src/hdf5.cpp b/modules/hdf/src/hdf5.cpp index 20cada4dc..48c56a6cb 100644 --- a/modules/hdf/src/hdf5.cpp +++ b/modules/hdf/src/hdf5.cpp @@ -266,14 +266,16 @@ HDF5Impl::HDF5Impl( String _hdf5_filename ) // restore previous error handler H5Eset_auto( stackid, errfunc, errdata ); - if ( check == 1 ) + if ( check == 1 || check == 0 ) // open the HDF5 file m_h5_file_id = H5Fopen( m_hdf5_filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT ); - else - // create the HDF5 file + else if ( check == -1 ) + // file does not exist m_h5_file_id = H5Fcreate( m_hdf5_filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT ); + else + CV_Error( Error::StsInternal, "Unknown file state." ); } void HDF5Impl::close() @@ -282,8 +284,6 @@ void HDF5Impl::close() H5Fclose( m_h5_file_id ); // mark closed m_h5_file_id = -1; - - H5close( ); } /* @@ -328,17 +328,41 @@ vector HDF5Impl::dsgetsize( String dslabel, int dims_flag ) const // fetch rank int n_dims = H5Sget_simple_extent_ndims( fspace ); + // dims storage + hsize_t dims[n_dims]; + + // output storage + vector SizeVect(0); + // fetch dims - hsize_t dsdims[n_dims]; - if ( dims_flag == H5_GETDIMS ) - H5Sget_simple_extent_dims( fspace, dsdims, NULL ); + if ( dims_flag == H5_GETDIMS || + dims_flag == H5_GETMAXDIMS ) + { + if ( dims_flag == H5_GETDIMS ) + H5Sget_simple_extent_dims( fspace, dims, NULL ); + else + H5Sget_simple_extent_dims( fspace, NULL, dims ); + SizeVect.resize( n_dims ); + } + else if ( dims_flag == H5_GETCHUNKDIMS ) + { + // rank size + int rank_chunk = -1; + // fetch chunk size + hid_t cparms = H5Dget_create_plist( dsdata ); + if ( H5D_CHUNKED == H5Pget_layout ( cparms ) ) + { + rank_chunk = H5Pget_chunk ( cparms, n_dims, dims ); + } + if ( rank_chunk > 0 ) + SizeVect.resize( n_dims ); + } else - H5Sget_simple_extent_dims( fspace, NULL, dsdims ); + CV_Error( Error::StsInternal, "Unknown dimension flag." ); // fill with size data - vector SizeVect( n_dims ); - for ( int d = 0; d < n_dims; d++ ) - SizeVect[d] = (int) dsdims[d]; + for ( size_t d = 0; d < SizeVect.size(); d++ ) + SizeVect[d] = (int) dims[d]; H5Dclose( dsdata ); H5Sclose( fspace );