Commit 02885b8b authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

added Mat::push_back, pop_back and related operations; enabled…

added Mat::push_back, pop_back and related operations; enabled reading/writing/creating/copying matrices with zero dimensions.
parent bddaa00e
......@@ -94,6 +94,7 @@ class CV_EXPORTS VectorArg;
class CV_EXPORTS MatArg;
class CV_EXPORTS MatConstIterator;
template<typename _Tp> class CV_EXPORTS Mat_;
template<typename _Tp> class CV_EXPORTS MatIterator_;
template<typename _Tp> class CV_EXPORTS MatConstIterator_;
template<typename _Tp> class CV_EXPORTS MatCommaInitializer_;
......@@ -1600,7 +1601,22 @@ public:
void deallocate();
//! internal use function; properly re-allocates _size, _step arrays
void copySize(const Mat& m);
//! reserves enough space to fit sz hyper-planes
void reserve(size_t sz);
//! resizes matrix to the specified number of hyper-planes
void resize(size_t sz);
//! resizes matrix to the specified number of hyper-planes; initializes the newly added elements
void resize(size_t sz, const Scalar& s);
//! internal function
void push_back_(const void* elem);
//! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat)
template<typename _Tp> void push_back(const _Tp& elem);
template<typename _Tp> void push_back(const Mat_<_Tp>& elem);
void push_back(const Mat& m);
//! removes several hyper-planes from bottom of the matrix
void pop_back(size_t nelems);
//! locates matrix header within a parent matrix. See below
void locateROI( Size& wholeSize, Point& ofs ) const;
//! moves/resizes the current matrix ROI inside the parent matrix.
......@@ -1626,6 +1642,10 @@ public:
// (i.e. when there are no gaps between successive rows).
// similar to CV_IS_MAT_CONT(cvmat->type)
bool isContinuous() const;
//! returns true if the matrix is a submatrix of another matrix
bool isSubmatrix() const;
//! returns element size in bytes,
// similar to CV_ELEM_SIZE(cvmat->type)
size_t elemSize() const;
......@@ -1707,7 +1727,7 @@ public:
template<typename _Tp> MatConstIterator_<_Tp> begin() const;
template<typename _Tp> MatConstIterator_<_Tp> end() const;
enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG };
enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, SUBMATRIX_FLAG=CV_SUBMAT_FLAG };
/*! includes several bit-fields:
- the magic signature
......@@ -1730,6 +1750,8 @@ public:
//! helper fields used in locateROI and adjustROI
uchar* datastart;
uchar* dataend;
uchar* datalimit;
//! custom allocator
ArrayAllocator* allocator;
......@@ -2252,13 +2274,13 @@ CV_EXPORTS void fillConvexPoly(Mat& img, CV_CARRAY(npts) const Point* pts, int n
int shift=0);
//! fills an area bounded by one or more polygons
CV_EXPORTS void fillPoly(Mat& img, CV_CARRAY(ncontours) const Point** pts,
CV_EXPORTS void fillPoly(Mat& img, CV_CARRAY(ncontours.npts) const Point** pts,
CV_CARRAY(ncontours) const int* npts, int ncontours,
const Scalar& color, int lineType=8, int shift=0,
Point offset=Point() );
//! draws one or more polygonal curves
CV_EXPORTS void polylines(Mat& img, CV_CARRAY(ncontours) const Point** pts, CV_CARRAY(ncontours) const int* npts,
CV_EXPORTS void polylines(Mat& img, CV_CARRAY(ncontours.npts) const Point** pts, CV_CARRAY(ncontours) const int* npts,
int ncontours, bool isClosed, const Scalar& color,
int thickness=1, int lineType=8, int shift=0 );
......
This diff is collapsed.
......@@ -2692,7 +2692,6 @@ operator << ( FileStorage& fs, const vector<_Tp>& vec )
}
CV_EXPORTS void write( FileStorage& fs, const string& name, const Mat& value );
CV_EXPORTS void write( FileStorage& fs, const string& name, const MatND& value );
CV_EXPORTS void write( FileStorage& fs, const string& name, const SparseMat& value );
template<typename _Tp> static inline FileStorage& operator << (FileStorage& fs, const _Tp& value)
......
......@@ -601,9 +601,9 @@ IplConvKernelFP;
#define CV_MAT_CONT_FLAG (1 << CV_MAT_CONT_FLAG_SHIFT)
#define CV_IS_MAT_CONT(flags) ((flags) & CV_MAT_CONT_FLAG)
#define CV_IS_CONT_MAT CV_IS_MAT_CONT
#define CV_MAT_TEMP_FLAG_SHIFT 15
#define CV_MAT_TEMP_FLAG (1 << CV_MAT_TEMP_FLAG_SHIFT)
#define CV_IS_TEMP_MAT(flags) ((flags) & CV_MAT_TEMP_FLAG)
#define CV_SUBMAT_FLAG_SHIFT 15
#define CV_SUBMAT_FLAG (1 << CV_SUBMAT_FLAG_SHIFT)
#define CV_IS_SUBMAT(flags) ((flags) & CV_MAT_SUBMAT_FLAG)
#define CV_MAGIC_MASK 0xFFFF0000
#define CV_MAT_MAGIC_VAL 0x42420000
......@@ -653,6 +653,11 @@ CvMat;
(((const CvMat*)(mat))->type & CV_MAGIC_MASK) == CV_MAT_MAGIC_VAL && \
((const CvMat*)(mat))->cols > 0 && ((const CvMat*)(mat))->rows > 0)
#define CV_IS_MAT_HDR_Z(mat) \
((mat) != NULL && \
(((const CvMat*)(mat))->type & CV_MAGIC_MASK) == CV_MAT_MAGIC_VAL && \
((const CvMat*)(mat))->cols >= 0 && ((const CvMat*)(mat))->rows >= 0)
#define CV_IS_MAT(mat) \
(CV_IS_MAT_HDR(mat) && ((const CvMat*)(mat))->data.ptr != NULL)
......
......@@ -109,7 +109,7 @@ cvCreateMatHeader( int rows, int cols, int type )
{
type = CV_MAT_TYPE(type);
if( rows <= 0 || cols <= 0 )
if( rows < 0 || cols <= 0 )
CV_Error( CV_StsBadSize, "Non-positive width or height" );
int min_step = CV_ELEM_SIZE(type)*cols;
......@@ -142,7 +142,7 @@ cvInitMatHeader( CvMat* arr, int rows, int cols,
if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX )
CV_Error( CV_BadNumChannels, "" );
if( rows <= 0 || cols <= 0 )
if( rows < 0 || cols <= 0 )
CV_Error( CV_StsBadSize, "Non-positive cols or rows" );
type = CV_MAT_TYPE( type );
......@@ -175,12 +175,6 @@ cvInitMatHeader( CvMat* arr, int rows, int cols,
}
#undef CV_IS_MAT_HDR_Z
#define CV_IS_MAT_HDR_Z(mat) \
((mat) != NULL && \
(((const CvMat*)(mat))->type & CV_MAGIC_MASK) == CV_MAT_MAGIC_VAL && \
((const CvMat*)(mat))->cols >= 0 && ((const CvMat*)(mat))->rows >= 0)
// Deallocates the CvMat structure and underlying data
CV_IMPL void
cvReleaseMat( CvMat** array )
......@@ -248,7 +242,7 @@ cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,
for( int i = dims - 1; i >= 0; i-- )
{
if( sizes[i] <= 0 )
if( sizes[i] < 0 )
CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" );
mat->dim[i].size = sizes[i];
if( step > INT_MAX )
......@@ -795,12 +789,15 @@ icvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval )
CV_IMPL void
cvCreateData( CvArr* arr )
{
if( CV_IS_MAT_HDR( arr ))
if( CV_IS_MAT_HDR_Z( arr ))
{
size_t step, total_size;
CvMat* mat = (CvMat*)arr;
step = mat->step;
if( mat->rows == 0 || mat->cols == 0 )
return;
if( mat->data.ptr != 0 )
CV_Error( CV_StsError, "Data is already allocated" );
......@@ -849,6 +846,9 @@ cvCreateData( CvArr* arr )
CvMatND* mat = (CvMatND*)arr;
int i;
size_t total_size = CV_ELEM_SIZE(mat->type);
if( mat->dim[0].size == 0 )
return;
if( mat->data.ptr != 0 )
CV_Error( CV_StsError, "Data is already allocated" );
......@@ -1207,7 +1207,7 @@ cvGetSize( const CvArr* arr )
{
CvSize size = { 0, 0 };
if( CV_IS_MAT_HDR( arr ))
if( CV_IS_MAT_HDR_Z( arr ))
{
CvMat *mat = (CvMat*)arr;
......
......@@ -166,38 +166,45 @@ static SetMaskFunc setMaskFuncTab[] =
/* dst = src */
void Mat::copyTo( Mat& dst ) const
{
if( data == dst.data )
if( data == dst.data && data != 0 )
return;
if( dims > 2 )
{
dst.create( dims, size, type() );
const Mat* arrays[] = { this, &dst, 0 };
Mat planes[2];
NAryMatIterator it(arrays, planes);
CV_DbgAssert(it.planes[0].isContinuous() &&
it.planes[1].isContinuous());
size_t planeSize = it.planes[0].elemSize()*it.planes[0].rows*it.planes[0].cols;
for( int i = 0; i < it.nplanes; i++, ++it )
memcpy(it.planes[1].data, it.planes[0].data, planeSize);
if( total() != 0 )
{
const Mat* arrays[] = { this, &dst, 0 };
Mat planes[2];
NAryMatIterator it(arrays, planes);
CV_DbgAssert(it.planes[0].isContinuous() &&
it.planes[1].isContinuous());
size_t planeSize = it.planes[0].elemSize()*it.planes[0].rows*it.planes[0].cols;
for( int i = 0; i < it.nplanes; i++, ++it )
memcpy(it.planes[1].data, it.planes[0].data, planeSize);
}
return;
}
dst.create( rows, cols, type() );
Size sz = size();
const uchar* sptr = data;
uchar* dptr = dst.data;
sz.width *= (int)elemSize();
if( isContinuous() && dst.isContinuous() )
if( rows > 0 && cols > 0 )
{
sz.width *= sz.height;
sz.height = 1;
}
const uchar* sptr = data;
uchar* dptr = dst.data;
for( ; sz.height--; sptr += step, dptr += dst.step )
memcpy( dptr, sptr, sz.width );
size_t width = sz.width*elemSize();
if( isContinuous() && dst.isContinuous() )
{
width *= sz.height;
sz.height = 1;
}
for( ; sz.height--; sptr += step, dptr += dst.step )
memcpy( dptr, sptr, width );
}
}
void Mat::copyTo( Mat& dst, const Mat& mask ) const
......
This diff is collapsed.
......@@ -3328,7 +3328,7 @@ cvGetFileNodeName( const CvFileNode* file_node )
static int
icvIsMat( const void* ptr )
{
return CV_IS_MAT_HDR(ptr);
return CV_IS_MAT_HDR_Z(ptr);
}
static void
......@@ -3340,7 +3340,7 @@ icvWriteMat( CvFileStorage* fs, const char* name,
CvSize size;
int y;
assert( CV_IS_MAT(mat) );
assert( CV_IS_MAT_HDR_Z(mat) );
cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_MAT );
cvWriteInt( fs, "rows", mat->rows );
......@@ -3349,14 +3349,17 @@ icvWriteMat( CvFileStorage* fs, const char* name,
cvStartWriteStruct( fs, "data", CV_NODE_SEQ + CV_NODE_FLOW );
size = cvGetSize(mat);
if( CV_IS_MAT_CONT(mat->type) )
if( size.height > 0 && size.width > 0 && mat->data.ptr )
{
size.width *= size.height;
size.height = 1;
}
if( CV_IS_MAT_CONT(mat->type) )
{
size.width *= size.height;
size.height = 1;
}
for( y = 0; y < size.height; y++ )
cvWriteRawData( fs, mat->data.ptr + y*mat->step, size.width, dt );
for( y = 0; y < size.height; y++ )
cvWriteRawData( fs, mat->data.ptr + y*mat->step, size.width, dt );
}
cvEndWriteStruct( fs );
cvEndWriteStruct( fs );
}
......@@ -3379,11 +3382,11 @@ icvReadMat( CvFileStorage* fs, CvFileNode* node )
CvFileNode* data;
int rows, cols, elem_type;
rows = cvReadIntByName( fs, node, "rows", 0 );
cols = cvReadIntByName( fs, node, "cols", 0 );
rows = cvReadIntByName( fs, node, "rows", -1 );
cols = cvReadIntByName( fs, node, "cols", -1 );
dt = cvReadStringByName( fs, node, "dt", 0 );
if( rows == 0 || cols == 0 || dt == 0 )
if( rows < 0 || cols < 0 || dt < 0 )
CV_Error( CV_StsError, "Some of essential matrix attributes are absent" );
elem_type = icvDecodeSimpleFormat( dt );
......@@ -3391,13 +3394,19 @@ icvReadMat( CvFileStorage* fs, CvFileNode* node )
data = cvGetFileNodeByName( fs, node, "data" );
if( !data )
CV_Error( CV_StsError, "The matrix data is not found in file storage" );
if( icvFileNodeSeqLen( data ) != rows*cols*CV_MAT_CN(elem_type) )
int nelems = icvFileNodeSeqLen( data );
if( nelems > 0 && nelems != rows*cols*CV_MAT_CN(elem_type) )
CV_Error( CV_StsUnmatchedSizes,
"The matrix size does not match to the number of stored elements" );
mat = cvCreateMat( rows, cols, elem_type );
cvReadRawData( fs, data, mat->data.ptr, dt );
"The matrix size does not match to the number of stored elements" );
if( nelems > 0 )
{
mat = cvCreateMat( rows, cols, elem_type );
cvReadRawData( fs, data, mat->data.ptr, dt );
}
else
mat = cvCreateMatHeader( rows, cols, elem_type );
ptr = mat;
return ptr;
......@@ -3409,7 +3418,7 @@ icvReadMat( CvFileStorage* fs, CvFileNode* node )
static int
icvIsMatND( const void* ptr )
{
return CV_IS_MATND(ptr);
return CV_IS_MATND_HDR(ptr);
}
......@@ -3417,13 +3426,13 @@ static void
icvWriteMatND( CvFileStorage* fs, const char* name,
const void* struct_ptr, CvAttrList /*attr*/ )
{
void* mat = (void*)struct_ptr;
CvMatND* mat = (CvMatND*)struct_ptr;
CvMatND stub;
CvNArrayIterator iterator;
int dims, sizes[CV_MAX_DIM];
char dt[16];
assert( CV_IS_MATND(mat) );
assert( CV_IS_MATND_HDR(mat) );
cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_MATND );
dims = cvGetDims( mat, sizes );
......@@ -3433,11 +3442,14 @@ icvWriteMatND( CvFileStorage* fs, const char* name,
cvWriteString( fs, "dt", icvEncodeFormat( cvGetElemType(mat), dt ), 0 );
cvStartWriteStruct( fs, "data", CV_NODE_SEQ + CV_NODE_FLOW );
cvInitNArrayIterator( 1, &mat, 0, &stub, &iterator );
if( mat->dim[0].size > 0 && mat->data.ptr )
{
cvInitNArrayIterator( 1, (CvArr**)&mat, 0, &stub, &iterator );
do
cvWriteRawData( fs, iterator.ptr[0], iterator.size.width, dt );
while( cvNextNArraySlice( &iterator ));
do
cvWriteRawData( fs, iterator.ptr[0], iterator.size.width, dt );
while( cvNextNArraySlice( &iterator ));
}
cvEndWriteStruct( fs );
cvEndWriteStruct( fs );
}
......@@ -3472,16 +3484,25 @@ icvReadMatND( CvFileStorage* fs, CvFileNode* node )
data = cvGetFileNodeByName( fs, node, "data" );
if( !data )
CV_Error( CV_StsError, "The matrix data is not found in file storage" );
for( total_size = CV_MAT_CN(elem_type), i = 0; i < dims; i++ )
total_size *= sizes[i];
if( icvFileNodeSeqLen( data ) != total_size )
int nelems = icvFileNodeSeqLen( data );
if( nelems > 0 && nelems != total_size )
CV_Error( CV_StsUnmatchedSizes,
"The matrix size does not match to the number of stored elements" );
mat = cvCreateMatND( dims, sizes, elem_type );
cvReadRawData( fs, data, mat->data.ptr, dt );
"The matrix size does not match to the number of stored elements" );
if( nelems > 0 )
{
mat = cvCreateMatND( dims, sizes, elem_type );
cvReadRawData( fs, data, mat->data.ptr, dt );
}
else
mat = cvCreateMatNDHeader( dims, sizes, elem_type );
ptr = mat;
return ptr;
......@@ -5304,12 +5325,12 @@ void read( const FileNode& node, Mat& mat, const Mat& default_mat )
return;
}
void* obj = cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node);
if(CV_IS_MAT(obj))
if(CV_IS_MAT_HDR_Z(obj))
{
Mat((const CvMat*)obj).copyTo(mat);
cvReleaseMat((CvMat**)&obj);
}
else if(CV_IS_MATND(obj))
else if(CV_IS_MATND_HDR(obj))
{
Mat((const CvMatND*)obj).copyTo(mat);
cvReleaseMatND((CvMatND**)&obj);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment