1#include <cgv/data/data_view.h>
5#include <cgv/data/ref_ptr.h>
27 const data_format* _format,
29 const size_t* _step_sizes) : format(_format)
33 std::fill(step_sizes+dim,step_sizes+4,0);
34 std::copy(_step_sizes, _step_sizes+dim, step_sizes);
47 std::fill(step_sizes+dim,step_sizes+4,0);
52 for (
unsigned i=1; i < dim; ++i)
53 step_sizes[dim-1-i] = format->
align(
91 return step_sizes[dim];
93template <
class D,
typename P>
95 P _data_ptr,
unsigned _dim,
const size_t* _step_sizes)
99template <
class D,
typename P>
101 typename cgv::type::func::transfer_const<P,void*>::type _data_ptr)
105template <
class D,
typename P>
108 return data_ptr == 0 || format == 0;
110template <
class D,
typename P>
114 std::cerr <<
"1d operator access to 0d data ptr" << std::endl;
117 return D(format, data_ptr+i*step_sizes[0],
118 (
unsigned) (dim-1), step_sizes+1);
120template <
class D,
typename P>
124 std::cerr <<
"2d operator access to " << dim <<
"d data ptr" << std::endl;
127 return D(format, data_ptr+i*step_sizes[0]+j*step_sizes[1],
128 (
unsigned) (dim-2),step_sizes+2);
130template <
class D,
typename P>
134 std::cerr <<
"3d operator access to " << dim <<
"d data ptr" << std::endl;
137 return D(format, data_ptr+i*step_sizes[0]+j*step_sizes[1]+k*step_sizes[2],
138 (
unsigned) (dim-3),step_sizes+3);
140template <
class D,
typename P>
144 std::cerr <<
"4d operator access to " << dim <<
"d data ptr" << std::endl;
147 return D(format, data_ptr+i*step_sizes[0]+j*step_sizes[1]+k*step_sizes[2]+l*step_sizes[3],
148 (
unsigned int) (dim-4),step_sizes+4);
150template <
class D,
typename P>
153 unsigned n = (unsigned) permutation.size();
154 if (n < 2 || n > 4) {
155 std::cerr <<
"permutation '" << permutation.c_str() <<
"' has invalid length " << n << std::endl;
158 size_t new_step_sizes[4];
160 bool used[4] = {
false,
false,
false,
false };
162 new_step_sizes[i] = step_sizes[i];
163 for (i=0; i<n; ++i) {
164 int idx = permutation[i]-
'i';
165 if (idx < 0 || idx > 3) {
166 std::cerr <<
"invalid permutation entry '" << permutation[i] <<
"', only 'ijkl' allowed" << std::endl;
170 new_step_sizes[i] = step_sizes[idx];
172 for (i=0; i<get_dim(); ++i)
174 std::cerr <<
"invalid permutation of length " << n <<
" without reference to '" << (
'i'+i) <<
"'" << std::endl;
177 return D(get_format(), get_ptr<unsigned char>(), get_dim(), new_step_sizes);
221 for (
int i=0; i<4; ++i)
222 step_sizes[i] = dv.step_sizes[i];
237 for (
int i=0; i<4; ++i)
238 step_sizes[i] = dv.step_sizes[i];
253 data_ptr =
static_cast<unsigned char*
>(ptr);
257 unsigned _dim,
const size_t* _step_sizes)
270 dv.get_format(), dv.get_ptr<const unsigned char>(), dv.get_dim(), dv.step_sizes)
275 data_ptr =
static_cast<const unsigned char*
>(ptr);
281 char* buffer =
new char[delta];
283 for (
size_t y = 0; y < H/2; ++y) {
284 memcpy(buffer,
data_ptr + y*delta, delta);
286 memcpy(
data_ptr + (H-y-1)*delta, buffer, delta);
300 if(n_dims < 1 || n_dims > 3) {
301 std::cerr <<
"cannot compose data views with " << n_dims <<
" dimension" << std::endl;
305 case 1: composed_df->
set_height ((
unsigned)dvs.size());
break;
306 case 2: composed_df->
set_depth ((
unsigned)dvs.size());
break;
309 if(composed_dv.
empty()) {
310 new(&composed_dv)
data_view(composed_df);
312 std::cerr <<
"cannot compose into a non empty data view" << std::endl;
315 unsigned char* dst_ptr = composed_dv.
get_ptr<
unsigned char>();
316 unsigned wrong_format_count = 0;
317 size_t bytes_per_slice = composed_df->
get_nr_bytes() / dvs.size();
318 for(
size_t i = 0; i < dvs.size(); ++i) {
321 unsigned char* src_ptr = dv.
get_ptr<
unsigned char>();
324 if(*src_df_ptr != *df_ptr || n_bytes != bytes_per_slice) {
325 ++wrong_format_count;
328 memcpy(dst_ptr, src_ptr, n_bytes);
331 if(wrong_format_count > 0) {
332 std::cerr <<
"skipped " << wrong_format_count <<
" data views with unmatching formats while composing" << std::endl;
341 unsigned n_components = (unsigned)std::distance(first, last);
342 if(n_components < 2 || n_components > 4) {
343 std::cerr <<
"cannot combine channels of less than 2 or more than 4 data views" << std::endl;
349 std::cerr <<
"cannot combine components of data views with more than one component" << std::endl;
352 std::vector<data_view>::iterator it = first;
353 for(
unsigned i = 1; i < n_components; ++i) {
355 if(*src_df_ptr != *df_ptr) {
356 std::cerr <<
"cannot combine channels of data views with different formats" << std::endl;
365 switch(n_components) {
366 case 2: dst_component_format =
CF_RG;
break;
367 case 3: dst_component_format =
CF_RGB;
break;
368 case 4: dst_component_format =
CF_RGBA;
break;
382 dst_df_ptr =
new data_format(w, component_type, dst_component_format);
388 dst_df_ptr =
new data_format(w, h, component_type, dst_component_format);
396 dst_df_ptr =
new data_format(w, h, d, component_type, dst_component_format);
406 dst_df_ptr =
new data_format(w, h, d, t, component_type, dst_component_format);
412 std::cerr <<
"cannot combine channels into a non empty data view" << std::endl;
419 for(
size_t i = 0; i < t; ++i) {
420 for(
size_t z = 0; z < d; ++z) {
421 for(
size_t y = 0; y < h; ++y) {
422 for(
size_t x = 0; x < w; ++x) {
425 for(
unsigned j = 0; j < n_components; ++j) {
427 unsigned char* src_ptr = src_dv.
get_ptr<
unsigned char>(x, mask_h*y, mask_d*z, mask_t*i);
428 unsigned char* dst_ptr = dv.
get_ptr<
unsigned char>(x, mask_h*y, mask_d*z, mask_t*i);
430 dst_ptr += j * component_size;
432 memcpy(dst_ptr, src_ptr, component_size);
The const_data_view has the functionality of the data_view but uses a const pointer and therefore doe...
void set_ptr(const void *ptr)
set a different data pointer
const_data_view & operator=(const const_data_view &dv)
assignment of const_data_view never gains ownership of format or data
const_data_view()
construct an empty data view without format and with empty data pointer*/
base class of both implementations of the data view managing the component format,...
size_t get_step_size(unsigned int dim) const
return the step size in bytes in the i-th dimension
void manage_format(bool enable=true)
whether to manage the data format pointer
const data_format * get_format() const
return the component format
data_view_base(const data_format *_format, unsigned int _dim, const size_t *_step_sizes)
constructor used to construct sub views onto the data view
void set_format(const data_format *_format)
set a new data format
unsigned int get_dim() const
return the dimension of the data view, which is less or equal to the dimension of the data format
bool owns_format
whether to own the data format
virtual ~data_view_base()
delete format if it is owned
template class implementing the part of the view that depends on whether the pointer is const or not ...
D operator()(size_t i) const
access to i-th data entry
unsigned char * data_ptr
data pointer of type unsigned char or const unsigned char
bool empty() const
return whether the data pointer is a null pointer
cgv::type::func::transfer_const< P, S * >::type get_ptr() const
return a data pointer to type S
data_view_impl(const data_format *_format, P _data_ptr, unsigned _dim, const size_t *_step_sizes)
constructor used to construct sub views onto the data view
D permute(const std::string &permutation) const
permute the order of the indices, where the permutation argument "kji" implies that after the permuta...
the data view gives access to a data array of one, two, three or four dimensions.
bool owns_ptr
a flag telling whether the data ptr is owned by the view
~data_view()
destruct view and delete data pointer if it is owned by the view
static bool combine_components(data_view &dv, const std::vector< data_view >::iterator first, const std::vector< data_view >::iterator last)
combine n data views each with one component channel into a single data view with n component channel...
data_view & operator=(const data_view &dv)
the assignment operator takes over the data format and data pointers in case they are managed by the ...
data_view()
construct an empty data view without format and with empty data pointer*/
static bool compose(data_view &composed_dv, const std::vector< data_view > &dvs)
combine multiple n-dimensional data views with the same format into a (n+1)-dimensional data view by ...
void reflect_horizontally()
reflect 2D data view at horizontal axis
void set_ptr(unsigned char *ptr, bool manage_ptr)
set a different data pointer that will be deleted with the delete [] operator of type (unsigned char*...
static size_t align(size_t v, unsigned a)
return the next integer larger or equal to v which is dividable by a
ComponentFormat
define standard formats, which should be used to avoid wrong assignment of component names
@ CF_RGBA
color format with components R, G and B
@ CF_R
undefinded format with no component
@ CF_RGB
color format with two components R and G
@ CF_RG
color format with intensity and alpha components: I and A
unsigned int get_type_size(TypeId tid)
function that returns the size of a type specified through TypeId
TypeId
ids for the different types and type constructs