15 #include <vsg/core/Data.h>
17 #include <vsg/maths/mat4.h>
18 #include <vsg/maths/vec2.h>
19 #include <vsg/maths/vec3.h>
20 #include <vsg/maths/vec4.h>
22 #include <vsg/io/Input.h>
23 #include <vsg/io/Output.h>
25 #define VSG_array2D(N, T) \
26 using N = Array2D<T>; \
28 constexpr const char* type_name<N>() noexcept { return "vsg::" #N; }
52 if (_width != 0 && _height != 0)
54 _data = _allocate(_width * _height);
56 for (
auto& v : rhs) *(dest_v++) = v;
62 Data(in_properties,
sizeof(value_type)),
63 _data(_allocate(width * height)),
65 _height(height) {
dirty(); }
67 Array2D(uint32_t width, uint32_t height, value_type* data,
Properties in_properties = {}) :
68 Data(in_properties,
sizeof(value_type)),
71 _height(height) {
dirty(); }
73 Array2D(uint32_t width, uint32_t height,
const value_type& value,
Properties in_properties = {}) :
74 Data(in_properties,
sizeof(value_type)),
75 _data(_allocate(width * height)),
79 for (
auto& v : *
this) v = value;
89 assign(data, offset, stride, width, height, in_properties);
92 template<
typename... Args>
98 std::size_t sizeofObject()
const noexcept
override {
return sizeof(
Array2D); }
99 const char* className()
const noexcept
override {
return type_name<Array2D>(); }
100 const std::type_info&
type_info() const noexcept
override {
return typeid(*this); }
101 bool is_compatible(
const std::type_info& type)
const noexcept
override {
return typeid(
Array2D) == type || Data::is_compatible(type); }
104 void accept(Visitor& visitor)
override;
105 void accept(ConstVisitor& visitor)
const override;
107 void read(Input& input)
override
109 std::size_t original_size = size();
113 uint32_t w = input.readValue<uint32_t>(
"width");
114 uint32_t h = input.readValue<uint32_t>(
"height");
116 if (
auto data_storage = input.readObject<Data>(
"storage"))
118 uint32_t offset = input.readValue<uint32_t>(
"offset");
123 if (input.matchPropertyName(
"data"))
125 std::size_t new_size = computeValueCountIncludingMipmaps(w, h, 1,
properties.maxNumMipmaps);
129 if (original_size != new_size)
132 _data = _allocate(new_size);
137 _data = _allocate(new_size);
145 if (_data) input.read(new_size, _data);
151 void write(Output& output)
const override
155 output.writeValue<uint32_t>(
"width", _width);
156 output.writeValue<uint32_t>(
"height", _height);
158 output.writeObject(
"storage", _storage);
161 auto offset = (
reinterpret_cast<uintptr_t
>(_data) -
reinterpret_cast<uintptr_t
>(_storage->dataPointer()));
162 output.writeValue<uint32_t>(
"offset", offset);
166 output.writePropertyName(
"data");
167 output.write(valueCount(), _data);
168 output.writeEndOfLine();
171 std::size_t size()
const {
return (
properties.maxNumMipmaps <= 1) ?
static_cast<std::size_t
>(_width * _height) : computeValueCountIncludingMipmaps(_width, _height, 1,
properties.maxNumMipmaps); }
173 bool available()
const {
return _data !=
nullptr; }
174 bool empty()
const {
return _data ==
nullptr; }
186 Array2D& operator=(
const Array2D& rhs)
188 if (&rhs ==
this)
return *
this;
194 _height = rhs._height;
196 if (_width != 0 && _height != 0)
198 _data = _allocate(_width * _height);
200 for (
auto& v : rhs) *(dest_v++) = v;
208 void assign(uint32_t width, uint32_t height, value_type* data, Properties in_properties = {})
222 void assign(ref_ptr<Data> storage, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, Properties in_properties = {})
229 if (_storage && _storage->dataPointer())
231 _data =
reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_storage->dataPointer()) + offset);
247 void* dataRelease()
override
263 std::size_t valueSize()
const override {
return sizeof(value_type); }
264 std::size_t valueCount()
const override {
return size(); }
266 bool dataAvailable()
const override {
return available(); }
267 std::size_t dataSize()
const override {
return size() *
properties.stride; }
269 void* dataPointer()
override {
return _data; }
270 const void* dataPointer()
const override {
return _data; }
272 void* dataPointer(std::size_t i)
override {
return data(i); }
273 const void* dataPointer(std::size_t i)
const override {
return data(i); }
275 uint32_t dimensions()
const override {
return 2; }
276 uint32_t width()
const override {
return _width; }
277 uint32_t height()
const override {
return _height; }
278 uint32_t depth()
const override {
return 1; }
280 value_type* data() {
return _data; }
281 const value_type* data()
const {
return _data; }
283 inline value_type* data(std::size_t i) {
return reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_data) + i *
properties.stride); }
284 inline const value_type* data(std::size_t i)
const {
return reinterpret_cast<const value_type*
>(
reinterpret_cast<const uint8_t*
>(_data) + i *
properties.stride); }
286 std::size_t index(uint32_t i, uint32_t j)
const noexcept {
return static_cast<std::size_t
>(j) * _width + i; }
288 value_type& operator[](std::size_t i) {
return *data(i); }
289 const value_type& operator[](std::size_t i)
const {
return *data(i); }
291 value_type& at(std::size_t i) {
return *data(i); }
292 const value_type& at(std::size_t i)
const {
return *data(i); }
294 value_type& operator()(uint32_t i, uint32_t j) {
return *data(index(i, j)); }
295 const value_type& operator()(uint32_t i, uint32_t j)
const {
return *data(index(i, j)); }
297 value_type& at(uint32_t i, uint32_t j) {
return *data(index(i, j)); }
298 const value_type& at(uint32_t i, uint32_t j)
const {
return *data(index(i, j)); }
300 void set(std::size_t i,
const value_type& v) { *data(i) = v; }
301 void set(uint32_t i, uint32_t j,
const value_type& v) { *data(index(i, j)) = v; }
303 Data* storage() {
return _storage; }
304 const Data* storage()
const {
return _storage; }
306 iterator begin() {
return iterator{_data,
properties.stride}; }
307 const_iterator begin()
const {
return const_iterator{_data,
properties.stride}; }
309 iterator end() {
return iterator{data(_width * _height),
properties.stride}; }
310 const_iterator end()
const {
return const_iterator{data(_width * _height),
properties.stride}; }
318 value_type* _allocate(
size_t size)
const
323 return new value_type[size];
325 return new (std::malloc(
sizeof(value_type) * size)) value_type[size];
327 return new (vsg::allocate(
sizeof(value_type) * size, ALLOCATOR_AFFINITY_DATA)) value_type[size];
332 if (!_storage && _data)
339 vsg::deallocate(_data);
347 ref_ptr<Data> _storage;
350 VSG_array2D(byteArray2D, int8_t);
351 VSG_array2D(ubyteArray2D, uint8_t);
352 VSG_array2D(shortArray2D, int16_t);
353 VSG_array2D(ushortArray2D, uint16_t);
354 VSG_array2D(intArray2D, int32_t);
355 VSG_array2D(uintArray2D, uint32_t);
356 VSG_array2D(floatArray2D,
float);
357 VSG_array2D(doubleArray2D,
double);
359 VSG_array2D(vec2Array2D, vec2);
360 VSG_array2D(vec3Array2D, vec3);
361 VSG_array2D(vec4Array2D, vec4);
363 VSG_array2D(dvec2Array2D, dvec2);
364 VSG_array2D(dvec3Array2D, dvec3);
365 VSG_array2D(dvec4Array2D, dvec4);
367 VSG_array2D(bvec2Array2D, bvec2);
368 VSG_array2D(bvec3Array2D, bvec3);
369 VSG_array2D(bvec4Array2D, bvec4);
371 VSG_array2D(ubvec2Array2D, ubvec2);
372 VSG_array2D(ubvec3Array2D, ubvec3);
373 VSG_array2D(ubvec4Array2D, ubvec4);
375 VSG_array2D(svec2Array2D, svec2);
376 VSG_array2D(svec3Array2D, svec3);
377 VSG_array2D(svec4Array2D, svec4);
379 VSG_array2D(usvec2Array2D, usvec2);
380 VSG_array2D(usvec3Array2D, usvec3);
381 VSG_array2D(usvec4Array2D, usvec4);
383 VSG_array2D(ivec2Array2D, ivec2);
384 VSG_array2D(ivec3Array2D, ivec3);
385 VSG_array2D(ivec4Array2D, ivec4);
387 VSG_array2D(uivec2Array2D, uivec2);
388 VSG_array2D(uivec3Array2D, uivec3);
389 VSG_array2D(uivec4Array2D, uivec4);
391 VSG_array2D(block64Array2D, block64);
392 VSG_array2D(block128Array2D, block128);
const std::type_info & type_info() const noexcept override
return the std::type_info of this Object
Definition: Array2D.h:100
Properties properties
properties of the data such as format, origin, stride, dataVariance etc.
Definition: Data.h:173
void dirty()
increment the ModifiedCount to signify the data has been modified
Definition: Data.h:206
AllocatorType allocatorType
hint as how the data values may change during the lifetime of the vsg::Data.
Definition: Data.h:125