50 #include <visp3/core/vpConfig.h>
51 #include <visp3/core/vpException.h>
158 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
175 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
192 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
198 resize(r, c,
false,
false);
202 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
220 resize(1, static_cast<unsigned int>(list.size()),
false,
false);
221 std::copy(list.begin(), list.end(),
data);
224 explicit vpArray2D<Type>(
unsigned int nrows,
unsigned int ncols,
const std::initializer_list<Type> &list)
227 if (nrows * ncols != static_cast<unsigned int>(list.size())) {
228 std::ostringstream oss;
229 oss <<
"Cannot create a vpArray2D of size (" << nrows <<
", " << ncols
230 <<
") with a list of size " << list.size();
234 resize(nrows, ncols,
false,
false);
235 std::copy(list.begin(), list.end(),
data);
240 unsigned int nrows = static_cast<unsigned int>(lists.size()), ncols = 0;
241 for (
auto& l : lists) {
242 if (static_cast<unsigned int>(l.size()) > ncols) {
243 ncols = static_cast<unsigned int>(l.size());
247 resize(nrows, ncols,
false,
false);
248 auto it = lists.begin();
249 for (
unsigned int i = 0; i <
rowNum; i++, ++it) {
250 std::copy(it->begin(), it->end(),
rowPtrs[i]);
305 void resize(
unsigned int nrows,
unsigned int ncols,
bool flagNullify =
true,
bool recopy_ =
true)
308 if (flagNullify && this->data != NULL) {
309 memset(this->data, 0, this->dsize *
sizeof(Type));
312 bool recopy = !flagNullify && recopy_;
313 const bool recopyNeeded = (ncols != this->colNum && this->colNum > 0 && ncols > 0 && (!flagNullify || recopy));
314 Type *copyTmp = NULL;
315 unsigned int rowTmp = 0, colTmp = 0;
319 if (recopyNeeded && this->data != NULL) {
320 copyTmp =
new Type[this->
dsize];
321 memcpy(copyTmp, this->data,
sizeof(Type) * this->dsize);
327 this->dsize = nrows * ncols;
328 this->data = (Type *)realloc(this->data, this->dsize *
sizeof(Type));
329 if ((NULL == this->data) && (0 != this->
dsize)) {
330 if (copyTmp != NULL) {
336 this->rowPtrs = (Type **)realloc(this->rowPtrs, nrows *
sizeof(Type *));
337 if ((NULL == this->rowPtrs) && (0 != this->
dsize)) {
338 if (copyTmp != NULL) {
342 "Memory allocation error when allocating 2D array rowPtrs"));
348 for (
unsigned int i = 0; i <
dsize; i += ncols) {
349 *t_++ = this->data + i;
353 this->rowNum = nrows;
354 this->colNum = ncols;
358 memset(this->data, 0, (
size_t)(this->dsize) *
sizeof(Type));
359 }
else if (recopyNeeded && this->rowPtrs != NULL) {
361 unsigned int minRow = (this->rowNum < rowTmp) ? this->rowNum : rowTmp;
362 unsigned int minCol = (this->colNum < colTmp) ? this->colNum : colTmp;
363 for (
unsigned int i = 0; i < this->
rowNum; ++i) {
364 for (
unsigned int j = 0; j < this->
colNum; ++j) {
365 if ((minRow > i) && (minCol > j)) {
366 (*this)[i][j] = copyTmp[i * colTmp + j];
374 if (copyTmp != NULL) {
380 void reshape(
unsigned int nrows,
unsigned int ncols)
387 if (nrows * ncols !=
dsize) {
388 std::ostringstream oss;
389 oss <<
"Cannot reshape array of total size " <<
dsize
390 <<
" into shape (" << nrows <<
", " << ncols <<
")";
396 rowPtrs = reinterpret_cast<Type **>(realloc(
rowPtrs, nrows *
sizeof(Type *)));
399 for (
unsigned int i = 0; i <
dsize; i += ncols) {
432 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
435 if (
this != &other) {
447 other.rowPtrs = NULL;
457 if (
dsize != static_cast<unsigned int>(list.size())) {
458 resize(1, static_cast<unsigned int>(list.size()),
false,
false);
460 std::copy(list.begin(), list.end(),
data);
467 unsigned int nrows = static_cast<unsigned int>(lists.size()), ncols = 0;
468 for (
auto& l : lists) {
469 if (static_cast<unsigned int>(l.size()) > ncols) {
470 ncols = static_cast<unsigned int>(l.size());
474 resize(nrows, ncols,
false,
false);
475 auto it = lists.begin();
476 for (
unsigned int i = 0; i <
rowNum; i++, ++it) {
477 std::copy(it->begin(), it->end(),
rowPtrs[i]);
496 if (A.
data == NULL || A.
size() == 0) {
499 std::ios_base::fmtflags original_flags = s.flags();
502 for (
unsigned int i = 0; i < A.
getRows(); i++) {
503 for (
unsigned int j = 0; j < A.
getCols() - 1; j++) {
509 if (i < A.getRows() - 1) {
514 s.flags(original_flags);
541 static bool load(
const std::string &filename,
vpArray2D<Type> &A,
bool binary =
false,
char *header = NULL)
546 file.open(filename.c_str(), std::fstream::in);
549 file.open(filename.c_str(), std::fstream::in | std::fstream::binary);
559 bool headerIsDecoded =
false;
561 std::streampos pos = file.tellg();
563 file.getline(line, 256);
564 std::string prefix(
"# ");
565 std::string line_(line);
566 if (line_.compare(0, 2, prefix.c_str()) == 0) {
573 h += line_.substr(2);
576 file.seekg(pos, file.beg);
577 headerIsDecoded =
true;
579 }
while (!headerIsDecoded);
581 if (header != NULL) {
582 #if defined(__MINGW32__) || \
583 !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
584 sprintf(header,
"%s", h.c_str());
586 _snprintf_s(header, h.size() + 1, _TRUNCATE,
"%s", h.c_str());
590 unsigned int rows, cols;
594 if (rows >= (std::numeric_limits<unsigned int>::max)() || cols >= (std::numeric_limits<unsigned int>::max)()) {
601 for (
unsigned int i = 0; i < rows; i++) {
602 for (
unsigned int j = 0; j < cols; j++) {
615 if (header != NULL) {
616 #if defined(__MINGW32__) || \
617 !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
618 sprintf(header,
"%s", h.c_str());
620 _snprintf_s(header, h.size() + 1, _TRUNCATE,
"%s", h.c_str());
624 unsigned int rows, cols;
625 file.read((
char *)&rows,
sizeof(
unsigned int));
626 file.read((
char *)&cols,
sizeof(
unsigned int));
630 for (
unsigned int i = 0; i < rows; i++) {
631 for (
unsigned int j = 0; j < cols; j++) {
632 file.read((
char *)&value,
sizeof(Type));
657 file.open(filename.c_str(), std::fstream::in);
664 unsigned int rows = 0, cols = 0;
666 std::string line, subs;
667 bool inheader =
true;
668 unsigned int i = 0, j;
669 unsigned int lineStart = 0;
671 while (getline(file, line)) {
673 if (rows == 0 && line.compare(0, 5,
"rows:") == 0) {
674 std::stringstream ss(line);
677 }
else if (cols == 0 && line.compare(0, 5,
"cols:") == 0) {
678 std::stringstream ss(line);
681 }
else if (line.compare(0, 5,
"data:") == 0) {
691 if (rows == 0 || cols == 0) {
697 lineStart = (
unsigned int)line.find(
"[") + 1;
699 std::stringstream ss(line.substr(lineStart, line.find(
"]") - lineStart));
701 while (getline(ss, subs,
',')) {
702 A[i][j++] = atof(subs.c_str());
708 if (header != NULL) {
709 std::string h_ = h.substr(0, h.size() - 1);
710 #if defined(__MINGW32__) || \
711 !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
712 sprintf(header,
"%s", h_.c_str());
714 _snprintf_s(header, h_.size() + 1, _TRUNCATE,
"%s", h_.c_str());
738 static bool save(
const std::string &filename,
const vpArray2D<Type> &A,
bool binary =
false,
739 const char *header =
"")
744 file.open(filename.c_str(), std::fstream::out);
747 file.open(filename.c_str(), std::fstream::out | std::fstream::binary);
758 while (header[i] !=
'\0') {
760 if (header[i] ==
'\n') {
767 file << A << std::endl;
770 while (header[headerSize] !=
'\0') {
773 file.write(header, (
size_t)headerSize + (
size_t)1);
774 unsigned int matrixSize;
776 file.write((
char *)&matrixSize,
sizeof(
unsigned int));
778 file.write((
char *)&matrixSize,
sizeof(
unsigned int));
780 for (
unsigned int i = 0; i < A.
getRows(); i++) {
781 for (
unsigned int j = 0; j < A.
getCols(); j++) {
783 file.write((
char *)&value,
sizeof(Type));
835 file.open(filename.c_str(), std::fstream::out);
843 bool inIndent =
false;
844 std::string indent =
"";
845 bool checkIndent =
true;
846 while (header[i] !=
'\0') {
850 if (header[i] ==
' ') {
853 else if (indent.length() > 0) {
857 if (header[i] ==
'\n' || (inIndent && header[i] ==
' ')) {
870 file <<
"rows: " << A.
getRows() << std::endl;
871 file <<
"cols: " << A.
getCols() << std::endl;
873 if (indent.length() == 0) {
877 file <<
"data: " << std::endl;
879 for (i = 0; i < A.
getRows(); ++i) {
880 file << indent <<
"- [";
881 for (j = 0; j < A.
getCols() - 1; ++j) {
882 file << A[i][j] <<
", ";
884 file << A[i][j] <<
"]" << std::endl;
898 Type *dataptr = data;
901 for (
unsigned int i = 0; i < dsize - 1; i++) {
902 if (*dataptr < min) {
915 Type *dataptr = data;
918 for (
unsigned int i = 0; i < dsize - 1; i++) {
919 if (*dataptr > max) {
940 out.
resize(rowNum, colNum,
false);
942 for (
unsigned int i = 0; i < dsize; i++) {
955 for (
unsigned int i = 0; i < A.
size(); i++) {
956 if (data[i] != A.
data[i]) {
970 for (
unsigned int i = 0; i < A.
size(); i++) {
971 if (fabs(
data[i] - A.
data[i]) > std::numeric_limits<double>::epsilon()) {
985 for (
unsigned int i = 0; i < A.
size(); i++) {
986 if (fabsf(data[i] - A.
data[i]) > std::numeric_limits<float>::epsilon()) {
996 return !(*
this == A);