38  template <
typename ValueType>
 
   40      public ImageBase<Image<ValueType>, ValueType>
 
   75          for (
size_t n = 0; n < 
ndim(); ++n)
 
   99          stream << 
"\"" << V.
name() << 
"\", datatype " << DataType::from<Image::value_type>().specifier() << 
", index [ ";
 
  100          for (
size_t n = 0; n < V.
ndim(); ++n) stream << V.index(n) << 
" ";
 
  101          stream << 
"], current offset = " << V.
offset() << 
", ";
 
  102          if (is_out_of_bounds(V))
 
  103            stream << 
"outside FoV";
 
  105            stream << 
"value = " << V.value();
 
  107          else stream << 
" (using direct IO, data at " << V.
data_pointer << 
")";
 
  186          assert (
data_pointer != 
nullptr && 
"Image::address() can only be used when image access is via direct RAM access");
 
  189        static Image open (
const std::string& image_name, 
bool read_write_if_existing = 
false) {
 
  190          return Header::open (image_name).get_image<ValueType> (read_write_if_existing);
 
  192        static Image create (
const std::string& image_name, 
const Header& template_header, 
bool add_to_command_history = 
true) {
 
  193          return Header::create (image_name, template_header, add_to_command_history).get_image<ValueType>();
 
  196          return Header::scratch (template_header, label).get_image<ValueType>();
 
  219  template <
typename ValueType>
 
  229          Header (b), fetch_func (b.fetch_func), store_func (b.store_func) { }
 
  233          ssize_t nseg = 
offset / io->segment_size();
 
  234          return fetch_func (io->segment (nseg), 
offset - nseg*io->segment_size(), intensity_offset(), intensity_scale());
 
  238          ssize_t nseg = 
offset / io->segment_size();
 
  239          store_func (val, io->segment (nseg), 
offset - nseg*io->segment_size(), intensity_offset(), intensity_scale());
 
  275    template <
typename ValueType>
 
  277        public ImageBase<TmpImage<ValueType>, ValueType>
 
  283        b (b), data (data), x (x), strides (strides), 
offset (
offset) { }
 
  285        const typename Image<ValueType>::Buffer& b;
 
  291        bool valid ()
 const { 
return true; }
 
  292        const std::string 
name ()
 const { 
return "direct IO buffer"; }
 
  301        FORCE_INLINE void set_value (ValueType val) { Raw::store_native<ValueType> (val, data, 
offset); }
 
  315  template <
typename ValueType>
 
  318        assert (
H.valid() && 
"IO handler must be set when creating an Image");
 
  322        io->set_readwrite_if_existing (read_write_if_existing);
 
  323        io->open (*
this, footprint<ValueType> (voxel_count (*
this)));
 
  324        if (
io->is_file_backed())
 
  333  template <
typename ValueType>
 
  337        return data_buffer.get();
 
  339      assert (io && 
"data pointer will only be set for valid Images");
 
  340      if (!io->is_file_backed()) 
 
  341        return io->segment(0);
 
  345      if (io->nsegments() == 1 && datatype() == DataType::from<ValueType>() && intensity_offset() == 0.0 && intensity_scale() == 1.0)
 
  346        return io->segment(0);
 
  354  template <
typename ValueType>
 
  355    Image<ValueType> Header::get_image (
bool read_write_if_existing)
 
  358        throw Exception (
"FIXME: don't invoke get_image() with invalid Header!");
 
  359      std::shared_ptr<typename Image<ValueType>::Buffer> 
buffer (
new typename Image<ValueType>::Buffer (*
this, read_write_if_existing));
 
  368  template <
typename ValueType>
 
  373  template <
typename ValueType>
 
  384            + 
", using " + ( 
is_direct_io() ? 
"" : 
"in" ) + 
"direct IO");
 
  391  template <
typename ValueType>
 
  397          if (
buffer->get_io()->is_image_readwrite() && 
buffer->data_buffer) {
 
  398            auto data_buffer = std::move (
buffer->data_buffer);
 
  400            Image<ValueType> dest (
buffer);
 
  409  template <
typename ValueType>
 
  413        throw Exception (
"FIXME: don't invoke 'with_direct_io()' on images already using direct IO!");
 
  415        throw Exception (
"FIXME: don't invoke 'with_direct_io()' on non-validated images!");
 
  417        throw Exception (
"FIXME: don't invoke 'with_direct_io()' on images if other copies exist!");
 
  419      bool preload = ( 
buffer->datatype() != DataType::from<ValueType>() ) || ( 
buffer->get_io()->files.size() > 1 );
 
  420      if (with_strides.size()) {
 
  423        with_strides = new_strides;
 
  429        return std::move (*
this);
 
  434      const auto buffer_size = footprint<ValueType> (voxel_count (*
this));
 
  435      buffer->data_buffer = std::unique_ptr<uint8_t[]> (
new uint8_t [buffer_size]);
 
  437      if (
buffer->get_io()->is_image_new()) {
 
  439        memset (
buffer->data_buffer.get(), 0, buffer_size);
 
  443        TmpImage<ValueType> dest = { *
buffer, 
buffer->data_buffer.get(), vector<ssize_t> (
ndim(), 0), with_strides, 
Stride::offset (with_strides, *
this) };
 
  454  template <
typename ValueType>
 
  458        throw Exception (
"FIXME: image not suitable for use with 'Image::dump_to_mrtrix_file()'");
 
  464      DEBUG (
"dumping image \"" + 
name() + 
"\" to file \"" + filename + 
"\"...");
 
  466      File::OFStream out (filename, std::ios::out | std::ios::binary);
 
  467      out << 
"mrtrix image\n";
 
  471      std::string data_filename = filename;
 
  476        offset = int64_t(out.tellp()) + int64_t(18);
 
  478        out << 
". " << 
offset << 
"\nEND\n";
 
  481        data_filename = filename.substr (0, filename.size()-4) + 
".dat";
 
  484        out.open (data_filename, std::ios::out | std::ios::binary);
 
  487      const int64_t data_size = footprint (*
buffer);
 
  488      out.seekp (
offset, out.beg);
 
  491        throw Exception (
"error writing back contents of file \"" + data_filename + 
"\": " + strerror(errno));
 
  508  template <
class ImageType>
 
  509    std::string __save_generic (ImageType& 
x, 
const std::string& filename, 
bool use_multi_threading) {
 
  511      if (use_multi_threading)
 
  521  template <
class ImageType>
 
  522    typename std::enable_if<is_adapter_type<typename std::remove_reference<ImageType>::type>
::value, std::string>::type
 
  523    save (ImageType&& 
x, 
const std::string& filename, 
bool use_multi_threading = 
true)
 
  525      return __save_generic (
x, filename, use_multi_threading);
 
  529  template <
class ImageType>
 
  530    typename std::enable_if<is_pure_image<typename std::remove_reference<ImageType>::type>
::value, std::string>::type
 
  531    save (ImageType&& 
x, 
const std::string& filename, 
bool use_multi_threading = 
true)
 
  533      try { 
return x.dump_to_mrtrix_file (filename, use_multi_threading); }
 
  535      return __save_generic (
x, filename, use_multi_threading);
 
  540  template <
class ImageType>
 
  541    typename enable_if_image_type<ImageType,void>::type 
display (ImageType& 
x) {
 
  542      std::string filename = 
save (
x, 
"-");
 
  543      CONSOLE (
"displaying image \"" + filename + 
"\"");
 
  544      if (system ((
"bash -c \"mrview " + filename + 
"\"").c_str()))
 
  545        WARN (std::string(
"error invoking viewer: ") + strerror(errno));
 
void * get_data_pointer()
std::function< ValueType(const void *, size_t, default_type, default_type)> fetch_func
ValueType get_value(size_t offset) const
void set_fetch_store_functions()
Buffer(Header &H, bool read_write_if_existing=false)
construct a Buffer object to access the data in the image specified
ImageIO::Base * get_io() const
void set_value(size_t offset, ValueType val) const
Buffer(Buffer &&)=default
std::unique_ptr< uint8_t[]> data_buffer
std::function< void(ValueType, void *, size_t, default_type, default_type)> store_func
functions and classes related to image data input/output
Image with_direct_io(Stride::List with_strides=Stride::List())
return a new Image using direct IO
Image with_direct_io(int axis)
return a new Image using direct IO
bool is_direct_io() const
static Image scratch(const Header &template_header, const std::string &label="scratch image")
static Image create(const std::string &image_name, const Header &template_header, bool add_to_command_history=true)
size_t offset() const
offset to current voxel from start of data
ValueType get_value() const
get voxel value at current location
void set_value(ValueType val)
set voxel value at current location
const std::string & name() const
ssize_t get_index(size_t axis) const
get position of current voxel location along axis
std::shared_ptr< Buffer > buffer
shared reference to header/buffer
const KeyValues & keyval() const
get generic key/value text attributes
const transform_type & transform() const
ValueType * address() const
return RAM address of current voxel
friend std::ostream & operator<<(std::ostream &stream, const Image &V)
use for debugging
std::string dump_to_mrtrix_file(std::string filename, bool use_multi_threading=true) const
write out the contents of a direct IO image to file
size_t data_offset
offset to currently pointed-to voxel
Image(const std::shared_ptr< Buffer > &, const Stride::List &=Stride::List())
used internally to instantiate Image objects
default_type spacing(size_t axis) const
Stride::List strides
voxel indices
void move_index(size_t axis, ssize_t increment)
move position of current voxel location along axis
static Image open(const std::string &image_name, bool read_write_if_existing=false)
void reset()
reset index to zero (origin)
Image(const Image &)=default
ssize_t stride(size_t axis) const
Image & operator=(const Image &image)=default
void * data_pointer
pointer to data address whether in RAM or MMap
vector< ssize_t > x
voxel indices
ssize_t size(size_t axis) const
VectorType::Scalar value(const VectorType &coefs, typename VectorType::Scalar cos_elevation, typename VectorType::Scalar cos_azimuth, typename VectorType::Scalar sin_azimuth, int lmax)
std::unique_ptr< ImageIO::Base > create(Header &H)
void resize(const std::string &filename, int64_t size)
std::string create_tempfile(int64_t size=0, const char *suffix=NULL)
MR::default_type value_type
std::string basename(const std::string &name)
bool has_suffix(const std::string &name, const std::string &suffix)
List contiguous_along_axis(size_t axis)
convenience function to get volume-contiguous strides
List contiguous_along_spatial_axes(const HeaderType &header)
convenience function to get spatially contiguous strides
List get_nearest_match(const HeaderType ¤t, const List &desired)
produce strides from current that match those specified in desired
List get_actual(HeaderType &header)
get actual strides:
size_t offset(const HeaderType &header)
calculate offset to start of data
List get(const HeaderType &header)
return the strides of header as a vector<ssize_t>
std::map< std::string, std::string > KeyValues
used in various places for storing key-value pairs
constexpr int SpatiallyContiguous
enable_if_image_type< ImageType, void >::type display(ImageType &x)
display the contents of an image in MRView (for debugging only)
double default_type
the default type used throughout MRtrix
std::string str(const T &value, int precision=0)
Eigen::Transform< default_type, 3, Eigen::AffineCompact > transform_type
the type for the affine transform of an image:
std::enable_if<!is_data_type< ValueType >::value, void >::type __set_fetch_store_functions(std::function< ValueType(const void *, size_t, default_type, default_type)> &, std::function< void(ValueType, void *, size_t, default_type, default_type)> &, DataType)
void copy(InputImageType &&source, OutputImageType &&destination, size_t from_axis=0, size_t to_axis=std::numeric_limits< size_t >::max())
void threaded_copy(InputImageType &source, OutputImageType &destination, const vector< size_t > &axes, size_t num_axes_in_thread=1)
size_t is_dash(const std::string &arg)
match whole string to a dash or any Unicode character that looks like one
std::enable_if< is_adapter_type< typenamestd::remove_reference< ImageType >::type >::value, std::string >::type save(ImageType &&x, const std::string &filename, bool use_multi_threading=true)
save contents of an existing image to file (for debugging only)
void threaded_copy_with_progress_message(const std::string &message, InputImageType &source, OutputImageType &destination, const vector< size_t > &axes, size_t num_axes_in_thread=1)