mirror of
https://github.com/Relintai/pmlpp.git
synced 2024-11-08 13:12:09 +01:00
2460 lines
58 KiB
C++
2460 lines
58 KiB
C++
/*************************************************************************/
|
|
/* mlpp_tensor3.cpp */
|
|
/*************************************************************************/
|
|
/* This file is part of: */
|
|
/* PMLPP Machine Learning Library */
|
|
/* https://github.com/Relintai/pmlpp */
|
|
/*************************************************************************/
|
|
/* Copyright (c) 2023-present Péter Magyar. */
|
|
/* Copyright (c) 2022-2023 Marc Melikyan */
|
|
/* */
|
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
/* a copy of this software and associated documentation files (the */
|
|
/* "Software"), to deal in the Software without restriction, including */
|
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
/* the following conditions: */
|
|
/* */
|
|
/* The above copyright notice and this permission notice shall be */
|
|
/* included in all copies or substantial portions of the Software. */
|
|
/* */
|
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
/*************************************************************************/
|
|
|
|
#include "mlpp_tensor3.h"
|
|
|
|
#include "core/io/image.h"
|
|
|
|
Array MLPPTensor3::get_data() {
|
|
PoolRealArray pl;
|
|
|
|
int ds = data_size();
|
|
|
|
if (ds) {
|
|
pl.resize(ds);
|
|
PoolRealArray::Write w = pl.write();
|
|
real_t *dest = w.ptr();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
dest[i] = _data[i];
|
|
}
|
|
}
|
|
|
|
Array arr;
|
|
arr.push_back(size());
|
|
arr.push_back(pl);
|
|
|
|
return arr;
|
|
}
|
|
void MLPPTensor3::set_data(const Array &p_from) {
|
|
if (p_from.size() != 2) {
|
|
return;
|
|
}
|
|
|
|
Size3i s = p_from[0];
|
|
PoolRealArray pl = p_from[1];
|
|
|
|
int ds = s.x * s.y * s.z;
|
|
|
|
if (ds != pl.size()) {
|
|
return;
|
|
}
|
|
|
|
if (_size != s) {
|
|
resize(s);
|
|
}
|
|
|
|
PoolRealArray::Read r = pl.read();
|
|
for (int i = 0; i < ds; ++i) {
|
|
_data[i] = r[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_add(const Vector<real_t> &p_row) {
|
|
if (p_row.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
int fms = z_slice_data_size();
|
|
|
|
ERR_FAIL_COND(fms != p_row.size());
|
|
|
|
int ci = data_size();
|
|
|
|
++_size.z;
|
|
|
|
_data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t));
|
|
CRASH_COND_MSG(!_data, "Out of memory");
|
|
|
|
const real_t *row_arr = p_row.ptr();
|
|
|
|
for (int i = 0; i < p_row.size(); ++i) {
|
|
_data[ci + i] = row_arr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_add_pool_vector(const PoolRealArray &p_row) {
|
|
if (p_row.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
int fms = z_slice_data_size();
|
|
|
|
ERR_FAIL_COND(fms != p_row.size());
|
|
|
|
int ci = data_size();
|
|
|
|
++_size.z;
|
|
|
|
_data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t));
|
|
CRASH_COND_MSG(!_data, "Out of memory");
|
|
|
|
PoolRealArray::Read rread = p_row.read();
|
|
const real_t *row_arr = rread.ptr();
|
|
|
|
for (int i = 0; i < p_row.size(); ++i) {
|
|
_data[ci + i] = row_arr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_add_mlpp_vector(const Ref<MLPPVector> &p_row) {
|
|
ERR_FAIL_COND(!p_row.is_valid());
|
|
|
|
int p_row_size = p_row->size();
|
|
|
|
if (p_row_size == 0) {
|
|
return;
|
|
}
|
|
|
|
int fms = z_slice_data_size();
|
|
|
|
ERR_FAIL_COND(fms != p_row_size);
|
|
|
|
int ci = data_size();
|
|
|
|
++_size.z;
|
|
|
|
_data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t));
|
|
CRASH_COND_MSG(!_data, "Out of memory");
|
|
|
|
const real_t *row_ptr = p_row->ptr();
|
|
|
|
for (int i = 0; i < p_row_size; ++i) {
|
|
_data[ci + i] = row_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_add_mlpp_matrix(const Ref<MLPPMatrix> &p_matrix) {
|
|
ERR_FAIL_COND(!p_matrix.is_valid());
|
|
|
|
int other_data_size = p_matrix->data_size();
|
|
|
|
if (other_data_size == 0) {
|
|
return;
|
|
}
|
|
|
|
Size2i matrix_size = p_matrix->size();
|
|
Size2i fms = z_slice_size();
|
|
|
|
ERR_FAIL_COND(fms != matrix_size);
|
|
|
|
int start_offset = data_size();
|
|
|
|
++_size.z;
|
|
|
|
_data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t));
|
|
CRASH_COND_MSG(!_data, "Out of memory");
|
|
|
|
const real_t *other_ptr = p_matrix->ptr();
|
|
|
|
for (int i = 0; i < other_data_size; ++i) {
|
|
_data[start_offset + i] = other_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_remove(int p_index) {
|
|
ERR_FAIL_INDEX(p_index, _size.z);
|
|
|
|
--_size.z;
|
|
|
|
int ds = data_size();
|
|
|
|
if (ds == 0) {
|
|
memfree(_data);
|
|
_data = NULL;
|
|
return;
|
|
}
|
|
|
|
int fmds = z_slice_data_size();
|
|
|
|
for (int i = calculate_z_slice_index(p_index); i < ds; ++i) {
|
|
_data[i] = _data[i + fmds];
|
|
}
|
|
|
|
_data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t));
|
|
CRASH_COND_MSG(!_data, "Out of memory");
|
|
}
|
|
|
|
// Removes the item copying the last value into the position of the one to
|
|
// remove. It's generally faster than `remove`.
|
|
void MLPPTensor3::z_slice_remove_unordered(int p_index) {
|
|
ERR_FAIL_INDEX(p_index, _size.z);
|
|
|
|
--_size.z;
|
|
|
|
int ds = data_size();
|
|
|
|
if (ds == 0) {
|
|
memfree(_data);
|
|
_data = NULL;
|
|
return;
|
|
}
|
|
|
|
int start_ind = calculate_z_slice_index(p_index);
|
|
int end_ind = calculate_z_slice_index(p_index + 1);
|
|
|
|
for (int i = start_ind; i < end_ind; ++i) {
|
|
_data[i] = _data[ds + i];
|
|
}
|
|
|
|
_data = (real_t *)memrealloc(_data, data_size() * sizeof(real_t));
|
|
CRASH_COND_MSG(!_data, "Out of memory");
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_swap(int p_index_1, int p_index_2) {
|
|
ERR_FAIL_INDEX(p_index_1, _size.z);
|
|
ERR_FAIL_INDEX(p_index_2, _size.z);
|
|
|
|
int ind1_start = calculate_z_slice_index(p_index_1);
|
|
int ind2_start = calculate_z_slice_index(p_index_2);
|
|
|
|
int fmds = z_slice_data_size();
|
|
|
|
for (int i = 0; i < fmds; ++i) {
|
|
SWAP(_data[ind1_start + i], _data[ind2_start + i]);
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::resize(const Size3i &p_size) {
|
|
_size = p_size;
|
|
|
|
int ds = data_size();
|
|
|
|
if (ds == 0) {
|
|
if (_data) {
|
|
memfree(_data);
|
|
_data = NULL;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
_data = (real_t *)memrealloc(_data, ds * sizeof(real_t));
|
|
CRASH_COND_MSG(!_data, "Out of memory");
|
|
}
|
|
|
|
void MLPPTensor3::shape_set(const Size3i &p_size) {
|
|
int ds = data_size();
|
|
int new_data_size = p_size.x * p_size.y * p_size.z;
|
|
|
|
ERR_FAIL_COND_MSG(ds != new_data_size, "The new size has a different volume than the old. If this is intended use resize()!");
|
|
|
|
_size = p_size;
|
|
}
|
|
|
|
Vector<real_t> MLPPTensor3::row_get_vector(int p_index_z, int p_index_y) const {
|
|
ERR_FAIL_INDEX_V(p_index_y, _size.y, Vector<real_t>());
|
|
ERR_FAIL_INDEX_V(p_index_z, _size.z, Vector<real_t>());
|
|
|
|
Vector<real_t> ret;
|
|
|
|
if (unlikely(_size.x == 0)) {
|
|
return ret;
|
|
}
|
|
|
|
ret.resize(_size.x);
|
|
|
|
int ind_start = p_index_y * _size.x;
|
|
|
|
real_t *row_ptr = ret.ptrw();
|
|
|
|
for (int i = 0; i < _size.x; ++i) {
|
|
row_ptr[i] = _data[ind_start + i];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
PoolRealArray MLPPTensor3::row_get_pool_vector(int p_index_z, int p_index_y) const {
|
|
ERR_FAIL_INDEX_V(p_index_y, _size.y, PoolRealArray());
|
|
ERR_FAIL_INDEX_V(p_index_z, _size.z, PoolRealArray());
|
|
|
|
PoolRealArray ret;
|
|
|
|
if (unlikely(_size.x == 0)) {
|
|
return ret;
|
|
}
|
|
|
|
ret.resize(_size.x);
|
|
|
|
int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z;
|
|
|
|
PoolRealArray::Write w = ret.write();
|
|
real_t *row_ptr = w.ptr();
|
|
|
|
for (int i = 0; i < _size.x; ++i) {
|
|
row_ptr[i] = _data[ind_start + i];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Ref<MLPPVector> MLPPTensor3::row_get_mlpp_vector(int p_index_z, int p_index_y) const {
|
|
ERR_FAIL_INDEX_V(p_index_y, _size.y, Ref<MLPPVector>());
|
|
ERR_FAIL_INDEX_V(p_index_z, _size.z, Ref<MLPPVector>());
|
|
|
|
Ref<MLPPVector> ret;
|
|
ret.instance();
|
|
|
|
if (unlikely(_size.x == 0)) {
|
|
return ret;
|
|
}
|
|
|
|
ret->resize(_size.x);
|
|
|
|
int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z;
|
|
|
|
real_t *row_ptr = ret->ptrw();
|
|
|
|
for (int i = 0; i < _size.x; ++i) {
|
|
row_ptr[i] = _data[ind_start + i];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void MLPPTensor3::row_get_into_mlpp_vector(int p_index_z, int p_index_y, Ref<MLPPVector> target) const {
|
|
ERR_FAIL_COND(!target.is_valid());
|
|
ERR_FAIL_INDEX(p_index_y, _size.y);
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
|
|
if (unlikely(target->size() != _size.x)) {
|
|
target->resize(_size.x);
|
|
}
|
|
|
|
int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z;
|
|
|
|
real_t *row_ptr = target->ptrw();
|
|
|
|
for (int i = 0; i < _size.x; ++i) {
|
|
row_ptr[i] = _data[ind_start + i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::row_set_vector(int p_index_z, int p_index_y, const Vector<real_t> &p_row) {
|
|
ERR_FAIL_COND(p_row.size() != _size.x);
|
|
ERR_FAIL_INDEX(p_index_y, _size.y);
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
|
|
int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z;
|
|
|
|
const real_t *row_ptr = p_row.ptr();
|
|
|
|
for (int i = 0; i < _size.x; ++i) {
|
|
_data[ind_start + i] = row_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::row_set_pool_vector(int p_index_z, int p_index_y, const PoolRealArray &p_row) {
|
|
ERR_FAIL_COND(p_row.size() != _size.x);
|
|
ERR_FAIL_INDEX(p_index_y, _size.y);
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
|
|
int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z;
|
|
|
|
PoolRealArray::Read r = p_row.read();
|
|
const real_t *row_ptr = r.ptr();
|
|
|
|
for (int i = 0; i < _size.x; ++i) {
|
|
_data[ind_start + i] = row_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::row_set_mlpp_vector(int p_index_z, int p_index_y, const Ref<MLPPVector> &p_row) {
|
|
ERR_FAIL_COND(!p_row.is_valid());
|
|
ERR_FAIL_COND(p_row->size() != _size.x);
|
|
ERR_FAIL_INDEX(p_index_y, _size.y);
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
|
|
int ind_start = p_index_y * _size.x + _size.x * _size.y * p_index_z;
|
|
|
|
const real_t *row_ptr = p_row->ptr();
|
|
|
|
for (int i = 0; i < _size.x; ++i) {
|
|
_data[ind_start + i] = row_ptr[i];
|
|
}
|
|
}
|
|
|
|
Vector<real_t> MLPPTensor3::z_slice_get_vector(int p_index_z) const {
|
|
ERR_FAIL_INDEX_V(p_index_z, _size.z, Vector<real_t>());
|
|
|
|
Vector<real_t> ret;
|
|
|
|
int fmds = z_slice_data_size();
|
|
|
|
if (unlikely(fmds == 0)) {
|
|
return ret;
|
|
}
|
|
|
|
ret.resize(fmds);
|
|
|
|
int ind_start = calculate_z_slice_index(p_index_z);
|
|
|
|
real_t *row_ptr = ret.ptrw();
|
|
|
|
for (int i = 0; i < fmds; ++i) {
|
|
row_ptr[i] = _data[ind_start + i];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
PoolRealArray MLPPTensor3::z_slice_get_pool_vector(int p_index_z) const {
|
|
ERR_FAIL_INDEX_V(p_index_z, _size.z, PoolRealArray());
|
|
|
|
PoolRealArray ret;
|
|
|
|
int fmds = z_slice_data_size();
|
|
|
|
if (unlikely(fmds == 0)) {
|
|
return ret;
|
|
}
|
|
|
|
ret.resize(fmds);
|
|
|
|
int ind_start = calculate_z_slice_index(p_index_z);
|
|
|
|
PoolRealArray::Write w = ret.write();
|
|
real_t *row_ptr = w.ptr();
|
|
|
|
for (int i = 0; i < fmds; ++i) {
|
|
row_ptr[i] = _data[ind_start + i];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Ref<MLPPVector> MLPPTensor3::z_slice_get_mlpp_vector(int p_index_z) const {
|
|
ERR_FAIL_INDEX_V(p_index_z, _size.z, Ref<MLPPVector>());
|
|
|
|
Ref<MLPPVector> ret;
|
|
ret.instance();
|
|
|
|
int fmds = z_slice_data_size();
|
|
|
|
if (unlikely(fmds == 0)) {
|
|
return ret;
|
|
}
|
|
|
|
ret->resize(fmds);
|
|
|
|
int ind_start = calculate_z_slice_index(p_index_z);
|
|
|
|
real_t *row_ptr = ret->ptrw();
|
|
|
|
for (int i = 0; i < fmds; ++i) {
|
|
row_ptr[i] = _data[ind_start + i];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_get_into_mlpp_vector(int p_index_z, Ref<MLPPVector> target) const {
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
|
|
int fmds = z_slice_data_size();
|
|
|
|
if (unlikely(target->size() != fmds)) {
|
|
target->resize(fmds);
|
|
}
|
|
|
|
int ind_start = calculate_z_slice_index(p_index_z);
|
|
|
|
real_t *row_ptr = target->ptrw();
|
|
|
|
for (int i = 0; i < fmds; ++i) {
|
|
row_ptr[i] = _data[ind_start + i];
|
|
}
|
|
}
|
|
|
|
Ref<MLPPMatrix> MLPPTensor3::z_slice_get_mlpp_matrix(int p_index_z) const {
|
|
ERR_FAIL_INDEX_V(p_index_z, _size.z, Ref<MLPPMatrix>());
|
|
|
|
Ref<MLPPMatrix> ret;
|
|
ret.instance();
|
|
|
|
int fmds = z_slice_data_size();
|
|
|
|
if (unlikely(fmds == 0)) {
|
|
return ret;
|
|
}
|
|
|
|
ret->resize(z_slice_size());
|
|
|
|
int ind_start = calculate_z_slice_index(p_index_z);
|
|
|
|
real_t *row_ptr = ret->ptrw();
|
|
|
|
for (int i = 0; i < fmds; ++i) {
|
|
row_ptr[i] = _data[ind_start + i];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_get_into_mlpp_matrix(int p_index_z, Ref<MLPPMatrix> target) const {
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
|
|
int fmds = z_slice_data_size();
|
|
Size2i fms = z_slice_size();
|
|
|
|
if (unlikely(target->size() != fms)) {
|
|
target->resize(fms);
|
|
}
|
|
|
|
int ind_start = calculate_z_slice_index(p_index_z);
|
|
|
|
real_t *row_ptr = target->ptrw();
|
|
|
|
for (int i = 0; i < fmds; ++i) {
|
|
row_ptr[i] = _data[ind_start + i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_set_vector(int p_index_z, const Vector<real_t> &p_row) {
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
|
|
int fmds = z_slice_data_size();
|
|
|
|
ERR_FAIL_COND(p_row.size() != fmds);
|
|
|
|
int ind_start = calculate_z_slice_index(p_index_z);
|
|
|
|
const real_t *row_ptr = p_row.ptr();
|
|
|
|
for (int i = 0; i < fmds; ++i) {
|
|
_data[ind_start + i] = row_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_set_pool_vector(int p_index_z, const PoolRealArray &p_row) {
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
|
|
int fmds = z_slice_data_size();
|
|
|
|
ERR_FAIL_COND(p_row.size() != fmds);
|
|
|
|
int ind_start = calculate_z_slice_index(p_index_z);
|
|
|
|
PoolRealArray::Read r = p_row.read();
|
|
const real_t *row_ptr = r.ptr();
|
|
|
|
for (int i = 0; i < fmds; ++i) {
|
|
_data[ind_start + i] = row_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_set_mlpp_vector(int p_index_z, const Ref<MLPPVector> &p_row) {
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
ERR_FAIL_COND(!p_row.is_valid());
|
|
|
|
int fmds = z_slice_data_size();
|
|
|
|
ERR_FAIL_COND(p_row->size() != fmds);
|
|
|
|
int ind_start = calculate_z_slice_index(p_index_z);
|
|
|
|
const real_t *row_ptr = p_row->ptr();
|
|
|
|
for (int i = 0; i < fmds; ++i) {
|
|
_data[ind_start + i] = row_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_set_mlpp_matrix(int p_index_z, const Ref<MLPPMatrix> &p_mat) {
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
ERR_FAIL_COND(!p_mat.is_valid());
|
|
|
|
int fmds = z_slice_data_size();
|
|
|
|
ERR_FAIL_COND(p_mat->size() != z_slice_size());
|
|
|
|
int ind_start = calculate_z_slice_index(p_index_z);
|
|
|
|
const real_t *row_ptr = p_mat->ptr();
|
|
|
|
for (int i = 0; i < fmds; ++i) {
|
|
_data[ind_start + i] = row_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::x_slice_get_into(int p_index_x, Ref<MLPPMatrix> target) const {
|
|
ERR_FAIL_INDEX(p_index_x, _size.x);
|
|
ERR_FAIL_COND(!target.is_valid());
|
|
|
|
if (unlikely(target->size() != Size2i(_size.y, _size.z))) {
|
|
target->resize(Size2i(_size.y, _size.z));
|
|
}
|
|
|
|
for (int z = 0; z < _size.z; ++z) {
|
|
for (int y = 0; y < _size.y; ++y) {
|
|
target->element_set(z, y, element_get(z, p_index_x, y));
|
|
}
|
|
}
|
|
}
|
|
Ref<MLPPMatrix> MLPPTensor3::x_slice_get(int p_index_x) const {
|
|
ERR_FAIL_INDEX_V(p_index_x, _size.x, Ref<MLPPMatrix>());
|
|
|
|
Ref<MLPPMatrix> m;
|
|
m.instance();
|
|
|
|
x_slice_get_into(p_index_x, m);
|
|
|
|
return m;
|
|
}
|
|
void MLPPTensor3::x_slice_set(int p_index_x, const Ref<MLPPMatrix> &p_mat) {
|
|
ERR_FAIL_INDEX(p_index_x, _size.x);
|
|
ERR_FAIL_COND(!p_mat.is_valid());
|
|
ERR_FAIL_COND(p_mat->size() != Size2i(_size.y, _size.z));
|
|
|
|
for (int z = 0; z < _size.z; ++z) {
|
|
for (int y = 0; y < _size.y; ++y) {
|
|
element_set(z, p_index_x, y, p_mat->element_get(z, y));
|
|
}
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::y_slice_get_into(int p_index_y, Ref<MLPPMatrix> target) const {
|
|
ERR_FAIL_INDEX(p_index_y, _size.y);
|
|
ERR_FAIL_COND(!target.is_valid());
|
|
|
|
if (unlikely(target->size() != Size2i(_size.y, _size.z))) {
|
|
target->resize(Size2i(_size.x, _size.z));
|
|
}
|
|
|
|
for (int z = 0; z < _size.z; ++z) {
|
|
for (int x = 0; x < _size.x; ++x) {
|
|
target->element_set(z, x, element_get(z, x, p_index_y));
|
|
}
|
|
}
|
|
}
|
|
Ref<MLPPMatrix> MLPPTensor3::y_slice_get(int p_index_y) const {
|
|
ERR_FAIL_INDEX_V(p_index_y, _size.y, Ref<MLPPMatrix>());
|
|
|
|
Ref<MLPPMatrix> m;
|
|
m.instance();
|
|
|
|
y_slice_get_into(p_index_y, m);
|
|
|
|
return m;
|
|
}
|
|
void MLPPTensor3::y_slice_set(int p_index_y, const Ref<MLPPMatrix> &p_mat) {
|
|
ERR_FAIL_INDEX(p_index_y, _size.y);
|
|
ERR_FAIL_COND(!p_mat.is_valid());
|
|
ERR_FAIL_COND(p_mat->size() != Size2i(_size.y, _size.z));
|
|
|
|
for (int z = 0; z < _size.z; ++z) {
|
|
for (int x = 0; x < _size.x; ++x) {
|
|
element_set(z, x, p_index_y, p_mat->element_get(z, x));
|
|
}
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::z_slices_add_image(const Ref<Image> &p_img, const int p_channels) {
|
|
ERR_FAIL_COND(!p_img.is_valid());
|
|
|
|
Size2i img_size = Size2i(p_img->get_width(), p_img->get_height());
|
|
|
|
int channel_count = 0;
|
|
int channels[4];
|
|
|
|
if (p_channels & IMAGE_CHANNEL_FLAG_R) {
|
|
channels[channel_count] = 0;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_channels & IMAGE_CHANNEL_FLAG_G) {
|
|
channels[channel_count] = 1;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_channels & IMAGE_CHANNEL_FLAG_B) {
|
|
channels[channel_count] = 2;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_channels & IMAGE_CHANNEL_FLAG_A) {
|
|
channels[channel_count] = 3;
|
|
++channel_count;
|
|
}
|
|
|
|
ERR_FAIL_COND(channel_count == 0);
|
|
|
|
if (unlikely(_size == Size3i())) {
|
|
resize(Size3i(img_size.x, img_size.y, channel_count));
|
|
}
|
|
|
|
Size2i fms = z_slice_size();
|
|
|
|
ERR_FAIL_COND(img_size != fms);
|
|
|
|
int start_channel = _size.y;
|
|
|
|
_size.y += channel_count;
|
|
|
|
resize(_size);
|
|
|
|
Ref<Image> img = p_img;
|
|
|
|
img->lock();
|
|
|
|
for (int y = 0; y < fms.y; ++y) {
|
|
for (int x = 0; x < fms.x; ++x) {
|
|
Color c = img->get_pixel(x, y);
|
|
|
|
for (int i = 0; i < channel_count; ++i) {
|
|
element_set(start_channel + i, y, x, c[channels[i]]);
|
|
}
|
|
}
|
|
}
|
|
|
|
img->unlock();
|
|
}
|
|
|
|
Ref<Image> MLPPTensor3::z_slice_get_image(const int p_index_z) const {
|
|
ERR_FAIL_INDEX_V(p_index_z, _size.z, Ref<Image>());
|
|
|
|
Ref<Image> image;
|
|
image.instance();
|
|
|
|
if (data_size() == 0) {
|
|
return image;
|
|
}
|
|
|
|
PoolByteArray arr;
|
|
|
|
int fmsi = calculate_z_slice_index(p_index_z);
|
|
int fms = z_slice_data_size();
|
|
|
|
arr.resize(fms);
|
|
|
|
PoolByteArray::Write w = arr.write();
|
|
uint8_t *wptr = w.ptr();
|
|
|
|
for (int i = 0; i < fms; ++i) {
|
|
wptr[i] = static_cast<uint8_t>(_data[fmsi + i] * 255.0);
|
|
}
|
|
|
|
image->create(_size.x, _size.y, false, Image::FORMAT_L8, arr);
|
|
|
|
return image;
|
|
}
|
|
Ref<Image> MLPPTensor3::z_slices_get_image(const int p_index_r, const int p_index_g, const int p_index_b, const int p_index_a) const {
|
|
if (p_index_r != -1) {
|
|
ERR_FAIL_INDEX_V(p_index_r, _size.z, Ref<Image>());
|
|
}
|
|
|
|
if (p_index_g != -1) {
|
|
ERR_FAIL_INDEX_V(p_index_g, _size.z, Ref<Image>());
|
|
}
|
|
|
|
if (p_index_b != -1) {
|
|
ERR_FAIL_INDEX_V(p_index_b, _size.z, Ref<Image>());
|
|
}
|
|
|
|
if (p_index_a != -1) {
|
|
ERR_FAIL_INDEX_V(p_index_a, _size.z, Ref<Image>());
|
|
}
|
|
|
|
Ref<Image> image;
|
|
image.instance();
|
|
|
|
if (data_size() == 0) {
|
|
return image;
|
|
}
|
|
|
|
Size2i fms = z_slice_size();
|
|
|
|
image->create(_size.x, _size.y, false, Image::FORMAT_RGBA8);
|
|
|
|
image->lock();
|
|
|
|
for (int y = 0; y < fms.y; ++y) {
|
|
for (int x = 0; x < fms.x; ++x) {
|
|
Color c;
|
|
|
|
if (p_index_r != -1) {
|
|
c.r = element_get(p_index_r, y, x);
|
|
}
|
|
|
|
if (p_index_g != -1) {
|
|
c.g = element_get(p_index_g, y, x);
|
|
}
|
|
|
|
if (p_index_b != -1) {
|
|
c.b = element_get(p_index_b, y, x);
|
|
}
|
|
|
|
if (p_index_a != -1) {
|
|
c.a = element_get(p_index_a, y, x);
|
|
}
|
|
|
|
image->set_pixel(x, y, c);
|
|
}
|
|
}
|
|
|
|
image->unlock();
|
|
|
|
return image;
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_get_into_image(Ref<Image> p_target, const int p_index_z, const int p_target_channels) const {
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
ERR_FAIL_COND(!p_target.is_valid());
|
|
|
|
int channel_count = 0;
|
|
int channels[4];
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_R) {
|
|
channels[channel_count] = 0;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_G) {
|
|
channels[channel_count] = 1;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_B) {
|
|
channels[channel_count] = 2;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_A) {
|
|
channels[channel_count] = 3;
|
|
++channel_count;
|
|
}
|
|
|
|
ERR_FAIL_COND(channel_count == 0);
|
|
|
|
if (data_size() == 0) {
|
|
p_target->clear();
|
|
return;
|
|
}
|
|
|
|
Size2i img_size = Size2i(p_target->get_width(), p_target->get_height());
|
|
Size2i fms = z_slice_size();
|
|
if (img_size != fms) {
|
|
bool mip_maps = p_target->has_mipmaps();
|
|
p_target->resize(fms.x, fms.y, Image::INTERPOLATE_NEAREST);
|
|
|
|
if (p_target->has_mipmaps() != mip_maps) {
|
|
if (mip_maps) {
|
|
p_target->generate_mipmaps();
|
|
} else {
|
|
p_target->clear_mipmaps();
|
|
}
|
|
}
|
|
}
|
|
|
|
p_target->lock();
|
|
|
|
for (int y = 0; y < fms.y; ++y) {
|
|
for (int x = 0; x < fms.x; ++x) {
|
|
Color c;
|
|
|
|
float e = element_get(p_index_z, y, x);
|
|
|
|
for (int i = 0; i < channel_count; ++i) {
|
|
c[channels[i]] = e;
|
|
}
|
|
|
|
p_target->set_pixel(x, y, c);
|
|
}
|
|
}
|
|
|
|
p_target->unlock();
|
|
}
|
|
void MLPPTensor3::z_slices_get_into_image(Ref<Image> p_target, const int p_index_r, const int p_index_g, const int p_index_b, const int p_index_a) const {
|
|
ERR_FAIL_COND(!p_target.is_valid());
|
|
|
|
if (p_index_r != -1) {
|
|
ERR_FAIL_INDEX(p_index_r, _size.z);
|
|
}
|
|
|
|
if (p_index_g != -1) {
|
|
ERR_FAIL_INDEX(p_index_g, _size.z);
|
|
}
|
|
|
|
if (p_index_b != -1) {
|
|
ERR_FAIL_INDEX(p_index_b, _size.z);
|
|
}
|
|
|
|
if (p_index_a != -1) {
|
|
ERR_FAIL_INDEX(p_index_a, _size.z);
|
|
}
|
|
|
|
if (data_size() == 0) {
|
|
p_target->clear();
|
|
return;
|
|
}
|
|
|
|
Size2i img_size = Size2i(p_target->get_width(), p_target->get_height());
|
|
Size2i fms = z_slice_size();
|
|
if (img_size != fms) {
|
|
bool mip_maps = p_target->has_mipmaps();
|
|
p_target->resize(fms.x, fms.y, Image::INTERPOLATE_NEAREST);
|
|
|
|
if (p_target->has_mipmaps() != mip_maps) {
|
|
if (mip_maps) {
|
|
p_target->generate_mipmaps();
|
|
} else {
|
|
p_target->clear_mipmaps();
|
|
}
|
|
}
|
|
}
|
|
|
|
p_target->lock();
|
|
|
|
for (int y = 0; y < fms.y; ++y) {
|
|
for (int x = 0; x < fms.x; ++x) {
|
|
Color c;
|
|
|
|
if (p_index_r != -1) {
|
|
c.r = element_get(p_index_r, y, x);
|
|
}
|
|
|
|
if (p_index_g != -1) {
|
|
c.g = element_get(p_index_g, y, x);
|
|
}
|
|
|
|
if (p_index_b != -1) {
|
|
c.b = element_get(p_index_b, y, x);
|
|
}
|
|
|
|
if (p_index_a != -1) {
|
|
c.a = element_get(p_index_a, y, x);
|
|
}
|
|
|
|
p_target->set_pixel(x, y, c);
|
|
}
|
|
}
|
|
|
|
p_target->unlock();
|
|
}
|
|
|
|
void MLPPTensor3::z_slice_set_image(const Ref<Image> &p_img, const int p_index_z, const int p_image_channel_flag) {
|
|
ERR_FAIL_COND(!p_img.is_valid());
|
|
ERR_FAIL_INDEX(p_index_z, _size.z);
|
|
|
|
int channel_index = -1;
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
if (((p_image_channel_flag & (1 << i)) != 0)) {
|
|
channel_index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ERR_FAIL_INDEX(channel_index, 4);
|
|
|
|
Size2i img_size = Size2i(p_img->get_width(), p_img->get_height());
|
|
Size2i fms = z_slice_size();
|
|
|
|
ERR_FAIL_COND(img_size != fms);
|
|
|
|
Ref<Image> img = p_img;
|
|
|
|
img->lock();
|
|
|
|
for (int y = 0; y < fms.y; ++y) {
|
|
for (int x = 0; x < fms.x; ++x) {
|
|
Color c = img->get_pixel(x, y);
|
|
|
|
element_set(p_index_z, y, x, c[channel_index]);
|
|
}
|
|
}
|
|
|
|
img->unlock();
|
|
}
|
|
void MLPPTensor3::z_slices_set_image(const Ref<Image> &p_img, const int p_index_r, const int p_index_g, const int p_index_b, const int p_index_a) {
|
|
ERR_FAIL_COND(!p_img.is_valid());
|
|
|
|
if (p_index_r != -1) {
|
|
ERR_FAIL_INDEX(p_index_r, _size.z);
|
|
}
|
|
|
|
if (p_index_g != -1) {
|
|
ERR_FAIL_INDEX(p_index_g, _size.z);
|
|
}
|
|
|
|
if (p_index_b != -1) {
|
|
ERR_FAIL_INDEX(p_index_b, _size.z);
|
|
}
|
|
|
|
if (p_index_a != -1) {
|
|
ERR_FAIL_INDEX(p_index_a, _size.z);
|
|
}
|
|
|
|
Size2i img_size = Size2i(p_img->get_width(), p_img->get_height());
|
|
Size2i fms = z_slice_size();
|
|
|
|
ERR_FAIL_COND(img_size != fms);
|
|
|
|
Ref<Image> img = p_img;
|
|
|
|
img->lock();
|
|
|
|
for (int y = 0; y < fms.y; ++y) {
|
|
for (int x = 0; x < fms.x; ++x) {
|
|
Color c = img->get_pixel(x, y);
|
|
|
|
if (p_index_r != -1) {
|
|
element_set(p_index_r, y, x, c.r);
|
|
}
|
|
|
|
if (p_index_g != -1) {
|
|
element_set(p_index_g, y, x, c.g);
|
|
}
|
|
|
|
if (p_index_b != -1) {
|
|
element_set(p_index_b, y, x, c.b);
|
|
}
|
|
|
|
if (p_index_a != -1) {
|
|
element_set(p_index_a, y, x, c.a);
|
|
}
|
|
}
|
|
}
|
|
|
|
img->unlock();
|
|
}
|
|
|
|
void MLPPTensor3::set_from_image(const Ref<Image> &p_img, const int p_channels) {
|
|
ERR_FAIL_COND(!p_img.is_valid());
|
|
|
|
int channel_count = 0;
|
|
int channels[4];
|
|
|
|
if (p_channels & IMAGE_CHANNEL_FLAG_R) {
|
|
channels[channel_count] = 0;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_channels & IMAGE_CHANNEL_FLAG_G) {
|
|
channels[channel_count] = 1;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_channels & IMAGE_CHANNEL_FLAG_B) {
|
|
channels[channel_count] = 2;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_channels & IMAGE_CHANNEL_FLAG_A) {
|
|
channels[channel_count] = 3;
|
|
++channel_count;
|
|
}
|
|
|
|
ERR_FAIL_COND(channel_count == 0);
|
|
|
|
Size2i img_size = Size2i(p_img->get_width(), p_img->get_height());
|
|
|
|
resize(Size3i(img_size.x, img_size.y, channel_count));
|
|
|
|
Size2i fms = z_slice_size();
|
|
|
|
Ref<Image> img = p_img;
|
|
|
|
img->lock();
|
|
|
|
for (int y = 0; y < fms.y; ++y) {
|
|
for (int x = 0; x < fms.x; ++x) {
|
|
Color c = img->get_pixel(x, y);
|
|
|
|
for (int i = 0; i < channel_count; ++i) {
|
|
element_set(i, y, x, c[channels[i]]);
|
|
}
|
|
}
|
|
}
|
|
|
|
img->unlock();
|
|
}
|
|
|
|
Ref<Image> MLPPTensor3::x_slice_get_image(const int p_index_x) const {
|
|
ERR_FAIL_INDEX_V(p_index_x, _size.x, Ref<Image>());
|
|
|
|
Ref<Image> image;
|
|
image.instance();
|
|
|
|
if (data_size() == 0) {
|
|
return image;
|
|
}
|
|
|
|
PoolByteArray arr;
|
|
arr.resize(_size.y * _size.z);
|
|
|
|
PoolByteArray::Write w = arr.write();
|
|
uint8_t *wptr = w.ptr();
|
|
int i = 0;
|
|
|
|
for (int z = 0; z < _size.z; ++z) {
|
|
for (int y = 0; y < _size.y; ++y) {
|
|
wptr[i] = static_cast<uint8_t>(element_get(z, p_index_x, y) * 255.0);
|
|
|
|
++i;
|
|
}
|
|
}
|
|
|
|
image->create(_size.y, _size.z, false, Image::FORMAT_L8, arr);
|
|
|
|
return image;
|
|
}
|
|
void MLPPTensor3::x_slice_get_into_image(Ref<Image> p_target, const int p_index_x, const int p_target_channels) const {
|
|
ERR_FAIL_INDEX(p_index_x, _size.x);
|
|
ERR_FAIL_COND(!p_target.is_valid());
|
|
|
|
int channel_count = 0;
|
|
int channels[4];
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_R) {
|
|
channels[channel_count] = 0;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_G) {
|
|
channels[channel_count] = 1;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_B) {
|
|
channels[channel_count] = 2;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_A) {
|
|
channels[channel_count] = 3;
|
|
++channel_count;
|
|
}
|
|
|
|
ERR_FAIL_COND(channel_count == 0);
|
|
|
|
if (data_size() == 0) {
|
|
p_target->clear();
|
|
return;
|
|
}
|
|
|
|
Size2i img_size = Size2i(p_target->get_width(), p_target->get_height());
|
|
Size2i fms = Size2i(_size.y, _size.z);
|
|
if (img_size != fms) {
|
|
bool mip_maps = p_target->has_mipmaps();
|
|
p_target->resize(fms.x, fms.y, Image::INTERPOLATE_NEAREST);
|
|
|
|
if (p_target->has_mipmaps() != mip_maps) {
|
|
if (mip_maps) {
|
|
p_target->generate_mipmaps();
|
|
} else {
|
|
p_target->clear_mipmaps();
|
|
}
|
|
}
|
|
}
|
|
|
|
p_target->lock();
|
|
|
|
for (int y = 0; y < fms.y; ++y) {
|
|
for (int z = 0; z < fms.x; ++z) {
|
|
Color c;
|
|
|
|
float e = element_get(z, y, p_index_x);
|
|
|
|
for (int i = 0; i < channel_count; ++i) {
|
|
c[channels[i]] = e;
|
|
}
|
|
|
|
p_target->set_pixel(z, y, c);
|
|
}
|
|
}
|
|
|
|
p_target->unlock();
|
|
}
|
|
void MLPPTensor3::x_slice_set_image(const Ref<Image> &p_img, const int p_index_x, const int p_image_channel_flag) {
|
|
ERR_FAIL_COND(!p_img.is_valid());
|
|
ERR_FAIL_INDEX(p_index_x, _size.x);
|
|
|
|
int channel_index = -1;
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
if (((p_image_channel_flag & (1 << i)) != 0)) {
|
|
channel_index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ERR_FAIL_INDEX(channel_index, 4);
|
|
|
|
Size2i img_size = Size2i(p_img->get_width(), p_img->get_height());
|
|
Size2i fms = Size2i(_size.y, _size.z);
|
|
|
|
ERR_FAIL_COND(img_size != fms);
|
|
|
|
Ref<Image> img = p_img;
|
|
|
|
img->lock();
|
|
|
|
for (int y = 0; y < fms.y; ++y) {
|
|
for (int z = 0; z < fms.x; ++z) {
|
|
Color c = img->get_pixel(z, y);
|
|
|
|
element_set(z, y, p_index_x, c[channel_index]);
|
|
}
|
|
}
|
|
|
|
img->unlock();
|
|
}
|
|
|
|
Ref<Image> MLPPTensor3::y_slice_get_image(const int p_index_y) const {
|
|
ERR_FAIL_INDEX_V(p_index_y, _size.y, Ref<Image>());
|
|
|
|
Ref<Image> image;
|
|
image.instance();
|
|
|
|
if (data_size() == 0) {
|
|
return image;
|
|
}
|
|
|
|
PoolByteArray arr;
|
|
arr.resize(_size.x * _size.z);
|
|
|
|
PoolByteArray::Write w = arr.write();
|
|
uint8_t *wptr = w.ptr();
|
|
int i = 0;
|
|
|
|
for (int z = 0; z < _size.z; ++z) {
|
|
for (int x = 0; x < _size.x; ++x) {
|
|
wptr[i] = static_cast<uint8_t>(element_get(z, x, p_index_y) * 255.0);
|
|
|
|
++i;
|
|
}
|
|
}
|
|
|
|
image->create(_size.x, _size.z, false, Image::FORMAT_L8, arr);
|
|
|
|
return image;
|
|
}
|
|
void MLPPTensor3::y_slice_get_into_image(Ref<Image> p_target, const int p_index_y, const int p_target_channels) const {
|
|
ERR_FAIL_INDEX(p_index_y, _size.y);
|
|
ERR_FAIL_COND(!p_target.is_valid());
|
|
|
|
int channel_count = 0;
|
|
int channels[4];
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_R) {
|
|
channels[channel_count] = 0;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_G) {
|
|
channels[channel_count] = 1;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_B) {
|
|
channels[channel_count] = 2;
|
|
++channel_count;
|
|
}
|
|
|
|
if (p_target_channels & IMAGE_CHANNEL_FLAG_A) {
|
|
channels[channel_count] = 3;
|
|
++channel_count;
|
|
}
|
|
|
|
ERR_FAIL_COND(channel_count == 0);
|
|
|
|
if (data_size() == 0) {
|
|
p_target->clear();
|
|
return;
|
|
}
|
|
|
|
Size2i img_size = Size2i(p_target->get_width(), p_target->get_height());
|
|
Size2i fms = Size2i(_size.x, _size.z);
|
|
if (img_size != fms) {
|
|
bool mip_maps = p_target->has_mipmaps();
|
|
p_target->resize(fms.x, fms.y, Image::INTERPOLATE_NEAREST);
|
|
|
|
if (p_target->has_mipmaps() != mip_maps) {
|
|
if (mip_maps) {
|
|
p_target->generate_mipmaps();
|
|
} else {
|
|
p_target->clear_mipmaps();
|
|
}
|
|
}
|
|
}
|
|
|
|
p_target->lock();
|
|
|
|
for (int x = 0; x < fms.y; ++x) {
|
|
for (int z = 0; z < fms.x; ++z) {
|
|
Color c;
|
|
|
|
float e = element_get(z, p_index_y, x);
|
|
|
|
for (int i = 0; i < channel_count; ++i) {
|
|
c[channels[i]] = e;
|
|
}
|
|
|
|
p_target->set_pixel(z, x, c);
|
|
}
|
|
}
|
|
|
|
p_target->unlock();
|
|
}
|
|
void MLPPTensor3::y_slice_set_image(const Ref<Image> &p_img, const int p_index_y, const int p_image_channel_flag) {
|
|
ERR_FAIL_COND(!p_img.is_valid());
|
|
ERR_FAIL_INDEX(p_index_y, _size.y);
|
|
|
|
int channel_index = -1;
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
if (((p_image_channel_flag & (1 << i)) != 0)) {
|
|
channel_index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ERR_FAIL_INDEX(channel_index, 4);
|
|
|
|
Size2i img_size = Size2i(p_img->get_width(), p_img->get_height());
|
|
Size2i fms = Size2i(_size.x, _size.z);
|
|
|
|
ERR_FAIL_COND(img_size != fms);
|
|
|
|
Ref<Image> img = p_img;
|
|
|
|
img->lock();
|
|
|
|
for (int z = 0; z < fms.y; ++z) {
|
|
for (int x = 0; x < fms.x; ++x) {
|
|
Color c = img->get_pixel(x, z);
|
|
|
|
element_set(z, p_index_y, x, c[channel_index]);
|
|
}
|
|
}
|
|
|
|
img->unlock();
|
|
}
|
|
|
|
void MLPPTensor3::add(const Ref<MLPPTensor3> &B) {
|
|
ERR_FAIL_COND(!B.is_valid());
|
|
ERR_FAIL_COND(_size != B->size());
|
|
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = ptrw();
|
|
|
|
int ds = data_size();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
c_ptr[i] += b_ptr[i];
|
|
}
|
|
}
|
|
Ref<MLPPTensor3> MLPPTensor3::addn(const Ref<MLPPTensor3> &B) const {
|
|
ERR_FAIL_COND_V(!B.is_valid(), Ref<MLPPTensor3>());
|
|
ERR_FAIL_COND_V(_size != B->size(), Ref<MLPPTensor3>());
|
|
|
|
Ref<MLPPTensor3> C;
|
|
C.instance();
|
|
C->resize(_size);
|
|
|
|
const real_t *a_ptr = ptr();
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = C->ptrw();
|
|
|
|
int ds = data_size();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
c_ptr[i] = a_ptr[i] + b_ptr[i];
|
|
}
|
|
|
|
return C;
|
|
}
|
|
void MLPPTensor3::addb(const Ref<MLPPTensor3> &A, const Ref<MLPPTensor3> &B) {
|
|
ERR_FAIL_COND(!A.is_valid() || !B.is_valid());
|
|
Size3i a_size = A->size();
|
|
ERR_FAIL_COND(a_size != B->size());
|
|
|
|
if (_size != a_size) {
|
|
resize(a_size);
|
|
}
|
|
|
|
const real_t *a_ptr = A->ptr();
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = ptrw();
|
|
|
|
int data_size = A->data_size();
|
|
|
|
for (int i = 0; i < data_size; ++i) {
|
|
c_ptr[i] = a_ptr[i] + b_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::sub(const Ref<MLPPTensor3> &B) {
|
|
ERR_FAIL_COND(!B.is_valid());
|
|
ERR_FAIL_COND(_size != B->size());
|
|
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = ptrw();
|
|
|
|
int ds = data_size();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
c_ptr[i] -= b_ptr[i];
|
|
}
|
|
}
|
|
Ref<MLPPTensor3> MLPPTensor3::subn(const Ref<MLPPTensor3> &B) const {
|
|
ERR_FAIL_COND_V(!B.is_valid(), Ref<MLPPTensor3>());
|
|
ERR_FAIL_COND_V(_size != B->size(), Ref<MLPPTensor3>());
|
|
|
|
Ref<MLPPTensor3> C;
|
|
C.instance();
|
|
C->resize(_size);
|
|
|
|
const real_t *a_ptr = ptr();
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = C->ptrw();
|
|
|
|
int ds = data_size();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
c_ptr[i] = a_ptr[i] - b_ptr[i];
|
|
}
|
|
|
|
return C;
|
|
}
|
|
void MLPPTensor3::subb(const Ref<MLPPTensor3> &A, const Ref<MLPPTensor3> &B) {
|
|
ERR_FAIL_COND(!A.is_valid() || !B.is_valid());
|
|
Size3i a_size = A->size();
|
|
ERR_FAIL_COND(a_size != B->size());
|
|
|
|
if (_size != a_size) {
|
|
resize(a_size);
|
|
}
|
|
|
|
const real_t *a_ptr = A->ptr();
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = ptrw();
|
|
|
|
int data_size = A->data_size();
|
|
|
|
for (int i = 0; i < data_size; ++i) {
|
|
c_ptr[i] = a_ptr[i] - b_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::division_element_wise(const Ref<MLPPTensor3> &B) {
|
|
ERR_FAIL_COND(!B.is_valid());
|
|
ERR_FAIL_COND(_size != B->size());
|
|
|
|
int ds = data_size();
|
|
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; i++) {
|
|
c_ptr[i] /= b_ptr[i];
|
|
}
|
|
}
|
|
Ref<MLPPTensor3> MLPPTensor3::division_element_wisen(const Ref<MLPPTensor3> &B) const {
|
|
ERR_FAIL_COND_V(!B.is_valid(), Ref<MLPPTensor3>());
|
|
ERR_FAIL_COND_V(_size != B->size(), Ref<MLPPTensor3>());
|
|
|
|
int ds = data_size();
|
|
|
|
Ref<MLPPTensor3> C;
|
|
C.instance();
|
|
C->resize(_size);
|
|
|
|
const real_t *a_ptr = ptr();
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = C->ptrw();
|
|
|
|
for (int i = 0; i < ds; i++) {
|
|
c_ptr[i] = a_ptr[i] / b_ptr[i];
|
|
}
|
|
|
|
return C;
|
|
}
|
|
void MLPPTensor3::division_element_wiseb(const Ref<MLPPTensor3> &A, const Ref<MLPPTensor3> &B) {
|
|
ERR_FAIL_COND(!A.is_valid() || !B.is_valid());
|
|
Size3i a_size = A->size();
|
|
ERR_FAIL_COND(a_size != B->size());
|
|
|
|
if (a_size != _size) {
|
|
resize(a_size);
|
|
}
|
|
|
|
int ds = data_size();
|
|
|
|
const real_t *a_ptr = A->ptr();
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; i++) {
|
|
c_ptr[i] = a_ptr[i] / b_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::sqrt() {
|
|
int ds = data_size();
|
|
|
|
real_t *out_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
out_ptr[i] = Math::sqrt(out_ptr[i]);
|
|
}
|
|
}
|
|
Ref<MLPPTensor3> MLPPTensor3::sqrtn() const {
|
|
Ref<MLPPTensor3> out;
|
|
out.instance();
|
|
out->resize(size());
|
|
|
|
int ds = data_size();
|
|
|
|
const real_t *a_ptr = ptr();
|
|
real_t *out_ptr = out->ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
out_ptr[i] = Math::sqrt(a_ptr[i]);
|
|
}
|
|
|
|
return out;
|
|
}
|
|
void MLPPTensor3::sqrtb(const Ref<MLPPTensor3> &A) {
|
|
ERR_FAIL_COND(!A.is_valid());
|
|
|
|
Size3i a_size = A->size();
|
|
|
|
if (a_size != size()) {
|
|
resize(a_size);
|
|
}
|
|
|
|
int ds = data_size();
|
|
|
|
const real_t *a_ptr = A->ptr();
|
|
real_t *out_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
out_ptr[i] = Math::sqrt(a_ptr[i]);
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::exponentiate(real_t p) {
|
|
int ds = data_size();
|
|
|
|
real_t *out_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
out_ptr[i] = Math::pow(out_ptr[i], p);
|
|
}
|
|
}
|
|
Ref<MLPPTensor3> MLPPTensor3::exponentiaten(real_t p) const {
|
|
Ref<MLPPTensor3> out;
|
|
out.instance();
|
|
out->resize(size());
|
|
|
|
int ds = data_size();
|
|
|
|
const real_t *a_ptr = ptr();
|
|
real_t *out_ptr = out->ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
out_ptr[i] = Math::pow(a_ptr[i], p);
|
|
}
|
|
|
|
return out;
|
|
}
|
|
void MLPPTensor3::exponentiateb(const Ref<MLPPTensor3> &A, real_t p) {
|
|
ERR_FAIL_COND(!A.is_valid());
|
|
|
|
Size3i a_size = A->size();
|
|
|
|
if (a_size != size()) {
|
|
resize(a_size);
|
|
}
|
|
|
|
int ds = data_size();
|
|
|
|
const real_t *a_ptr = A->ptr();
|
|
real_t *out_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
out_ptr[i] = Math::pow(a_ptr[i], p);
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::scalar_multiply(const real_t scalar) {
|
|
int ds = data_size();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
_data[i] *= scalar;
|
|
}
|
|
}
|
|
Ref<MLPPTensor3> MLPPTensor3::scalar_multiplyn(const real_t scalar) const {
|
|
Ref<MLPPTensor3> AN = duplicate_fast();
|
|
int ds = AN->data_size();
|
|
real_t *an_ptr = AN->ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
an_ptr[i] *= scalar;
|
|
}
|
|
|
|
return AN;
|
|
}
|
|
void MLPPTensor3::scalar_multiplyb(const real_t scalar, const Ref<MLPPTensor3> &A) {
|
|
ERR_FAIL_COND(!A.is_valid());
|
|
|
|
if (A->size() != _size) {
|
|
resize(A->size());
|
|
}
|
|
|
|
int ds = data_size();
|
|
real_t *an_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
_data[i] = an_ptr[i] * scalar;
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::scalar_add(const real_t scalar) {
|
|
int ds = data_size();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
_data[i] += scalar;
|
|
}
|
|
}
|
|
Ref<MLPPTensor3> MLPPTensor3::scalar_addn(const real_t scalar) const {
|
|
Ref<MLPPTensor3> AN = duplicate_fast();
|
|
int ds = AN->data_size();
|
|
real_t *an_ptr = AN->ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
an_ptr[i] += scalar;
|
|
}
|
|
|
|
return AN;
|
|
}
|
|
void MLPPTensor3::scalar_addb(const real_t scalar, const Ref<MLPPTensor3> &A) {
|
|
ERR_FAIL_COND(!A.is_valid());
|
|
|
|
if (A->size() != _size) {
|
|
resize(A->size());
|
|
}
|
|
|
|
int ds = data_size();
|
|
real_t *an_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
_data[i] = an_ptr[i] + scalar;
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::hadamard_product(const Ref<MLPPTensor3> &B) {
|
|
ERR_FAIL_COND(!B.is_valid());
|
|
ERR_FAIL_COND(_size != B->size());
|
|
|
|
int ds = data_size();
|
|
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; i++) {
|
|
c_ptr[i] = c_ptr[i] * b_ptr[i];
|
|
}
|
|
}
|
|
Ref<MLPPTensor3> MLPPTensor3::hadamard_productn(const Ref<MLPPTensor3> &B) const {
|
|
ERR_FAIL_COND_V(!B.is_valid(), Ref<MLPPTensor3>());
|
|
ERR_FAIL_COND_V(_size != B->size(), Ref<MLPPTensor3>());
|
|
|
|
int ds = data_size();
|
|
|
|
Ref<MLPPTensor3> C;
|
|
C.instance();
|
|
C->resize(_size);
|
|
|
|
const real_t *a_ptr = ptr();
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = C->ptrw();
|
|
|
|
for (int i = 0; i < ds; i++) {
|
|
c_ptr[i] = a_ptr[i] * b_ptr[i];
|
|
}
|
|
|
|
return C;
|
|
}
|
|
void MLPPTensor3::hadamard_productb(const Ref<MLPPTensor3> &A, const Ref<MLPPTensor3> &B) {
|
|
ERR_FAIL_COND(!A.is_valid() || !B.is_valid());
|
|
Size3i a_size = A->size();
|
|
ERR_FAIL_COND(a_size != B->size());
|
|
|
|
if (a_size != _size) {
|
|
resize(a_size);
|
|
}
|
|
|
|
int ds = data_size();
|
|
|
|
const real_t *a_ptr = A->ptr();
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; i++) {
|
|
c_ptr[i] = a_ptr[i] * b_ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::max(const Ref<MLPPTensor3> &B) {
|
|
ERR_FAIL_COND(!B.is_valid());
|
|
ERR_FAIL_COND(_size != B->size());
|
|
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = ptrw();
|
|
|
|
int ds = data_size();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
c_ptr[i] = MAX(c_ptr[i], b_ptr[i]);
|
|
}
|
|
}
|
|
Ref<MLPPTensor3> MLPPTensor3::maxn(const Ref<MLPPTensor3> &B) const {
|
|
ERR_FAIL_COND_V(!B.is_valid(), Ref<MLPPTensor3>());
|
|
ERR_FAIL_COND_V(_size != B->size(), Ref<MLPPTensor3>());
|
|
|
|
Ref<MLPPTensor3> C;
|
|
C.instance();
|
|
C->resize(_size);
|
|
|
|
const real_t *a_ptr = ptr();
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = C->ptrw();
|
|
|
|
int ds = data_size();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
c_ptr[i] = MAX(a_ptr[i], b_ptr[i]);
|
|
}
|
|
|
|
return C;
|
|
}
|
|
void MLPPTensor3::maxb(const Ref<MLPPTensor3> &A, const Ref<MLPPTensor3> &B) {
|
|
ERR_FAIL_COND(!A.is_valid() || !B.is_valid());
|
|
Size3i a_size = A->size();
|
|
ERR_FAIL_COND(a_size != B->size());
|
|
|
|
if (_size != a_size) {
|
|
resize(a_size);
|
|
}
|
|
|
|
const real_t *a_ptr = A->ptr();
|
|
const real_t *b_ptr = B->ptr();
|
|
real_t *c_ptr = ptrw();
|
|
|
|
int data_size = A->data_size();
|
|
|
|
for (int i = 0; i < data_size; ++i) {
|
|
c_ptr[i] = MAX(a_ptr[i], b_ptr[i]);
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::abs() {
|
|
int ds = data_size();
|
|
|
|
real_t *out_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
out_ptr[i] = ABS(out_ptr[i]);
|
|
}
|
|
}
|
|
Ref<MLPPTensor3> MLPPTensor3::absn() const {
|
|
Ref<MLPPTensor3> out;
|
|
out.instance();
|
|
out->resize(size());
|
|
|
|
int ds = data_size();
|
|
|
|
const real_t *a_ptr = ptr();
|
|
real_t *out_ptr = out->ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
out_ptr[i] = ABS(a_ptr[i]);
|
|
}
|
|
|
|
return out;
|
|
}
|
|
void MLPPTensor3::absb(const Ref<MLPPTensor3> &A) {
|
|
ERR_FAIL_COND(!A.is_valid());
|
|
|
|
Size3i a_size = A->size();
|
|
|
|
if (a_size != size()) {
|
|
resize(a_size);
|
|
}
|
|
|
|
int ds = data_size();
|
|
|
|
const real_t *a_ptr = A->ptr();
|
|
real_t *out_ptr = ptrw();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
out_ptr[i] = ABS(a_ptr[i]);
|
|
}
|
|
}
|
|
|
|
Ref<MLPPVector> MLPPTensor3::flatten() const {
|
|
int ds = data_size();
|
|
|
|
Ref<MLPPVector> res;
|
|
res.instance();
|
|
res->resize(ds);
|
|
|
|
real_t *res_ptr = res->ptrw();
|
|
const real_t *a_ptr = ptr();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
res_ptr[i] = a_ptr[i];
|
|
}
|
|
|
|
return res;
|
|
}
|
|
void MLPPTensor3::flatteno(Ref<MLPPVector> out) const {
|
|
ERR_FAIL_COND(!out.is_valid());
|
|
|
|
int ds = data_size();
|
|
|
|
if (unlikely(out->size() != ds)) {
|
|
out->resize(ds);
|
|
}
|
|
|
|
real_t *res_ptr = out->ptrw();
|
|
const real_t *a_ptr = ptr();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
res_ptr[i] = a_ptr[i];
|
|
}
|
|
}
|
|
|
|
/*
|
|
real_t MLPPTensor3::norm_2(std::vector<std::vector<std::vector<real_t>>> A) {
|
|
real_t sum = 0;
|
|
for (uint32_t i = 0; i < A.size(); i++) {
|
|
for (uint32_t j = 0; j < A[i].size(); j++) {
|
|
for (uint32_t k = 0; k < A[i][j].size(); k++) {
|
|
sum += A[i][j][k] * A[i][j][k];
|
|
}
|
|
}
|
|
}
|
|
return Math::sqrt(sum);
|
|
}
|
|
*/
|
|
|
|
Ref<MLPPMatrix> MLPPTensor3::tensor_vec_mult(const Ref<MLPPVector> &b) {
|
|
Ref<MLPPMatrix> C;
|
|
C.instance();
|
|
C->resize(Size2i(_size.y, _size.z));
|
|
|
|
Ref<MLPPVector> row_tmp;
|
|
row_tmp.instance();
|
|
row_tmp->resize(_size.x);
|
|
|
|
for (int i = 0; i < _size.z; i++) {
|
|
for (int j = 0; j < _size.y; j++) {
|
|
row_get_into_mlpp_vector(i, j, row_tmp);
|
|
|
|
C->element_set(i, j, row_tmp->dot(b));
|
|
}
|
|
}
|
|
|
|
return C;
|
|
}
|
|
|
|
/*
|
|
// Bad implementation. Change this later.
|
|
std::vector<std::vector<std::vector<real_t>>> MLPPTensor3::vector_wise_tensor_product(std::vector<std::vector<std::vector<real_t>>> A, std::vector<std::vector<real_t>> B) {
|
|
std::vector<std::vector<std::vector<real_t>>> C;
|
|
C = resize(C, A);
|
|
for (uint32_t i = 0; i < A[0].size(); i++) {
|
|
for (uint32_t j = 0; j < A[0][i].size(); j++) {
|
|
std::vector<real_t> currentVector;
|
|
currentVector.resize(A.size());
|
|
|
|
for (uint32_t k = 0; k < C.size(); k++) {
|
|
currentVector[k] = A[k][i][j];
|
|
}
|
|
|
|
currentVector = mat_vec_mult(B, currentVector);
|
|
|
|
for (uint32_t k = 0; k < C.size(); k++) {
|
|
C[k][i][j] = currentVector[k];
|
|
}
|
|
}
|
|
}
|
|
return C;
|
|
}
|
|
*/
|
|
|
|
void MLPPTensor3::fill(real_t p_val) {
|
|
if (!_data) {
|
|
return;
|
|
}
|
|
|
|
int ds = data_size();
|
|
for (int i = 0; i < ds; ++i) {
|
|
_data[i] = p_val;
|
|
}
|
|
}
|
|
|
|
Vector<real_t> MLPPTensor3::to_flat_vector() const {
|
|
Vector<real_t> ret;
|
|
ret.resize(data_size());
|
|
real_t *w = ret.ptrw();
|
|
memcpy(w, _data, sizeof(real_t) * data_size());
|
|
return ret;
|
|
}
|
|
|
|
PoolRealArray MLPPTensor3::to_flat_pool_vector() const {
|
|
PoolRealArray pl;
|
|
if (data_size()) {
|
|
pl.resize(data_size());
|
|
typename PoolRealArray::Write w = pl.write();
|
|
real_t *dest = w.ptr();
|
|
|
|
for (int i = 0; i < data_size(); ++i) {
|
|
dest[i] = static_cast<real_t>(_data[i]);
|
|
}
|
|
}
|
|
return pl;
|
|
}
|
|
|
|
Vector<uint8_t> MLPPTensor3::to_flat_byte_array() const {
|
|
Vector<uint8_t> ret;
|
|
ret.resize(data_size() * sizeof(real_t));
|
|
uint8_t *w = ret.ptrw();
|
|
memcpy(w, _data, sizeof(real_t) * data_size());
|
|
return ret;
|
|
}
|
|
|
|
Ref<MLPPTensor3> MLPPTensor3::duplicate_fast() const {
|
|
Ref<MLPPTensor3> ret;
|
|
ret.instance();
|
|
|
|
ret->set_from_mlpp_tensor3r(*this);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void MLPPTensor3::set_from_mlpp_tensor3(const Ref<MLPPTensor3> &p_from) {
|
|
ERR_FAIL_COND(!p_from.is_valid());
|
|
|
|
resize(p_from->size());
|
|
|
|
int ds = p_from->data_size();
|
|
const real_t *ptr = p_from->ptr();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
_data[i] = ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::set_from_mlpp_tensor3r(const MLPPTensor3 &p_from) {
|
|
resize(p_from.size());
|
|
|
|
int ds = p_from.data_size();
|
|
const real_t *ptr = p_from.ptr();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
_data[i] = ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::set_from_mlpp_matrix(const Ref<MLPPMatrix> &p_from) {
|
|
ERR_FAIL_COND(!p_from.is_valid());
|
|
|
|
Size2i mat_size = p_from->size();
|
|
resize(Size3i(mat_size.x, mat_size.y, 1));
|
|
|
|
int ds = p_from->data_size();
|
|
const real_t *ptr = p_from->ptr();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
_data[i] = ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::set_from_mlpp_matrixr(const MLPPMatrix &p_from) {
|
|
Size2i mat_size = p_from.size();
|
|
resize(Size3i(mat_size.x, mat_size.y, 1));
|
|
|
|
int ds = p_from.data_size();
|
|
const real_t *ptr = p_from.ptr();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
_data[i] = ptr[i];
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::set_from_mlpp_vectors(const Vector<Ref<MLPPVector>> &p_from) {
|
|
if (p_from.size() == 0) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
if (!p_from[0].is_valid()) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
resize(Size3i(p_from[0]->size(), p_from.size(), 1));
|
|
|
|
if (data_size() == 0) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < p_from.size(); ++i) {
|
|
const Ref<MLPPVector> &r = p_from[i];
|
|
|
|
ERR_CONTINUE(!r.is_valid());
|
|
ERR_CONTINUE(r->size() != _size.x);
|
|
|
|
int start_index = i * _size.x;
|
|
|
|
const real_t *from_ptr = r->ptr();
|
|
for (int j = 0; j < _size.x; j++) {
|
|
_data[start_index + j] = from_ptr[j];
|
|
}
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::set_from_mlpp_matricess(const Vector<Ref<MLPPMatrix>> &p_from) {
|
|
if (p_from.size() == 0) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
if (!p_from[0].is_valid()) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
resize(Size3i(p_from[0]->size().x, p_from[0]->size().y, p_from.size()));
|
|
|
|
if (data_size() == 0) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
Size2i fms = z_slice_size();
|
|
int fmds = z_slice_data_size();
|
|
|
|
for (int i = 0; i < p_from.size(); ++i) {
|
|
const Ref<MLPPMatrix> &r = p_from[i];
|
|
|
|
ERR_CONTINUE(!r.is_valid());
|
|
ERR_CONTINUE(r->size() != fms);
|
|
|
|
int start_index = calculate_z_slice_index(i);
|
|
|
|
const real_t *from_ptr = r->ptr();
|
|
for (int j = 0; j < fmds; j++) {
|
|
_data[start_index + j] = from_ptr[j];
|
|
}
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::set_from_mlpp_vectors_array(const Array &p_from) {
|
|
if (p_from.size() == 0) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
Ref<MLPPVector> v0 = p_from[0];
|
|
|
|
if (!v0.is_valid()) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
resize(Size3i(v0->size(), p_from.size(), 1));
|
|
|
|
if (data_size() == 0) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < p_from.size(); ++i) {
|
|
Ref<MLPPVector> r = p_from[i];
|
|
|
|
ERR_CONTINUE(!r.is_valid());
|
|
ERR_CONTINUE(r->size() != _size.x);
|
|
|
|
int start_index = i * _size.x;
|
|
|
|
const real_t *from_ptr = r->ptr();
|
|
for (int j = 0; j < _size.x; j++) {
|
|
_data[start_index + j] = from_ptr[j];
|
|
}
|
|
}
|
|
}
|
|
|
|
void MLPPTensor3::set_from_mlpp_matrices_array(const Array &p_from) {
|
|
if (p_from.size() == 0) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
Ref<MLPPMatrix> v0 = p_from[0];
|
|
|
|
if (!v0.is_valid()) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
resize(Size3i(v0->size().x, v0->size().y, p_from.size()));
|
|
|
|
if (data_size() == 0) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
Size2i fms = z_slice_size();
|
|
int fmds = z_slice_data_size();
|
|
|
|
for (int i = 0; i < p_from.size(); ++i) {
|
|
Ref<MLPPMatrix> r = p_from[i];
|
|
|
|
ERR_CONTINUE(!r.is_valid());
|
|
ERR_CONTINUE(r->size() != fms);
|
|
|
|
int start_index = calculate_z_slice_index(i);
|
|
|
|
const real_t *from_ptr = r->ptr();
|
|
for (int j = 0; j < fmds; j++) {
|
|
_data[start_index + j] = from_ptr[j];
|
|
}
|
|
}
|
|
}
|
|
|
|
bool MLPPTensor3::is_equal_approx(const Ref<MLPPTensor3> &p_with, real_t tolerance) const {
|
|
ERR_FAIL_COND_V(!p_with.is_valid(), false);
|
|
|
|
if (unlikely(this == p_with.ptr())) {
|
|
return true;
|
|
}
|
|
|
|
if (_size != p_with->size()) {
|
|
return false;
|
|
}
|
|
|
|
int ds = data_size();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
if (!Math::is_equal_approx(_data[i], p_with->_data[i], tolerance)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
String MLPPTensor3::to_string() {
|
|
String str;
|
|
|
|
str += "[MLPPTensor3: \n";
|
|
|
|
for (int z = 0; z < _size.z; ++z) {
|
|
int z_ofs = _size.x * _size.y * z;
|
|
|
|
str += " [ ";
|
|
|
|
for (int y = 0; y < _size.y; ++y) {
|
|
str += " [ ";
|
|
|
|
for (int x = 0; x < _size.x; ++x) {
|
|
str += String::num(_data[_size.x * y + x + z_ofs]);
|
|
str += " ";
|
|
}
|
|
|
|
str += " ]\n";
|
|
}
|
|
|
|
str += "],\n";
|
|
}
|
|
|
|
str += "]\n";
|
|
|
|
return str;
|
|
}
|
|
|
|
MLPPTensor3::MLPPTensor3() {
|
|
_data = NULL;
|
|
}
|
|
|
|
MLPPTensor3::MLPPTensor3(const MLPPMatrix &p_from) {
|
|
_data = NULL;
|
|
|
|
Size2i mat_size = p_from.size();
|
|
resize(Size3i(mat_size.x, mat_size.y, 1));
|
|
|
|
int ds = p_from.data_size();
|
|
const real_t *ptr = p_from.ptr();
|
|
|
|
for (int i = 0; i < ds; ++i) {
|
|
_data[i] = ptr[i];
|
|
}
|
|
}
|
|
|
|
MLPPTensor3::MLPPTensor3(const Array &p_from) {
|
|
_data = NULL;
|
|
|
|
set_from_mlpp_matrices_array(p_from);
|
|
}
|
|
|
|
MLPPTensor3::~MLPPTensor3() {
|
|
if (_data) {
|
|
reset();
|
|
}
|
|
}
|
|
|
|
std::vector<real_t> MLPPTensor3::to_flat_std_vector() const {
|
|
std::vector<real_t> ret;
|
|
ret.resize(data_size());
|
|
real_t *w = &ret[0];
|
|
memcpy(w, _data, sizeof(real_t) * data_size());
|
|
return ret;
|
|
}
|
|
|
|
void MLPPTensor3::set_from_std_vectors(const std::vector<std::vector<std::vector<real_t>>> &p_from) {
|
|
if (p_from.size() == 0) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
resize(Size3i(p_from[0][0].size(), p_from[0].size(), p_from.size()));
|
|
|
|
if (data_size() == 0) {
|
|
reset();
|
|
return;
|
|
}
|
|
|
|
for (uint32_t z = 0; z < p_from.size(); ++z) {
|
|
const std::vector<std::vector<real_t>> &vxy = p_from[z];
|
|
|
|
for (uint32_t y = 0; y < vxy.size(); ++y) {
|
|
ERR_CONTINUE(vxy.size() != static_cast<uint32_t>(_size.y));
|
|
|
|
const std::vector<real_t> &vx = vxy[y];
|
|
|
|
ERR_CONTINUE(vx.size() != static_cast<uint32_t>(_size.x));
|
|
|
|
for (uint32_t x = 0; x < vx.size(); ++x) {
|
|
element_set(z, y, x, vx[x]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
std::vector<std::vector<std::vector<real_t>>> MLPPTensor3::to_std_vector() {
|
|
std::vector<std::vector<std::vector<real_t>>> ret;
|
|
|
|
ret.resize(_size.z);
|
|
|
|
for (int k = 0; k < _size.z; ++k) {
|
|
ret[k].resize(_size.y);
|
|
|
|
for (int i = 0; i < _size.y; ++i) {
|
|
std::vector<real_t> row;
|
|
|
|
for (int j = 0; j < _size.x; ++j) {
|
|
row.push_back(_data[calculate_index(k, i, j)]);
|
|
}
|
|
|
|
ret[k][i] = row;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
MLPPTensor3::MLPPTensor3(const std::vector<std::vector<std::vector<real_t>>> &p_from) {
|
|
_data = NULL;
|
|
|
|
set_from_std_vectors(p_from);
|
|
}
|
|
|
|
void MLPPTensor3::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("get_data"), &MLPPTensor3::get_data);
|
|
ClassDB::bind_method(D_METHOD("set_data", "data"), &MLPPTensor3::set_data);
|
|
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "data"), "set_data", "get_data");
|
|
|
|
ClassDB::bind_method(D_METHOD("z_slice_add_pool_vector", "row"), &MLPPTensor3::z_slice_add_pool_vector);
|
|
ClassDB::bind_method(D_METHOD("z_slice_add_mlpp_vector", "row"), &MLPPTensor3::z_slice_add_mlpp_vector);
|
|
ClassDB::bind_method(D_METHOD("z_slice_add_mlpp_matrix", "matrix"), &MLPPTensor3::z_slice_add_mlpp_matrix);
|
|
|
|
ClassDB::bind_method(D_METHOD("z_slice_remove", "index"), &MLPPTensor3::z_slice_remove);
|
|
ClassDB::bind_method(D_METHOD("z_slice_remove_unordered", "index"), &MLPPTensor3::z_slice_remove_unordered);
|
|
|
|
ClassDB::bind_method(D_METHOD("z_slice_swap", "index_1", "index_2"), &MLPPTensor3::z_slice_swap);
|
|
|
|
ClassDB::bind_method(D_METHOD("clear"), &MLPPTensor3::clear);
|
|
ClassDB::bind_method(D_METHOD("reset"), &MLPPTensor3::reset);
|
|
ClassDB::bind_method(D_METHOD("empty"), &MLPPTensor3::empty);
|
|
|
|
ClassDB::bind_method(D_METHOD("z_slice_data_size"), &MLPPTensor3::z_slice_data_size);
|
|
ClassDB::bind_method(D_METHOD("z_slice_size"), &MLPPTensor3::z_slice_size);
|
|
|
|
ClassDB::bind_method(D_METHOD("data_size"), &MLPPTensor3::data_size);
|
|
ClassDB::bind_method(D_METHOD("size"), &MLPPTensor3::size);
|
|
|
|
ClassDB::bind_method(D_METHOD("resize", "size"), &MLPPTensor3::resize);
|
|
|
|
ClassDB::bind_method(D_METHOD("shape_set", "size"), &MLPPTensor3::shape_set);
|
|
ClassDB::bind_method(D_METHOD("calculate_index", "index_y", "index_x", "index_z"), &MLPPTensor3::calculate_index);
|
|
ClassDB::bind_method(D_METHOD("calculate_z_slice_index", "index_z"), &MLPPTensor3::calculate_z_slice_index);
|
|
|
|
ClassDB::bind_method(D_METHOD("element_get_index", "index"), &MLPPTensor3::element_get_index);
|
|
ClassDB::bind_method(D_METHOD("element_set_index", "index", "val"), &MLPPTensor3::element_set_index);
|
|
|
|
ClassDB::bind_method(D_METHOD("element_get", "index_y", "index_x", "index_z"), &MLPPTensor3::element_get);
|
|
ClassDB::bind_method(D_METHOD("element_set", "index_y", "index_x", "index_z", "val"), &MLPPTensor3::element_set);
|
|
|
|
ClassDB::bind_method(D_METHOD("row_get_pool_vector", "index_y", "index_z"), &MLPPTensor3::row_get_pool_vector);
|
|
ClassDB::bind_method(D_METHOD("row_get_mlpp_vector", "index_y", "index_z"), &MLPPTensor3::row_get_mlpp_vector);
|
|
ClassDB::bind_method(D_METHOD("row_get_into_mlpp_vector", "index_y", "index_z", "target"), &MLPPTensor3::row_get_into_mlpp_vector);
|
|
|
|
ClassDB::bind_method(D_METHOD("row_set_pool_vector", "index_y", "index_z", "row"), &MLPPTensor3::row_set_pool_vector);
|
|
ClassDB::bind_method(D_METHOD("row_set_mlpp_vector", "index_y", "index_z", "row"), &MLPPTensor3::row_set_mlpp_vector);
|
|
|
|
ClassDB::bind_method(D_METHOD("z_slice_get_pool_vector", "index_z"), &MLPPTensor3::z_slice_get_pool_vector);
|
|
ClassDB::bind_method(D_METHOD("z_slice_get_mlpp_vector", "index_z"), &MLPPTensor3::z_slice_get_mlpp_vector);
|
|
ClassDB::bind_method(D_METHOD("z_slice_get_into_mlpp_vector", "index_z", "target"), &MLPPTensor3::z_slice_get_into_mlpp_vector);
|
|
|
|
ClassDB::bind_method(D_METHOD("z_slice_get_mlpp_matrix", "index_z"), &MLPPTensor3::z_slice_get_mlpp_matrix);
|
|
ClassDB::bind_method(D_METHOD("z_slice_get_into_mlpp_matrix", "index_z", "target"), &MLPPTensor3::z_slice_get_into_mlpp_matrix);
|
|
|
|
ClassDB::bind_method(D_METHOD("z_slice_set_pool_vector", "index_z", "row"), &MLPPTensor3::z_slice_set_pool_vector);
|
|
ClassDB::bind_method(D_METHOD("z_slice_set_mlpp_vector", "index_z", "row"), &MLPPTensor3::z_slice_set_mlpp_vector);
|
|
ClassDB::bind_method(D_METHOD("z_slice_set_mlpp_matrix", "index_z", "mat"), &MLPPTensor3::z_slice_set_mlpp_matrix);
|
|
|
|
ClassDB::bind_method(D_METHOD("x_slice_get_into", "index_x", "target"), &MLPPTensor3::x_slice_get_into);
|
|
ClassDB::bind_method(D_METHOD("x_slice_get", "index_x"), &MLPPTensor3::x_slice_get);
|
|
ClassDB::bind_method(D_METHOD("x_slice_set", "index_x", "mat"), &MLPPTensor3::x_slice_set);
|
|
|
|
ClassDB::bind_method(D_METHOD("y_slice_get_into", "index_y", "target"), &MLPPTensor3::y_slice_get_into);
|
|
ClassDB::bind_method(D_METHOD("y_slice_get", "index_y"), &MLPPTensor3::y_slice_get);
|
|
ClassDB::bind_method(D_METHOD("y_slice_set", "index_y", "mat"), &MLPPTensor3::y_slice_set);
|
|
|
|
ClassDB::bind_method(D_METHOD("z_slices_add_image", "img", "channels"), &MLPPTensor3::z_slices_add_image, IMAGE_CHANNEL_FLAG_RGBA);
|
|
|
|
ClassDB::bind_method(D_METHOD("z_slice_get_image", "index_z"), &MLPPTensor3::z_slice_get_image);
|
|
ClassDB::bind_method(D_METHOD("z_slices_get_image", "index_r", "index_g", "index_b", "index_a"), &MLPPTensor3::z_slices_get_image, -1, -1, -1, -1);
|
|
|
|
ClassDB::bind_method(D_METHOD("z_slice_get_into_image", "target", "index_z", "target_channels"), &MLPPTensor3::z_slice_get_into_image, IMAGE_CHANNEL_FLAG_RGB);
|
|
ClassDB::bind_method(D_METHOD("z_slices_get_into_image", "target", "index_r", "index_g", "index_b", "index_a"), &MLPPTensor3::z_slices_get_into_image, -1, -1, -1, -1);
|
|
|
|
ClassDB::bind_method(D_METHOD("z_slice_set_image", "img", "index_z", "image_channel_flag"), &MLPPTensor3::z_slice_set_image, IMAGE_CHANNEL_FLAG_R);
|
|
ClassDB::bind_method(D_METHOD("z_slices_set_image", "img", "index_r", "index_g", "index_b", "index_a"), &MLPPTensor3::z_slices_set_image);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_from_image", "img", "channels"), &MLPPTensor3::set_from_image, IMAGE_CHANNEL_FLAG_RGBA);
|
|
|
|
ClassDB::bind_method(D_METHOD("x_slice_get_image", "index_x"), &MLPPTensor3::x_slice_get_image);
|
|
ClassDB::bind_method(D_METHOD("x_slice_get_into_image", "target", "index_x", "target_channels"), &MLPPTensor3::x_slice_get_into_image, IMAGE_CHANNEL_FLAG_RGB);
|
|
ClassDB::bind_method(D_METHOD("x_slice_set_image", "img", "index_x", "image_channel_flag"), &MLPPTensor3::x_slice_set_image, IMAGE_CHANNEL_FLAG_R);
|
|
|
|
ClassDB::bind_method(D_METHOD("y_slice_get_image", "index_x"), &MLPPTensor3::y_slice_get_image);
|
|
ClassDB::bind_method(D_METHOD("y_slice_get_into_image", "target", "index_x", "target_channels"), &MLPPTensor3::y_slice_get_into_image, IMAGE_CHANNEL_FLAG_RGB);
|
|
ClassDB::bind_method(D_METHOD("y_slice_set_image", "img", "index_x", "image_channel_flag"), &MLPPTensor3::y_slice_set_image, IMAGE_CHANNEL_FLAG_R);
|
|
|
|
ClassDB::bind_method(D_METHOD("fill", "val"), &MLPPTensor3::fill);
|
|
|
|
ClassDB::bind_method(D_METHOD("to_flat_pool_vector"), &MLPPTensor3::to_flat_pool_vector);
|
|
ClassDB::bind_method(D_METHOD("to_flat_byte_array"), &MLPPTensor3::to_flat_byte_array);
|
|
|
|
ClassDB::bind_method(D_METHOD("duplicate_fast"), &MLPPTensor3::duplicate_fast);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_from_mlpp_tensor3", "from"), &MLPPTensor3::set_from_mlpp_tensor3);
|
|
ClassDB::bind_method(D_METHOD("set_from_mlpp_matrix", "from"), &MLPPTensor3::set_from_mlpp_matrix);
|
|
ClassDB::bind_method(D_METHOD("set_from_mlpp_vectors_array", "from"), &MLPPTensor3::set_from_mlpp_vectors_array);
|
|
ClassDB::bind_method(D_METHOD("set_from_mlpp_matrices_array", "from"), &MLPPTensor3::set_from_mlpp_matrices_array);
|
|
|
|
ClassDB::bind_method(D_METHOD("is_equal_approx", "with", "tolerance"), &MLPPTensor3::is_equal_approx, CMP_EPSILON);
|
|
|
|
ClassDB::bind_method(D_METHOD("add", "B"), &MLPPTensor3::add);
|
|
ClassDB::bind_method(D_METHOD("addn", "B"), &MLPPTensor3::addn);
|
|
ClassDB::bind_method(D_METHOD("addb", "A", "B"), &MLPPTensor3::addb);
|
|
|
|
ClassDB::bind_method(D_METHOD("sub", "B"), &MLPPTensor3::sub);
|
|
ClassDB::bind_method(D_METHOD("subn", "B"), &MLPPTensor3::subn);
|
|
ClassDB::bind_method(D_METHOD("subb", "A", "B"), &MLPPTensor3::subb);
|
|
|
|
ClassDB::bind_method(D_METHOD("hadamard_product", "B"), &MLPPTensor3::hadamard_product);
|
|
ClassDB::bind_method(D_METHOD("hadamard_productn", "B"), &MLPPTensor3::hadamard_productn);
|
|
ClassDB::bind_method(D_METHOD("hadamard_productb", "A", "B"), &MLPPTensor3::hadamard_productb);
|
|
|
|
ClassDB::bind_method(D_METHOD("division_element_wise", "B"), &MLPPTensor3::division_element_wise);
|
|
ClassDB::bind_method(D_METHOD("division_element_wisen", "B"), &MLPPTensor3::division_element_wisen);
|
|
ClassDB::bind_method(D_METHOD("division_element_wiseb", "A", "B"), &MLPPTensor3::division_element_wiseb);
|
|
|
|
ClassDB::bind_method(D_METHOD("scalar_multiply", "scalar"), &MLPPTensor3::scalar_multiply);
|
|
ClassDB::bind_method(D_METHOD("scalar_multiplyn", "scalar"), &MLPPTensor3::scalar_multiplyn);
|
|
ClassDB::bind_method(D_METHOD("scalar_multiplyb", "scalar", "A"), &MLPPTensor3::scalar_multiplyb);
|
|
|
|
ClassDB::bind_method(D_METHOD("scalar_add", "scalar"), &MLPPTensor3::scalar_add);
|
|
ClassDB::bind_method(D_METHOD("scalar_addn", "scalar"), &MLPPTensor3::scalar_addn);
|
|
ClassDB::bind_method(D_METHOD("scalar_addb", "scalar", "A"), &MLPPTensor3::scalar_addb);
|
|
|
|
ClassDB::bind_method(D_METHOD("exponentiate", "p"), &MLPPTensor3::exponentiate);
|
|
ClassDB::bind_method(D_METHOD("exponentiaten", "p"), &MLPPTensor3::exponentiaten);
|
|
ClassDB::bind_method(D_METHOD("exponentiateb", "A", "p"), &MLPPTensor3::exponentiateb);
|
|
|
|
ClassDB::bind_method(D_METHOD("sqrt"), &MLPPTensor3::sqrt);
|
|
ClassDB::bind_method(D_METHOD("sqrtn"), &MLPPTensor3::sqrtn);
|
|
ClassDB::bind_method(D_METHOD("sqrtb", "A"), &MLPPTensor3::sqrtb);
|
|
|
|
ClassDB::bind_method(D_METHOD("abs"), &MLPPTensor3::abs);
|
|
ClassDB::bind_method(D_METHOD("absn"), &MLPPTensor3::absn);
|
|
ClassDB::bind_method(D_METHOD("absb", "A"), &MLPPTensor3::absb);
|
|
|
|
ClassDB::bind_method(D_METHOD("max", "B"), &MLPPTensor3::max);
|
|
ClassDB::bind_method(D_METHOD("maxn", "B"), &MLPPTensor3::maxn);
|
|
ClassDB::bind_method(D_METHOD("maxb", "A", "B"), &MLPPTensor3::maxb);
|
|
|
|
ClassDB::bind_method(D_METHOD("flatten"), &MLPPTensor3::flatten);
|
|
ClassDB::bind_method(D_METHOD("flatteno", "out"), &MLPPTensor3::flatteno);
|
|
|
|
BIND_ENUM_CONSTANT(IMAGE_CHANNEL_FLAG_R);
|
|
BIND_ENUM_CONSTANT(IMAGE_CHANNEL_FLAG_G);
|
|
BIND_ENUM_CONSTANT(IMAGE_CHANNEL_FLAG_B);
|
|
BIND_ENUM_CONSTANT(IMAGE_CHANNEL_FLAG_A);
|
|
|
|
BIND_ENUM_CONSTANT(IMAGE_CHANNEL_FLAG_NONE);
|
|
BIND_ENUM_CONSTANT(IMAGE_CHANNEL_FLAG_RG);
|
|
BIND_ENUM_CONSTANT(IMAGE_CHANNEL_FLAG_RGB);
|
|
BIND_ENUM_CONSTANT(IMAGE_CHANNEL_FLAG_GB);
|
|
BIND_ENUM_CONSTANT(IMAGE_CHANNEL_FLAG_GBA);
|
|
BIND_ENUM_CONSTANT(IMAGE_CHANNEL_FLAG_BA);
|
|
BIND_ENUM_CONSTANT(IMAGE_CHANNEL_FLAG_RGBA);
|
|
}
|