DGtal 1.4.0
Loading...
Searching...
No Matches
HDF5Writer.ih
1/**
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 **/
16
17/**
18 * @file HDF5Writer.ih
19 * @author Martial Tola (\c martial.tola@liris.cnrs.fr )
20 * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
21 *
22 * @date 2013/09/11
23 *
24 * Implementation of inline methods defined in HDF5Writer.h
25 *
26 * This file is part of the DGtal library.
27 */
28
29
30//////////////////////////////////////////////////////////////////////////////
31#include <cstdlib>
32#include <fstream>
33#include "DGtal/io/Color.h"
34
35#include <hdf5.h>
36//////////////////////////////////////////////////////////////////////////////
37
38///////////////////////////////////////////////////////////////////////////////
39// IMPLEMENTATION of inline methods.
40///////////////////////////////////////////////////////////////////////////////
41
42#define RANK_3D 3
43#define SIZE_CHUNK 10 // for compressed dataset
44
45namespace DGtal {
46 template<typename I,typename F>
47 bool
48 HDF5Writer<I,F>::exportHDF5_3D(const std::string & filename, const I & aImage, const std::string & aDataset,
49 const Functor & aFunctor)
50 {
51 DGtal::IOException dgtalio;
52
53 typename I::Domain::Vector size;
54 const typename I::Domain::Point &upBound = aImage.domain().upperBound();
55 const typename I::Domain::Point &lowBound = aImage.domain().lowerBound();
56 size[0]=upBound[0]-lowBound[0]+1;
57 size[1]=upBound[1]-lowBound[1]+1;
58 size[2]=upBound[2]-lowBound[2]+1;
59
60 typename I::Domain domain = aImage.domain();
61 typename I::Value val;
62
63 hid_t file, dataset; // file and dataset handles
64 hid_t datatype, dataspace; // handles
65 hsize_t dimsf[RANK_3D]; // dataset dimensions
66 herr_t status;
67 DGtal::uint8_t *data;
68 int i;
69
70 // compressed dataset
71 hid_t plist_id;
72 hsize_t cdims[RANK_3D];
73 // compressed dataset
74
75 try
76 {
77 data = (DGtal::uint8_t*)malloc(size[2]*size[1]*size[0] * sizeof(DGtal::uint8_t));
78 if (data == NULL)
79 {
80 trace.error() << " malloc error" << std::endl;
81 return false;
82 }
83
84 // We scan the domain instead of the image because we cannot
85 // trust the image container Iterator
86 i=0;
87 for(typename I::Domain::ConstIterator it = domain.begin(), itend=domain.end();
88 it!=itend;
89 ++it)
90 {
91 val = aImage( (*it) );
92 data[i++] = aFunctor(val);
93 }
94
95 /*
96 * Create a new file using H5F_ACC_TRUNC access,
97 * default file creation properties, and default file
98 * access properties.
99 */
100 file = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
101
102 // Describe the size of the array and create the data space for fixed size dataset.
103 dimsf[0] = size[2];
104 dimsf[1] = size[1];
105 dimsf[2] = size[0];
106 dataspace = H5Screate_simple(RANK_3D, dimsf, NULL);
107
108 // compressed dataset
109 plist_id = H5Pcreate(H5P_DATASET_CREATE);
110
111 // Dataset must be chunked for compression.
112 cdims[0] = SIZE_CHUNK;
113 cdims[1] = SIZE_CHUNK;
114 cdims[2] = SIZE_CHUNK;
115 status = H5Pset_chunk(plist_id, RANK_3D, cdims);
116
117 // --> Compression levels :
118 // 0 No compression
119 // 1 Best compression speed; least compression
120 // 2 through 8 Compression improves; speed degrades
121 // 9 Best compression ratio; slowest speed
122 //
123 // Set ZLIB / DEFLATE Compression using compression level 6.
124 status = H5Pset_deflate(plist_id, 6);
125 // compressed dataset
126
127 /*
128 * Define datatype for the data in the file.
129 */
130 datatype = H5Tcopy(H5T_NATIVE_UINT8);
131 status = H5Tset_order(datatype, H5T_ORDER_LE);
132
133 /*
134 * Create a new dataset within the file using defined dataspace and
135 * datatype and default dataset creation properties.
136 */
137 dataset = H5Dcreate2(file, aDataset.c_str(), datatype, dataspace,
138 H5P_DEFAULT, /*H5P_DEFAULT*/plist_id, H5P_DEFAULT); // here to activate compressed dataset
139
140 // Write the data to the dataset using default transfer properties.
141 status = H5Dwrite(dataset, H5T_NATIVE_UINT8, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
142 if (status)
143 {
144 trace.error() << " H5Dwrite error" << std::endl;
145 free(data);
146 return false;
147 }
148
149 // Close/release resources.
150 H5Sclose(dataspace);
151 H5Tclose(datatype);
152 H5Dclose(dataset);
153 // compressed dataset
154 H5Pclose(plist_id);
155 // compressed dataset
156 H5Fclose(file);
157
158 free(data);
159 }
160 catch( ... )
161 {
162 trace.error() << "HDF5 writer IO error on export " << filename << std::endl;
163 throw dgtalio;
164 }
165 return true;
166 }
167
168}//namespace