DGtal 1.4.0
Loading...
Searching...
No Matches
ImageFactoryFromHDF5.h
1
17#pragma once
18
31#if defined(ImageFactoryFromHDF5_RECURSES)
32#error Recursive header files inclusion detected in ImageFactoryFromHDF5.h
33#else // defined(ImageFactoryFromHDF5_RECURSES)
35#define ImageFactoryFromHDF5_RECURSES
36
37#if !defined ImageFactoryFromHDF5_h
39#define ImageFactoryFromHDF5_h
40
42// Inclusions
43#include <iostream>
44#include "DGtal/base/Common.h"
45#include "DGtal/base/ConceptUtils.h"
46#include "DGtal/images/CImage.h"
47#include "DGtal/base/Alias.h"
48#include "DGtal/kernel/CBoundedNumber.h"
49
50#include "hdf5.h"
52
53namespace DGtal
54{
55
57 // template class H5DSpecializations
65 template <typename TImageFactory, typename T>
67 {
68 // ----------------------- Standard services ------------------------------
69
70 typedef TImageFactory ImageFactory;
71 typedef typename ImageFactory::OutputImage::Value Value;
72
73 static int H5DreadS(ImageFactory &anImageFactory, hid_t memspace, Value *data_out);
74 static int H5DwriteS(ImageFactory &anImageFactory, hid_t memspace, Value *data_in);
75
76 }; // end of class H5DSpecializations
77
79 // template class H5DSpecializations
84 template <typename TImageFactory>
85 struct H5DSpecializations<TImageFactory, DGtal::uint8_t>
86 {
87 // ----------------------- Standard services ------------------------------
88
89 typedef TImageFactory ImageFactory;
90 typedef typename ImageFactory::OutputImage::Value Value;
91
92 static int H5DreadS(ImageFactory &anImageFactory, hid_t memspace, Value *data_out)
93 {
94 return H5Dread(anImageFactory.dataset, H5T_NATIVE_UINT8, memspace, anImageFactory.dataspace, H5P_DEFAULT, data_out);
95 }
96
97 static int H5DwriteS(ImageFactory &anImageFactory, hid_t memspace, Value *data_in)
98 {
99 return H5Dwrite(anImageFactory.dataset, H5T_NATIVE_UINT8, memspace, anImageFactory.dataspace, H5P_DEFAULT, data_in);
100 }
101
102 }; // end of class H5DSpecializations
103
105 // template class H5DSpecializations
110 template <typename TImageFactory>
111 struct H5DSpecializations<TImageFactory, DGtal::int32_t>
112 {
113 // ----------------------- Standard services ------------------------------
114
115 typedef TImageFactory ImageFactory;
116 typedef typename ImageFactory::OutputImage::Value Value;
117
118 static int H5DreadS(ImageFactory &anImageFactory, hid_t memspace, Value *data_out)
119 {
120 return H5Dread(anImageFactory.dataset, H5T_NATIVE_INT32, memspace, anImageFactory.dataspace, H5P_DEFAULT, data_out);
121 }
122
123 static int H5DwriteS(ImageFactory &anImageFactory, hid_t memspace, Value *data_in)
124 {
125 return H5Dwrite(anImageFactory.dataset, H5T_NATIVE_INT32, memspace, anImageFactory.dataspace, H5P_DEFAULT, data_in);
126 }
127
128 }; // end of class H5DSpecializations
129
131 // template class H5DSpecializations
136 template <typename TImageFactory>
137 struct H5DSpecializations<TImageFactory, DGtal::int64_t>
138 {
139 // ----------------------- Standard services ------------------------------
140
141 typedef TImageFactory ImageFactory;
142 typedef typename ImageFactory::OutputImage::Value Value;
143
144 static int H5DreadS(ImageFactory &anImageFactory, hid_t memspace, Value *data_out)
145 {
146 return H5Dread(anImageFactory.dataset, H5T_NATIVE_INT64, memspace, anImageFactory.dataspace, H5P_DEFAULT, data_out);
147 }
148
149 static int H5DwriteS(ImageFactory &anImageFactory, hid_t memspace, Value *data_in)
150 {
151 return H5Dwrite(anImageFactory.dataset, H5T_NATIVE_INT64, memspace, anImageFactory.dataspace, H5P_DEFAULT, data_in);
152 }
153
154 }; // end of class H5DSpecializations
155
157 // template class H5DSpecializations
162 template <typename TImageFactory>
163 struct H5DSpecializations<TImageFactory, double>
164 {
165 // ----------------------- Standard services ------------------------------
166
167 typedef TImageFactory ImageFactory;
168 typedef typename ImageFactory::OutputImage::Value Value;
169
170 static int H5DreadS(ImageFactory &anImageFactory, hid_t memspace, Value *data_out)
171 {
172 return H5Dread(anImageFactory.dataset, H5T_NATIVE_DOUBLE, memspace, anImageFactory.dataspace, H5P_DEFAULT, data_out);
173 }
174
175 static int H5DwriteS(ImageFactory &anImageFactory, hid_t memspace, Value *data_in)
176 {
177 return H5Dwrite(anImageFactory.dataset, H5T_NATIVE_DOUBLE, memspace, anImageFactory.dataspace, H5P_DEFAULT, data_in);
178 }
179
180 }; // end of class H5DSpecializations
181
183 // Template class ImageFactoryFromHDF5
195 template <typename TImageContainer>
197 {
198
199 // ----------------------- Types ------------------------------
200
201 public:
203
206
210
213 typedef typename OutputImage::Value Value;
214
216
217 // ----------------------- Standard services ------------------------------
218
219 public:
220
226 ImageFactoryFromHDF5(const std::string & aFilename, const std::string & aDataset):
227 myFilename(aFilename), myDataset(aDataset)
228 {
229 const int ddim = Domain::dimension;
230
231 hsize_t dims_out[ddim]; // dataset dimensions
232
233 // Open the file and the dataset.
234 file = H5Fopen(myFilename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
235 dataset = H5Dopen2(file, myDataset.c_str(), H5P_DEFAULT);
236
237 // Get datatype and dataspace handles and then query dataset class, order, size, rank and dimensions.
238 datatype = H5Dget_type(dataset); // datatype handle
239
240 dataspace = H5Dget_space(dataset); // dataspace handle
241
242 H5Sget_simple_extent_dims(dataspace, dims_out, NULL);
243
244 // --
245
246 typedef SpaceND<ddim> TSpace;
247 typename TSpace::Point low, up;
248
249 typename Domain::Integer d;
250 for(d=0; d<ddim; d++)
251 {
252 low[d]=0;
253 up[d]=dims_out[ddim-d-1]-1;
254 }
255
256 myDomain = new Domain(low, up);
257 }
258
263 {
264 delete myDomain;
265
266 // --
267
268 // Close/release resources.
269 H5Tclose(datatype);
270 H5Dclose(dataset);
271 H5Sclose(dataspace);
272 H5Fclose(file);
273 }
274
275 private:
276
278
280
281 // ----------------------- Interface --------------------------------------
282 public:
283
285
291 const Domain & domain() const
292 {
293 return *myDomain;
294 }
295
297
298
300
305 void selfDisplay ( std::ostream & out ) const;
306
311 bool isValid() const
312 {
313 return (myDomain->isValid());
314 }
315
323 OutputImage * requestImage(const Domain &aDomain) // time consuming
324 {
325 DGtal::IOException dgtalio;
326
327 const int ddim = Domain::dimension;
328
329 // --
330
331 hsize_t offset[ddim]; // hyperslab offset in the file
332 hsize_t count[ddim]; // size of the hyperslab in the file
333
334 herr_t status;
335 hsize_t dimsm[ddim]; // memory space dimensions
336 hid_t memspace;
337
338 hsize_t offset_out[ddim]; // hyperslab offset in memory
339 hsize_t count_out[ddim]; // size of the hyperslab in memory
340
341 int N_SUB[ddim];
342 typename Domain::Integer d;
343
344 int malloc_size=1;
345 for(d=0; d<ddim; d++)
346 {
347 N_SUB[d] = (aDomain.upperBound()[ddim-d-1]-aDomain.lowerBound()[ddim-d-1])+1;
348 malloc_size = malloc_size*N_SUB[d];
349 }
350
351 Value *data_out = (Value*) malloc (malloc_size * sizeof(Value)); // output buffer
352 if (data_out == NULL)
353 {
354 trace.error() << "data_out malloc error in requestImage: " << (malloc_size * sizeof(Value)) << std::endl;
355 throw dgtalio;
356 }
357
358 // Define hyperslab in the dataset.
359 for(d=0; d<ddim; d++)
360 offset[d] = aDomain.lowerBound()[ddim-d-1]-myDomain->lowerBound()[ddim-d-1];
361 for(d=0; d<ddim; d++)
362 count[d] = N_SUB[d];
363 status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, NULL, count, NULL);
364 if (status)
365 {
366 trace.error() << " H5Sselect_hyperslab from dataspace error" << std::endl;
367 throw dgtalio;
368 }
369
370 // Define the memory dataspace.
371 for(d=0; d<ddim; d++)
372 dimsm[d] = N_SUB[d];
373 memspace = H5Screate_simple(ddim,dimsm,NULL);
374
375 // Define memory hyperslab.
376 for(d=0; d<ddim; d++)
377 offset_out[d] = 0;
378 for(d=0; d<ddim; d++)
379 count_out[d] = N_SUB[d];
380 status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, offset_out, NULL, count_out, NULL);
381 if (status)
382 {
383 trace.error() << " H5Sselect_hyperslab from memspace error" << std::endl;
384 throw dgtalio;
385 }
386
387 // Read data from hyperslab in the file into the hyperslab in memory.
388 //status = H5Dread(dataset, H5T_NATIVE_INT, memspace, dataspace, H5P_DEFAULT, data_out);
389 status = H5DSpecializations<Self, Value>::H5DreadS(*this, memspace, data_out);
390 if (status)
391 {
392 trace.error() << " H5DSpecializations/H5DreadS error" << std::endl;
393 throw dgtalio;
394 }
395
396 OutputImage* outputImage = new OutputImage(aDomain);
397 if (outputImage == NULL)
398 {
399 trace.error() << "outputImage new error in requestImage: " << std::endl;
400 throw dgtalio;
401 }
402
403 typedef SpaceND<ddim> TSpace;
404 typename TSpace::Point a, b;
405 for(d=0; d<ddim; d++)
406 {
407 a[d]=offset[ddim-d-1]+myDomain->lowerBound()[d];
408 b[d]=a[d]+N_SUB[ddim-d-1]-1;
409 }
410 HyperRectDomain<TSpace> hrdomain(a,b);
411
412 int p=0;
414 it = hrdomain.begin(), itend = hrdomain.end();
415 it != itend;
416 ++it)
417 {
418 outputImage->setValue((*it), data_out[ p++ ]);
419 }
420
421 H5Sclose(memspace);
422
423 // --
424
425 free(data_out);
426
427 return outputImage;
428 }
429
435 void flushImage(OutputImage* outputImage)
436 {
437 DGtal::IOException dgtalio;
438
439 const int ddim = Domain::dimension;
440
441 // --
442
443 hsize_t offset[ddim]; // hyperslab offset in the file
444 hsize_t count[ddim]; // size of the hyperslab in the file
445
446 herr_t status;
447 hsize_t dimsm[ddim]; // memory space dimensions
448 hid_t memspace;
449
450 hsize_t offset_in[ddim]; // hyperslab offset in memory
451 hsize_t count_in[ddim]; // size of the hyperslab in memory
452
453 //int i[ddim];
454 int N_SUB[ddim];
455 typename Domain::Integer d;
456
457 int malloc_size=1;
458 for(d=0; d<ddim; d++)
459 {
460 N_SUB[d] = (outputImage->domain().upperBound()[ddim-d-1]-outputImage->domain().lowerBound()[ddim-d-1])+1;
461 malloc_size = malloc_size*N_SUB[d];
462 }
463
464 Value *data_in = (Value*) malloc (malloc_size * sizeof(Value)); // input buffer
465 if (data_in == NULL)
466 {
467 trace.error() << "data_in malloc error in flushImage: " << (malloc_size * sizeof(Value)) << std::endl;
468 throw dgtalio;
469 }
470
471 // Define hyperslab in the dataset.
472 for(d=0; d<ddim; d++)
473 offset[d] = outputImage->domain().lowerBound()[ddim-d-1]-myDomain->lowerBound()[ddim-d-1];
474 for(d=0; d<ddim; d++)
475 count[d] = N_SUB[d];
476 status = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, offset, NULL, count, NULL);
477 if (status)
478 {
479 trace.error() << " H5Sselect_hyperslab from dataspace error" << std::endl;
480 throw dgtalio;
481 }
482
483 // Define the memory dataspace.
484 for(d=0; d<ddim; d++)
485 dimsm[d] = N_SUB[d];
486 memspace = H5Screate_simple(ddim,dimsm,NULL);
487
488 // Define memory hyperslab.
489 for(d=0; d<ddim; d++)
490 offset_in[d] = 0;
491 for(d=0; d<ddim; d++)
492 count_in[d] = N_SUB[d];
493 status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, offset_in, NULL, count_in, NULL);
494 if (status)
495 {
496 trace.error() << " H5Sselect_hyperslab from memspace error" << std::endl;
497 throw dgtalio;
498 }
499
500 typedef SpaceND<ddim> TSpace;
501 typename TSpace::Point a, b;
502 for(d=0; d<ddim; d++)
503 {
504 a[d]=offset[ddim-d-1]+myDomain->lowerBound()[d];
505 b[d]=a[d]+N_SUB[ddim-d-1]-1;
506 }
507 HyperRectDomain<TSpace> hrdomain(a,b);
508
509 std::vector<typename TSpace::Dimension> v(ddim);
510 for(d=0; d<ddim; d++)
511 v[d]=d;
512
513 int p=0;
515 it = hrdomain.subRange(v, a).begin(), itend = hrdomain.subRange(v, a).end();
516 it != itend;
517 ++it)
518 {
519 data_in[ p++ ] = outputImage->operator()((*it));
520 }
521
522 // Write data from hyperslab in memory into the hyperslab in the file.
523 //status = H5Dwrite(dataset, H5T_NATIVE_INT, memspace, dataspace, H5P_DEFAULT, data_in);
524 status = H5DSpecializations<Self, Value>::H5DwriteS(*this, memspace, data_in);
525 if (status)
526 {
527 trace.error() << " H5DSpecializations/H5DwriteS error" << std::endl;
528 throw dgtalio;
529 }
530
531 H5Sclose(memspace);
532
533 // --
534
535 free(data_in);
536 }
537
543 void detachImage(OutputImage* outputImage)
544 {
545 delete outputImage;
546 }
547
548 // ------------------------- Protected Datas ------------------------------
549 private:
553 //ImageFactoryFromHDF5() {}
554
555 // ------------------------- Private Datas --------------------------------
556 protected:
557
560
562 const std::string myFilename;
563 const std::string myDataset;
564
565 public:
566
567 // HDF5 handles
568 hid_t file, dataset;
570
571 // ------------------------- Internals ------------------------------------
572 private:
573
574 }; // end of class ImageFactoryFromHDF5
575
576
583 template <typename TImageContainer>
584 std::ostream&
585 operator<< ( std::ostream & out, const ImageFactoryFromHDF5<TImageContainer> & object );
586
587} // namespace DGtal
588
589
591// Includes inline functions.
592#include "DGtal/images/ImageFactoryFromHDF5.ih"
593
594// //
596
597#endif // !defined ImageFactoryFromHDF5_h
598
599#undef ImageFactoryFromHDF5_RECURSES
600#endif // else defined(ImageFactoryFromHDF5_RECURSES)
Aim: Parallelepidec region of a digital space, model of a 'CDomain'.
const ConstIterator & begin() const
ConstSubRange subRange(const std::vector< Dimension > &permutation) const
const ConstIterator & end() const
void setValue(const Point &aPoint, const Value &aValue)
const Domain & domain() const
Aim: implements a factory from an HDF5 file.
TImageContainer ImageContainer
Types copied from the container.
ImageFactoryFromHDF5 & operator=(const ImageFactoryFromHDF5 &other)
ImageFactoryFromHDF5(const ImageFactoryFromHDF5 &other)
OutputImage * requestImage(const Domain &aDomain)
Domain * myDomain
Alias on the image domain.
void flushImage(OutputImage *outputImage)
BOOST_CONCEPT_ASSERT((concepts::CBoundedNumber< Value >))
BOOST_CONCEPT_ASSERT((concepts::CImage< TImageContainer >))
Checking concepts.
const std::string myFilename
HDF5 filename and datasetname.
void detachImage(OutputImage *outputImage)
ImageContainer OutputImage
New types.
ImageFactoryFromHDF5< TImageContainer > Self
void selfDisplay(std::ostream &out) const
ImageFactoryFromHDF5(const std::string &aFilename, const std::string &aDataset)
std::ostream & error()
DGtal is the top-level namespace which contains all DGtal functions and types.
boost::int64_t int64_t
signed 94-bit integer.
Definition BasicTypes.h:74
boost::uint8_t uint8_t
unsigned 8-bit integer.
Definition BasicTypes.h:59
std::ostream & operator<<(std::ostream &out, const ClosedIntegerHalfPlane< TSpace > &object)
Trace trace
Definition Common.h:153
boost::int32_t int32_t
signed 32-bit integer.
Definition BasicTypes.h:72
static int H5DwriteS(ImageFactory &anImageFactory, hid_t memspace, Value *data_in)
static int H5DreadS(ImageFactory &anImageFactory, hid_t memspace, Value *data_out)
static int H5DreadS(ImageFactory &anImageFactory, hid_t memspace, Value *data_out)
static int H5DwriteS(ImageFactory &anImageFactory, hid_t memspace, Value *data_in)
static int H5DreadS(ImageFactory &anImageFactory, hid_t memspace, Value *data_out)
static int H5DwriteS(ImageFactory &anImageFactory, hid_t memspace, Value *data_in)
static int H5DreadS(ImageFactory &anImageFactory, hid_t memspace, Value *data_out)
static int H5DwriteS(ImageFactory &anImageFactory, hid_t memspace, Value *data_in)
Aim: implements HDF5 reading and writing for specialized type T.
ImageFactory::OutputImage::Value Value
static int H5DwriteS(ImageFactory &anImageFactory, hid_t memspace, Value *data_in)
static int H5DreadS(ImageFactory &anImageFactory, hid_t memspace, Value *data_out)
Aim: The concept CBoundedNumber specifies what are the bounded numbers. Models of this concept should...
Aim: Defines the concept describing a read/write image, having an output iterator.
Definition CImage.h:103
ImageContainerBySTLVector< HyperRectDomain< Z2i::Space >, std::unordered_set< Z2i::Point > > TImageContainer