#pragma once #include "component_format.h" #include "lib_begin.h" using namespace cgv::type::info; namespace cgv { namespace data { /** A data_format describes a multidimensional data block of data entries. It inherits the information stored in component info which describes which components each data entry has. The data_format adds information about the dimensionality and the alignment and resolution in each dimension. */ class CGV_API data_format : public component_format { protected: struct dimension_info { unsigned int resolution; unsigned int alignment; unsigned int layout_dimension; dimension_info(unsigned int n = 0, unsigned int a = 1, unsigned int ld = 0) : resolution(n), alignment(a), layout_dimension(ld) {} }; /// store for each dimension resolution and alignment in a dimension_info struct std::vector dimensions; public: /// construct an undefined data format data_format(); /// construct from description string, see set_data_format for docu explicit data_format(const std::string& description); /** Set data format from description string, which adds information to the description string of the component format and has the following syntax. For the definition of the token \c component_format in the syntax definition refer to the docu of component_format::set_component_format(). If a parse error arises, return false and set the static last_error member, which can be queried with get_last_error(). Syntax definition: \verbatim data_format <- component_format['|' alignment_in_bytes] '(' dimension_info (',' dimension_info)* ')' dimension_info <- resolution [':' layout_dimension]['|' alignment_in_bytes] - resolution : unsigned int ... number of entries in specified dimension - layout_dimension : unsigned int ... index of dimension in memory layout, which defaults to the specified dimension - alignment_in_bytes : unsigned int ... alignment in the memory layout for entries with index zero in the specified dimension \endverbatim In the standard memory layout of for example an image, the entries are arranged line by line, i.e. first the entries of the first line are stored from left to right, followed by the entries of the second line and so on. To change this order of the layout, one can specify for each dimension in the data format a layout dimension which defaults to the dimension index, i.e. if the layout dimensions of all dimensions correspond to the dimension index, the memory layout is starting with the 0-th dimension. To store an image in a columns first memory layout, the layout dimensions would be 1 and 0 for dimensions 0 and 1. Some examples of valid data format description strings: - \c "uint8[R,G,B](127|8,256)" ... 127x256 RGB-image, where each line is aligned to multiples of 8 - \c "uint8[R,G,B](127:1,256:0)" ... 127x256 RGB-image stored in column major memory layout - \c "uint16[L:12,A:12]|4(32,32,32)" ... 32x32x32 12-Bit Luminance Alpha Volume, where each entry is aligned to 4 bytes */ bool set_data_format(const std::string& description); /// construct a 1d data format from width and the information needed to construct a component info data_format(unsigned int _width, TypeId _component_type, const std::string& _component_name_list, unsigned int align = 1, unsigned int d0 = 0, unsigned int d1 = 0, unsigned int d2 = 0, unsigned int d3 = 0); /// construct a 1d data format from width and the information needed to construct a component info data_format(unsigned int _width, TypeId _component_type, ComponentFormat _cf, unsigned int align = 1, unsigned int d0 = 0, unsigned int d1 = 0, unsigned int d2 = 0, unsigned int d3 = 0); /// construct a 2d data format from width and height data_format(unsigned int _width, unsigned int _height, TypeId _component_type, const std::string& _component_name_list, unsigned int align = 1, unsigned int d0 = 0, unsigned int d1 = 0, unsigned int d2 = 0, unsigned int d3 = 0); /// construct a 2d data format from width and height data_format(unsigned int _width, unsigned int _height, TypeId _component_type, ComponentFormat _cf, unsigned int align = 1, unsigned int d0 = 0, unsigned int d1 = 0, unsigned int d2 = 0, unsigned int d3 = 0); /// construct a 3d data format from width, height and depth data_format(unsigned int _width, unsigned int _height, unsigned int _depth, TypeId _component_type, const std::string& _component_name_list, unsigned int align = 1, unsigned int d0 = 0, unsigned int d1 = 0, unsigned int d2 = 0, unsigned int d3 = 0); /// construct a 3d data format from width, height and depth data_format(unsigned int _width, unsigned int _height, unsigned int _depth, TypeId _component_type, ComponentFormat _cf, unsigned int align = 1, unsigned int d0 = 0, unsigned int d1 = 0, unsigned int d2 = 0, unsigned int d3 = 0); /// construct a 4d data format from width, height, depth and count data_format(unsigned int _width, unsigned int _height, unsigned int _depth, unsigned int _count, TypeId _component_type, const std::string& _component_name_list, unsigned int align = 1, unsigned int d0 = 0, unsigned int d1 = 0, unsigned int d2 = 0, unsigned int d3 = 0); /// construct a 4d data format from width, height, depth and count data_format(unsigned int _width, unsigned int _height, unsigned int _depth, unsigned int _count, TypeId _component_type, ComponentFormat _cf, unsigned int align = 1, unsigned int d0 = 0, unsigned int d1 = 0, unsigned int d2 = 0, unsigned int d3 = 0); /// define stream out operator friend FRIEND_MEMBER_API std::ostream& operator << (std::ostream& os, const data_format& df); /// set the dimensions to the given values void set_dimensions(unsigned _d0, unsigned _d1 = -1, unsigned _d2 = -1, unsigned _d3 = -1); /// return the number of dimensions of the data set unsigned int get_nr_dimensions() const; /// set the number of dimensions of the data set void set_nr_dimensions(unsigned int _d); /// return the resolution in the i-th dimension, or 0 if not defined unsigned int get_resolution(unsigned int i) const; /// return the resolution in the first dimension, or 1 if not defined unsigned int get_width() const; /// return the resolution in the second dimension, or 1 if not defined unsigned int get_height() const; /// return the resolution in the third dimension, or 1 if not defined unsigned int get_depth() const; /// return the resolution in the highest dimension, or 1 if not defined unsigned int get_nr_time_steps() const; /// return the total number of data entries unsigned int get_nr_entries() const; /// return the total number of bytes necessary to store the data unsigned int get_nr_bytes() const; /// set the resolution in the i-th dimension, add dimensions if necessary void set_resolution(unsigned int i, unsigned int resolution); /// set the resolution in the first dimension, add dimensions if necessary void set_width(unsigned int _width); /// set the resolution in the second dimension, add dimensions if necessary void set_height(unsigned int _height); /// set the resolution in the third dimension, add dimensions if necessary void set_depth(unsigned int _depth); /// set the resolution in the last dimension, add dimensions if necessary void set_nr_time_steps(unsigned int _nr_time_steps); /// return the alignment of entries unsigned int get_entry_alignment() const; /** return the alignment of a given dimension, where the alignment of the last dimension is always 1 and cannot be changed. This method also returns 1 if i is out of the range of valid dimensions. */ unsigned int get_alignment(unsigned int i) const; /// set the alignment of entries void set_entry_alignment(unsigned int _a); /** set the alignment of a given dimension, add dimensions if necessary. The alignment of the last dimension is always 1 and cannot be set.*/ void set_alignment(unsigned int i, unsigned int _a); /// return the layout dimension of a given dimension unsigned int get_layout_dimension(unsigned int dim) const; /// set the layout dimension of a given dimension, add dimensions if necessary void get_layout_dimension(unsigned int dim, unsigned int layout_dim); /// return the component_format info by simple conversion of the this pointer const component_format& get_component_format() const; /// set component_format by simply assigning to a converted this pointer void set_component_format(const component_format& cf); /// comparison between component formats bool operator == (const data_format& df) const; /// comparison between component formats bool operator != (const data_format& df) const; }; /** stream out operator writes the data format in the syntax of description strings as defined in the docu of set_data_format(). */ extern CGV_API std::ostream& operator << (std::ostream& os, const data_format& df); } } #include