cartodata 6.0.0
volumeformatreader_d.h
Go to the documentation of this file.
1/* This software and supporting documentation are distributed by
2 * Institut Federatif de Recherche 49
3 * CEA/NeuroSpin, Batiment 145,
4 * 91191 Gif-sur-Yvette cedex
5 * France
6 *
7 * This software is governed by the CeCILL-B license under
8 * French law and abiding by the rules of distribution of free software.
9 * You can use, modify and/or redistribute the software under the
10 * terms of the CeCILL-B license as circulated by CEA, CNRS
11 * and INRIA at the following URL "http://www.cecill.info".
12 *
13 * As a counterpart to the access to the source code and rights to copy,
14 * modify and redistribute granted by the license, users are provided only
15 * with a limited warranty and the software's author, the holder of the
16 * economic rights, and the successive licensors have only limited
17 * liability.
18 *
19 * In this respect, the user's attention is drawn to the risks associated
20 * with loading, using, modifying and/or developing or reproducing the
21 * software by the user in light of its specific status of free software,
22 * that may mean that it is complicated to manipulate, and that also
23 * therefore means that it is reserved for developers and experienced
24 * professionals having in-depth computer knowledge. Users are therefore
25 * encouraged to load and test the software's suitability as regards their
26 * requirements in conditions enabling the security of their systems and/or
27 * data to be ensured and, more generally, to use and operate it in the
28 * same conditions as regards security.
29 *
30 * The fact that you are presently reading this means that you have had
31 * knowledge of the CeCILL-B license and that you accept its terms.
32 */
33
34#ifndef CARTODATA_IO_VOLUMEFORMATREADER_D_H
35#define CARTODATA_IO_VOLUMEFORMATREADER_D_H
36//--- cartodata --------------------------------------------------------------
41//--- soma io ----------------------------------------------------------------
42#include <soma-io/config/soma_config.h>
46#include <soma-io/image/imagereader.h>
49//--- cartobase --------------------------------------------------------------
50#include <cartobase/object/object.h>
51#include <cartobase/smart/rcptr.h>
52#include <cartobase/exception/ioexcept.h>
53#include <cartobase/stream/fileutil.h>
54//--- system -----------------------------------------------------------------
55#include <vector>
56#include <iostream>
57#include <string>
58//--- debug ------------------------------------------------------------------
59#include <cartobase/config/verbose.h>
60#include <cartobase/type/string_conversion.h>
61#define localMsg( message ) cartoCondMsg( 4, message, "VOLUMEFORMATREADER" )
62// localMsg must be undef at end of file
63// #undef localMsg
64// #define localMsg( message ) std::cerr << (message) << std::endl;
65//----------------------------------------------------------------------------
66
67namespace soma
68{
72
73 //==========================================================================
74 // C O N S T R U C T O R S
75 //==========================================================================
76 template <typename T>
80
81 //==========================================================================
82 // U R I O P T I O N S
83 //==========================================================================
84
85 /**** setupAndRead *********************************************************
86 * Usually it is not necessary to redefine this method, but in the case of
87 * volumes the use of partial reading or borders triggers multiple volume
88 * allocations (see volume philosophy). These complex volumes are
89 * managed in VolumeUtilIO and setupAndRead/createAndRead must call them
90 * when needed.
91 **************************************************************************/
92 template <typename T> void
95 const AllocatorContext & context,
96 carto::Object options )
97 {
98 //=== Reading URI ========================================================
99 localMsg( "Reading existing object ( " + dsi->url() + " )" );
100 std::string uri = dsi->list().dataSource()->url();
101 std::string url = FileUtil::uriFilename( uri );
102 carto::Object urioptions = FileUtil::uriOptions( uri );
103 if( urioptions.get() ) {
104 if( !options.get() )
106 options->copyProperties( urioptions );
107 dsi->list().dataSource().reset( new FileDataSource( url ) );
108 }
109 //=== if no options -> classic reading ===================================
110 if( !options.get() )
111 return FormatReader<Volume<T> >::setupAndRead( obj, dsi, context,
112 options );
113 //=== else, look for known properties ====================================
114 std::set<std::string> prop = VolumeUtilIO<T>::listReadProperties();
115 typename std::set<std::string>::iterator p;
116 typename std::set<std::string>::iterator plast = prop.end();
117 for( p = prop.begin(); p != prop.end(); ++p )
118 {
119 if( options->hasProperty( *p ) )
120 {
121 localMsg( "use VolumeUtilIO::read()" );
122 VolumeUtilIO<T>::read( &obj, dsi, options );
123 bool convert = false;
124 options->getProperty( "convert_to_aims", convert );
125 if( convert )
126 {
128 translator.translate( carto::Object::reference( obj.header() ) );
129 }
130 return;
131 }
132 // for now it's juste unalloc/realloc.
133 // it must be possible to design a nice setup, but then changes are
134 // needed in VolumeUtilIO
135 }
136 //=== if no known property -> classic reading ============================
137 localMsg( "Fallback to FormatReader<Volume<T> >::setupAndRead()" );
138 return FormatReader<Volume<T> >::setupAndRead( obj, dsi, context,
139 options );
140 }
141
142 /**** createAndRead ********************************************************
143 * See setupAndRead
144 **************************************************************************/
145 template <typename T> Volume<T>*
147 const AllocatorContext & context,
148 carto::Object options )
149 {
150 localMsg( "Creating and reading object ( " + dsi->url() + " )" );
151
152 //=== Reading URI ========================================================
153 std::string uri = dsi->list().dataSource()->url();
154 std::string url = FileUtil::uriFilename( uri );
155 carto::Object urioptions = FileUtil::uriOptions( uri );
156 if( !options.get() )
158 else
159 options = options->clone();
160 if( urioptions.get() ) {
161 options->copyProperties( urioptions );
162 dsi->list().dataSource().reset( new FileDataSource( url ) );
163 }
164 //=== if no options -> classic reading ===================================
165 if( !options.get() || options->size() == 0 )
166 return FormatReader<Volume<T> >::createAndRead( dsi, context, options );
167 //=== else, look for known properties ====================================
168 std::set<std::string> prop = VolumeUtilIO<T>::listReadProperties();
169 typename std::set<std::string>::iterator p;
170 typename std::set<std::string>::iterator plast = prop.end();
171 Volume<T> *volume = 0;
172 for( p = prop.begin(); p != plast; ++p )
173 {
174 if( options->hasProperty( *p ) )
175 {
176 localMsg( "using VolumeUtilIO<T>::read ( " + dsi->url() + " )" );
177 volume = VolumeUtilIO<T>::read( 0, dsi, options );
178 break;
179 }
180 }
181 //=== if no known property -> classic reading ============================
182 if( !volume )
183 {
184 localMsg( "using classical Volume reading ( " + dsi->url() + " )" );
186 dsi, context, options );
187 }
188 if( volume )
189 {
190 bool convert = false;
191 options->getProperty( "convert_to_aims", convert );
192 if( convert )
193 {
195 translator.translate( carto::Object::reference( volume->header() ) );
196 }
197 }
198// localMsg( "-> effective volume size ( "
199// + carto::toString( volume->getSizeX() ) + ", "
200// + carto::toString( volume->getSizeY() ) + ", "
201// + carto::toString( volume->getSizeZ() ) + ", "
202// + carto::toString( volume->getSizeT() ) + " )"
203// );
204 return volume;
205 }
206
207 //==========================================================================
208 // N E W M E T H O D S
209 //==========================================================================
210
211 /**** Reading to a Volume<T> ***********************************************
212 * This method depends deeply on the data structure (Volume<T>). It is
213 * declared in FormatReader but only defined here.
214 **************************************************************************/
215 template <typename T>
218 const AllocatorContext & /* context */,
219 carto::Object options )
220 {
221 localMsg( "Reading object ( " + dsi->url() + " )" );
222
223 //=== Test data compability ==============================================
224 std::string otype = dsi->header()->getProperty( "object_type" )->getString();
225 std::string dtype = dsi->header()->getProperty( "data_type" )->getString();
226 std::string ttype = DataTypeCode<T>::dataType();
227 if( otype != "Volume" )
228 throw datatype_format_error( "unsupported data type - " + otype + " != Volume", dsi->url() );
229 if( dtype != ttype )
230 {
231 if( dsi->header()->hasProperty( "possible_data_types" ) )
232 {
233 size_t i;
234 for( i=0;
235 i<dsi->header()->getProperty( "possible_data_types" )->size();
236 ++i )
237 {
238 if( dsi->header()->getProperty( "possible_data_types" )
239 ->getArrayItem( i )->getString()
240 == ttype )
241 break;
242 }
243 if( i == dsi->header()->getProperty( "possible_data_types" )->size() )
244 throw datatype_format_error( dsi->url() );
245 } else
246 throw datatype_format_error( "unsupported data type - " + dtype + " != " + ttype, dsi->url() );
247 }
248
249 //=== test for memory mapping ============================================
250 localMsg( "checking for memory mapping..." );
253 {
254 localMsg( " -> Memory Mapping : nothing to read." );
255 return;
256 }
257
258 //=== volume is a view ? =================================================
259 localMsg( "checking if object is a view..." );
260 carto::Volume<T>* parent1( 0 );
261 carto::Volume<T>* parent2( 0 );
262 parent1 = obj.refVolume().get();
263 if( parent1 )
264 parent2 = parent1->refVolume().get();
265 else if( !obj.allocatorContext().isAllocated() ) {
266 localMsg( " -> Unallocated Volume : nothing to read." );
267 return;
268 }
269 localMsg( std::string(" -> object ") + ( parent1 ? "is" : "isn't" )
270 + " a view and "
271 + ( obj.allocatorContext().isAllocated() ? "is" : "isn't" )
272 + " allocated." );
273 if( parent1 )
274 {
275 localMsg( std::string(" -> parent exists and ")
276 + ( parent1->allocatorContext().isAllocated() ? "is" : "isn't" )
277 + " allocated." );
278 }
279 if( parent2 )
280 {
281 localMsg( std::string(" -> grandparent exists and ")
282 + ( parent2->allocatorContext().isAllocated() ? "is" : "isn't" )
283 + " allocated." );
284 }
285
286 //=== view size ==========================================================
287 localMsg( "reading view size..." );
288 std::vector<int> viewsize = obj.getSize();
289 localMsg( " -> view size ( "
290 + carto::toString( viewsize[ 0 ] ) + ", "
291 + carto::toString( viewsize[ 1 ] ) + ", "
292 + carto::toString( viewsize[ 2 ] ) + ", "
293 + carto::toString( viewsize[ 3 ] ) + " )" );
294
295 //=== multiresolution level ==============================================
296 localMsg( "reading multiresolution level..." );
297 int level = -1;
298 if( options->hasProperty( "resolution_level" ) ) {
299 options->getProperty( "resolution_level", level );
300 }
301
302 if (level < 0) {
303 try {
304 // Try to solve negative level values
305 level += dsi->header()->getProperty( "resolutions_dimension" )
306 ->size();
307 }
308 catch(...){
309 level = 0;
310 }
311 }
312 localMsg( " -> level to read : " + carto::toString( level ) );
313
314 //=== full volume size ===================================================
315 localMsg( "reading full volume size..." );
316 std::vector<int> imagesize( 4, 0 );
317 try
318 {
319 // first we look for "resolutions_dimension" property
320 carto::Object dim
321 = dsi->header()->getProperty( "resolutions_dimension" )->getArrayItem(
322 level );
323 int i, ndim = dim->size();
324 imagesize.resize( std::max( size_t( 4 ), dim->size() ), 1 );
325 for( i=0; i<ndim; ++i )
326 imagesize[ i ] = (int) rint( dim->getArrayItem( i )->getScalar() );
327 localMsg( " -> found \"resolutions_dimension\"." );
328 }
329 catch( ... )
330 {
331 try
332 {
333 // if it doesn't work, we look for "volume_dimension"
334 carto::Object dim = dsi->header()->getProperty( "volume_dimension" );
335 int i, ndim = dim->size();
336 imagesize.resize( std::max( size_t( 4 ), dim->size() ), 1 );
337 for( i=0; i<ndim; ++i )
338 imagesize[ i ] = (int) rint( dim->getArrayItem( i )->getScalar() );
339 localMsg( " -> found \"volume_dimension\"." );
340 }
341 catch( ... )
342 {
343 // if still nothing, we look for parent volumes
344 if( parent1 && !parent1->allocatorContext().isAllocated() ) {
345 imagesize = parent1->getSize();
346 localMsg( " -> found unallocated parent." );
347 } else if( parent2 ) {
348 imagesize = parent2->getSize();
349 localMsg( " -> found grandparent." );
350 } else {
351 imagesize = viewsize;
352 localMsg( " -> full volume is self." );
353 }
354 }
355 }
356 // FIXME: print all dims
357 localMsg( " -> full volume size ( "
358 + carto::toString( imagesize[ 0 ] ) + ", "
359 + carto::toString( imagesize[ 1 ] ) + ", "
360 + carto::toString( imagesize[ 2 ] ) + ", "
361 + carto::toString( imagesize[ 3 ] ) + " )" );
362
363 //=== allocated volume size ==============================================
364 localMsg( "reading allocated size..." );
365 std::vector<int> allocsize( 4, 0 );
366 if( !parent1 ) {
367 allocsize = viewsize;
368 localMsg( " -> allocated volume is self (full volume)." );
369 } else if( !parent1->allocatorContext().isAllocated() ) {
370 allocsize = viewsize;
371 localMsg( " -> allocated volume is self (partial volume)." );
372 } else {
373 allocsize = parent1->getSize();
374 localMsg( " -> allocated volume is parent "
375 "(borders or partially loading in full volume)." );
376 }
377 localMsg( " -> allocated volume size ( "
378 + carto::toString( allocsize[ 0 ] ) + ", "
379 + carto::toString( allocsize[ 1 ] ) + ", "
380 + carto::toString( allocsize[ 2 ] ) + ", "
381 + carto::toString( allocsize[ 3 ] ) + " )" );
382
383 //=== strides ============================================================
384 size_t i, ndim = allocsize.size();
385 std::vector<long> strides( ndim );
386 std::vector<int> stride_pos;
387 for( i=0; i<ndim; ++i )
388 {
389 stride_pos = std::vector<int>( ndim, 0 );
390 stride_pos[i] = 1;
391 strides[i] = &obj( stride_pos ) - &obj( 0,0,0,0 );
392 }
393
394 //=== region's origin ===================================================
395 localMsg( "reading view position in reference to full volume..." );
396 std::vector<int> pos ( ndim, 0 );
397 if( parent1 && !parent1->allocatorContext().isAllocated() ) {
398 localMsg( "parent is not allocated" );
399 pos = obj.posInRefVolume();
400 } else if( parent2 ) {
401 pos = obj.posInRefVolume();
402 for( i=0; i<parent1->posInRefVolume().size(); ++i )
403 pos[i] += parent1->posInRefVolume()[i];
404 }
405
406 // Reading position can not be negative, so restrict the read area in the
407 // full image
408 for(i=0; i<ndim; ++i)
409 if (pos[i] < 0)
410 {
411 viewsize[i] += pos[i];
412 pos[i] = 0;
413 }
414
415 localMsg( " -> view position ( "
416 + carto::toString( pos[ 0 ] ) + ", "
417 + carto::toString( pos[ 1 ] ) + ", "
418 + carto::toString( pos[ 2 ] ) + ", "
419 + carto::toString( pos[ 3 ] ) + " )" );
420
421 //=== region's size ===================================================
422 localMsg( "reading view size in reference to full volume..." );
423 // Reading size can not be over image size, so restrict the read area in the
424 // full image
425 for( i=0; i<ndim; ++i )
426 if (pos[i] + viewsize[i] > imagesize[i])
427 viewsize[i] = (pos[i] < imagesize[i] ? imagesize[i] - pos[i] : 0);
428
429 localMsg( " -> view size ( "
430 + carto::toString( viewsize[ 0 ] ) + ", "
431 + carto::toString( viewsize[ 1 ] ) + ", "
432 + carto::toString( viewsize[ 2 ] ) + ", "
433 + carto::toString( viewsize[ 3 ] ) + " )" );
434
435 //=== possibilities : with borders, partial reading ======================
436 bool withborders = false;
437 bool partialreading = false;
438 for( i=0; i<ndim; ++i )
439 {
440 if( allocsize[i] > viewsize[i] )
441 withborders = true;
442 if( imagesize[i] != viewsize[i] )
443 partialreading = true;
444 }
445 localMsg( "With Borders : "
446 + std::string( ( withborders ? "yes" : "no" ) ) );
447 localMsg( "Partial Reading : "
448 + std::string( ( partialreading ? "yes" : "no" ) ) );
449
450 // Compilation warning, I don't think this is necessary, because
451 // VolumeFormatReader does not have partialreading field
452 //partialreading = partialreading;
453
454 //=== reading volume =====================================================
455 //int y, z, t;
456 if( !withborders || dsi->capabilities().canHandleStrides() )
457 {
458 localMsg( "reading volume using strides..." );
459 // we can read the volume/region into a contiguous buffer
460 _imr->read( ( T * ) &obj(0,0,0,0), *dsi, pos,
461 viewsize, strides, options );
462 }
463 else
464 {
465 localMsg( "reading volume without strides..." );
466 // we are in a "border" context. The volume/region must be read
467 // line by line
468 std::vector<int> posline ( pos );
469 std::vector<int> sizeline ( ndim, 1 );
470 std::vector<int> volpos( ndim, 0 );
471 volpos[1] = -1;
472 sizeline[ 0 ] = viewsize[ 0 ];
473 size_t dim;
474 bool nextrow = false, ended = false;
475
476 bool was_open = _imr->isOpen( *dsi );
477
478 if( !was_open && !_imr->open( *dsi ) )
479 throw carto::open_error( "data source not available", dsi->url() );
480
481 while( !ended )
482 {
483 nextrow = true;
484 for( dim=1; dim<ndim; ++dim )
485 {
486 if( nextrow )
487 {
488 ++volpos[dim];
489 if( volpos[dim] == viewsize[dim] )
490 {
491 if( dim == ( ndim - 1 ) )
492 ended = true;
493 volpos[dim] = 0;
494 }
495 else
496 nextrow = false;
497 }
498 posline[dim] = pos[dim] + volpos[dim];
499 }
500 if( !ended )
501 {
502 posline[1] = pos[1] + volpos[1];
503 _imr->read( ( T * ) &obj( volpos ), *dsi, posline,
504 sizeline, strides, options );
505 }
506 }
507
508 if( !was_open )
509 _imr->close( *dsi );
510
511// for ( t=0; t<viewsize[ 3 ]; ++t ) {
512// volpos[ 3 ] = t;
513// posline[ 3 ] = pos[ 3 ] + t;
514// for ( z=0; z<viewsize[ 2 ]; ++z ) {
515// volpos[ 2 ] = z;
516// posline[ 2 ] = pos[ 2 ] + z;
517// for ( y=0; y<viewsize[ 1 ]; ++y ) {
518// volpos[ 1 ] = y;
519// posline[ 1 ] = pos[ 1 ] + y;
520// _imr->read( ( T * ) &obj( volpos ), *dsi, posline,
521// sizeline, strides, options );
522// }
523// }
524// }
525 }
526
527 // we reset at 0 the ImageReader's members (sizes, binary, ...) so that
528 // they are recomputed at the next reading.
529 _imr->resetParams();
530 }
531
532
533 template <typename T>
535 {
537 reader->attach( carto::rc_ptr<ImageReader<T> >( _imr->cloneReader() ) );
538 return reader;
539 }
540
541 /***************************************************************************
542 * Attaching a specific ImageReader to the FormatReader
543 **************************************************************************/
544 template <typename T>
549
550
551 template <typename T>
553 {
554 // delegate to ImageReader
555 if( !_imr )
556 return "";
557 return _imr->formatID();
558 }
559
563
564 //==========================================================================
565 // C O N S T R U C T O R S
566 //==========================================================================
567 template <typename T>
571
572 //==========================================================================
573 // U R I O P T I O N S
574 //==========================================================================
575 /*** setupAndRead **********************************************************
576 * see VolumeFormatReader
577 **************************************************************************/
578 template <typename T> void
581 const AllocatorContext & context,
582 carto::Object options )
583 {
584 //=== Reading URI ========================================================
585 std::string uri = dsi->list().dataSource()->url();
586 std::string url = FileUtil::uriFilename( uri );
587 carto::Object urioptions = FileUtil::uriOptions( uri );
588 if( urioptions.get() ) {
589 if( !options.get() )
591 options->copyProperties( urioptions );
592 dsi->list().dataSource().reset( new FileDataSource( url ) );
593 }
594 //=== if no options -> classic reading ===================================
595 if( !options.get() ) {
596 FormatReader<VolumeRef<T> >::setupAndRead( obj, dsi, context,
597 options );
598 return;
599 }
600
601 //=== else, look for known properties ====================================
602 std::set<std::string> prop = VolumeUtilIO<T>::listReadProperties();
603 typename std::set<std::string>::iterator p;
604 typename std::set<std::string>::iterator plast = prop.end();
605 for( p = prop.begin(); p != plast; ++p )
606 {
607 if( options->hasProperty( *p ) )
608 {
610 vrf.attach( _imr );
611 vrf.setupAndRead( *obj, dsi, context, options );
612 bool convert = false;
613 options->getProperty( "convert_to_aims", convert );
614 if( convert )
615 {
617 translator.translate( carto::Object::reference( obj->header() ) );
618 }
619 return; // return as soon as one read prop has been found.
620 }
621 }
622 //=== if no known property -> classic reading ============================
623 FormatReader<VolumeRef<T> >::setupAndRead( obj, dsi, context,
624 options );
625 }
626
627 /*** createAndRead *********************************************************
628 * see VolumeFormatReader
629 **************************************************************************/
630 template <typename T> VolumeRef<T>*
632 const AllocatorContext & context,
633 carto::Object options )
634 {
636 vrf.attach( _imr );
637 return new VolumeRef<T>( vrf.createAndRead( dsi, context, options ) );
638 }
639
640 //==========================================================================
641 // N E W M E T H O D S
642 //==========================================================================
643
644 /*** Reading to a Volume<T> ************************************************
645 * This method depends deeply on the data structure (Volume<T>). It is
646 * declared in FormatReader but only defined here.
647 **************************************************************************/
648 template <typename T>
651 const AllocatorContext & context,
652 carto::Object options )
653 {
655 vrf.attach( _imr );
656 vrf.read( *obj, dsi, context, options );
657 }
658
659 /***************************************************************************
660 * Attaching a specific ImageReader to the FormatReader
661 **************************************************************************/
662 template <typename T>
667
668
669 template <typename T>
672 {
674 reader->attach( carto::rc_ptr<ImageReader<T> >( _imr->cloneReader() ) );
675 return reader;
676 }
677
678
679 template <typename T>
681 {
682 // delegate to ImageReader
683 if( !_imr )
684 return "";
685 return _imr->formatID();
686 }
687
688}
689
690#undef localMsg
691#endif
virtual void translate(Object srcheader, Object dstheader=none()) const
Object reference(Object &value)
static Object value()
std::vector< int > getSize() const
get the 4 dimensions in a vector
Convenient handle for a Volume - this is normally the entry point for all volumes handling.
Definition volumeref.h:60
N-D Volume main class.
Definition volumebase.h:120
const AllocatorContext & allocatorContext() const
returns volume's AllocatorContext
const Position & posInRefVolume() const
Get position in parent volume.
rc_ptr< Volume< T > > refVolume() const
Get parent volume.
void reset(T *p=NULL)
T * get() const
MappingMode allocatorType() const
bool isAllocated() const
FormatReader specialized for 4D Volume.
void attach(carto::rc_ptr< ImageReader< T > > imr)
Linking to a ImageReader Allows us to declare only once the ImageReader.
virtual std::string formatID() const
carto::rc_ptr< ImageReader< T > > _imr
virtual Volume< T > * createAndRead(carto::rc_ptr< DataSourceInfo > dsi, const AllocatorContext &context, carto::Object options)
Factory mode: creates an object and reads it.
virtual void read(carto::Volume< T > &obj, carto::rc_ptr< DataSourceInfo > dsi, const AllocatorContext &context, carto::Object options=carto::none())
FormatReader derived function This method understands a volume and calls read( buffer ) with appropri...
virtual void setupAndRead(Volume< T > &obj, carto::rc_ptr< DataSourceInfo > dsi, const AllocatorContext &context, carto::Object options)
Full reading procedure, for an already existing object.
virtual FormatReader< carto::Volume< T > > * clone() const
FormatReader specialized for reference to 4D Volume.
carto::rc_ptr< ImageReader< T > > _imr
virtual VolumeRef< T > * createAndRead(carto::rc_ptr< DataSourceInfo > dsi, const AllocatorContext &context, carto::Object options)
Factory mode: creates an object and reads it.
virtual std::string formatID() const
virtual void read(carto::VolumeRef< T > &obj, carto::rc_ptr< DataSourceInfo > dsi, const AllocatorContext &context, carto::Object options=carto::none())
FormatReader derived function This method understands a volume and calls read( buffer ) with appropri...
virtual void setupAndRead(VolumeRef< T > &obj, carto::rc_ptr< DataSourceInfo > dsi, const AllocatorContext &context, carto::Object options)
Full reading procedure, for an already existing object.
virtual FormatReader< carto::VolumeRef< T > > * clone() const
void attach(carto::rc_ptr< ImageReader< T > > imr)
Linking to a ImageReader Allows us to declare only once the ImageReader.
static std::set< std::string > listReadProperties()
list of properties triggering partial reading and/or borders
static carto::Volume< T > * read(carto::Volume< T > *obj, carto::rc_ptr< DataSourceInfo > dsi, carto::Object options)
Manages all the volumes necessary and returns the final Volume.
std::string toString(const T &object)
#define localMsg(message)