Cv_iplCreateROI createROI,
Cv_iplCloneImage cloneImage )
{
- if( !createHeader || !allocateData || !deallocate || !createROI || !cloneImage )
- {
- if( createHeader || allocateData || deallocate || createROI || cloneImage )
- CV_Error( CV_StsBadArg, "Either all the pointers should be null or "
- "they all should be non-null" );
- }
+ int count = (createHeader != 0) + (allocateData != 0) + (deallocate != 0) +
+ (createROI != 0) + (cloneImage != 0);
+
+ if( count != 0 && count != 5 )
+ CV_Error( CV_StsBadArg, "Either all the pointers should be null or "
+ "they all should be non-null" );
CvIPL.createHeader = createHeader;
CvIPL.allocateData = allocateData;
CvMat* arr = (CvMat*)cvAlloc( sizeof(*arr));
- arr->step = rows == 1 ? 0 : cvAlign(min_step, CV_DEFAULT_MAT_ROW_ALIGN);
- arr->type = CV_MAT_MAGIC_VAL | type |
- (arr->step == 0 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0);
+ arr->step = min_step;
+ arr->type = CV_MAT_MAGIC_VAL | type | CV_MAT_CONT_FLAG;
arr->rows = rows;
arr->cols = cols;
arr->data.ptr = 0;
arr->refcount = 0;
arr->hdr_refcount = 0;
- int mask = (arr->rows <= 1) - 1;
int pix_size = CV_ELEM_SIZE(type);
- int min_step = arr->cols*pix_size & mask;
+ int min_step = arr->cols*pix_size;
if( step != CV_AUTOSTEP && step != 0 )
{
if( step < min_step )
CV_Error( CV_BadStep, "" );
- arr->step = step & mask;
+ arr->step = step;
}
else
{
}
arr->type = CV_MAT_MAGIC_VAL | type |
- (arr->step == min_step ? CV_MAT_CONT_FLAG : 0);
+ (arr->rows == 1 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0);
icvCheckHuge( arr );
return arr;
}
+#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 )
{
CvMat* arr = *array;
- if( !CV_IS_MAT_HDR(arr) && !CV_IS_MATND_HDR(arr) )
+ if( !CV_IS_MAT_HDR_Z(arr) && !CV_IS_MATND_HDR(arr) )
CV_Error( CV_StsBadFlag, "" );
*array = 0;
if( step == 0 )
step = CV_ELEM_SIZE(mat->type)*mat->cols;
- total_size = step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN;
+ int64 _total_size = (int64)step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN;
+ total_size = (size_t)_total_size;
+ if(_total_size != (int64)total_size)
+ CV_Error(CV_StsNoMem, "Too big buffer is allocated" );
mat->refcount = (int*)cvAlloc( (size_t)total_size );
mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
*mat->refcount = 1;
int depth = img->depth;
int width = img->width;
- if( img->depth == IPL_DEPTH_32F || img->nChannels == 64 )
+ if( img->depth == IPL_DEPTH_32F || img->depth == IPL_DEPTH_64F )
{
img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) : sizeof(double);
img->depth = IPL_DEPTH_8U;
int type = CV_MAT_TYPE(mat->type);
pix_size = CV_ELEM_SIZE(type);
- min_step = mat->cols*pix_size & ((mat->rows <= 1) - 1);
+ min_step = mat->cols*pix_size;
- if( step != CV_AUTOSTEP )
+ if( step != CV_AUTOSTEP && step != 0 )
{
if( step < min_step && data != 0 )
CV_Error( CV_BadStep, "" );
- mat->step = step & ((mat->rows <= 1) - 1);
+ mat->step = step;
}
else
- {
mat->step = min_step;
- }
mat->data.ptr = (uchar*)data;
mat->type = CV_MAT_MAGIC_VAL | type |
- (mat->step==min_step ? CV_MAT_CONT_FLAG : 0);
+ (mat->rows == 1 || mat->step == min_step ? CV_MAT_CONT_FLAG : 0);
icvCheckHuge( mat );
}
else if( CV_IS_IMAGE_HDR( arr ))
if( (((int)(size_t)data | step) & 7) == 0 &&
cvAlign(img->width * pix_size, 8) == step )
- {
img->align = 8;
- }
else
- {
img->align = 4;
- }
}
else if( CV_IS_MATND_HDR( arr ))
{
}
if( step )
- *step = size1 == 1 ? 0 : mat->dim[0].step;
+ *step = mat->dim[0].step;
}
}
else
else if( CV_IS_IMAGE(arr))
{
IplImage* img = (IplImage*)arr;
- type = CV_MAKETYPE( IplToCvDepth(img->depth), img->nChannels );
+ type = CV_MAKETYPE( IPL2CV_DEPTH(img->depth), img->nChannels );
}
else
CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
*/
submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step +
rect.x*CV_ELEM_SIZE(mat->type);
- submat->step = mat->step & (rect.height > 1 ? -1 : 0);
+ submat->step = mat->step;
submat->type = (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) |
- (submat->step == 0 ? CV_MAT_CONT_FLAG : 0);
+ (rect.height <= 1 ? CV_MAT_CONT_FLAG : 0);
submat->rows = rect.height;
submat->cols = rect.width;
submat->refcount = 0;
if( delta_row == 1 )
{
submat->rows = end_row - start_row;
- submat->step = mat->step & (submat->rows > 1 ? -1 : 0);
+ submat->step = mat->step;
}
else
{
submat->cols = mat->cols;
submat->step &= submat->rows > 1 ? -1 : 0;
submat->data.ptr = mat->data.ptr + (size_t)start_row*mat->step;
- submat->type = (mat->type | (submat->step == 0 ? CV_MAT_CONT_FLAG : 0)) &
- (delta_row != 1 ? ~CV_MAT_CONT_FLAG : -1);
+ submat->type = (mat->type | (submat->rows == 1 ? CV_MAT_CONT_FLAG : 0)) &
+ (delta_row != 1 && submat->rows > 1 ? ~CV_MAT_CONT_FLAG : -1);
submat->refcount = 0;
submat->hdr_refcount = 0;
res = submat;
*/
submat->rows = mat->rows;
submat->cols = end_col - start_col;
- submat->step = mat->step & (submat->rows > 1 ? -1 : 0);
+ submat->step = mat->step;
submat->data.ptr = mat->data.ptr + (size_t)start_col*CV_ELEM_SIZE(mat->type);
- submat->type = mat->type & (submat->step && submat->cols < cols ? ~CV_MAT_CONT_FLAG : -1);
+ submat->type = mat->type & (submat->rows > 1 && submat->cols < cols ? ~CV_MAT_CONT_FLAG : -1);
submat->refcount = 0;
submat->hdr_refcount = 0;
res = submat;
submat->rows = len;
submat->cols = 1;
- submat->step = (mat->step + pix_size) & (submat->rows > 1 ? -1 : 0);
+ submat->step = mat->step + (submat->rows > 1 ? pix_size : 0);
submat->type = mat->type;
- if( submat->step )
+ if( submat->rows > 1 )
submat->type &= ~CV_MAT_CONT_FLAG;
else
submat->type |= CV_MAT_CONT_FLAG;
if( _type )
{
- int type = IplToCvDepth(img->depth);
+ int type = IPL2CV_DEPTH(img->depth);
if( type < 0 || (unsigned)(img->nChannels - 1) > 3 )
CV_Error( CV_StsUnsupportedFormat, "" );
if( img->imageData == 0 )
CV_Error( CV_StsNullPtr, "The image has NULL data pointer" );
- depth = IplToCvDepth( img->depth );
+ depth = IPL2CV_DEPTH( img->depth );
if( depth < 0 )
CV_Error( CV_BadDepth, "" );
"Images with planar data layout should be used with COI selected" );
cvInitMatHeader( mat, img->roi->height,
- img->roi->width, type,
- img->imageData + (img->roi->coi-1)*img->imageSize +
- img->roi->yOffset*img->widthStep +
- img->roi->xOffset*CV_ELEM_SIZE(type),
- img->widthStep );
+ img->roi->width, type,
+ img->imageData + (img->roi->coi-1)*img->imageSize +
+ img->roi->yOffset*img->widthStep +
+ img->roi->xOffset*CV_ELEM_SIZE(type),
+ img->widthStep );
}
else /* pixel order */
{
"The image is interleaved and has over CV_CN_MAX channels" );
cvInitMatHeader( mat, img->roi->height, img->roi->width,
- type, img->imageData +
- img->roi->yOffset*img->widthStep +
- img->roi->xOffset*CV_ELEM_SIZE(type),
- img->widthStep );
+ type, img->imageData +
+ img->roi->yOffset*img->widthStep +
+ img->roi->xOffset*CV_ELEM_SIZE(type),
+ img->widthStep );
}
}
else
CV_Error( CV_StsBadFlag, "Pixel order should be used with coi == 0" );
cvInitMatHeader( mat, img->height, img->width, type,
- img->imageData, img->widthStep );
+ img->imageData, img->widthStep );
}
result = mat;
if( new_dims <= 2 )
{
CvMat* mat = (CvMat*)arr;
- CvMat* header = (CvMat*)_header;
+ CvMat header;
int* refcount = 0;
int hdr_refcount = 0;
int total_width, new_rows, cn;
- if( sizeof_header != sizeof(CvMat))
- CV_Error( CV_StsBadArg, "The header should be CvMat" );
+ if( sizeof_header != sizeof(CvMat) && sizeof_header != sizeof(CvMatND) )
+ CV_Error( CV_StsBadArg, "The output header should be CvMat or CvMatND" );
- if( mat == header )
+ if( mat == (CvMat*)_header )
{
refcount = mat->refcount;
hdr_refcount = mat->hdr_refcount;
}
- else if( !CV_IS_MAT( mat ))
- mat = cvGetMat( mat, header, &coi, 1 );
+
+ if( !CV_IS_MAT( mat ))
+ mat = cvGetMat( mat, &header, &coi, 1 );
cn = CV_MAT_CN( mat->type );
total_width = mat->cols * cn;
"is not divisible by the new number of rows" );
}
- header->rows = new_rows;
- header->cols = total_width / new_cn;
+ header.rows = new_rows;
+ header.cols = total_width / new_cn;
- if( header->cols * new_cn != total_width ||
- (new_sizes && header->cols != new_sizes[1]) )
+ if( header.cols * new_cn != total_width ||
+ (new_sizes && header.cols != new_sizes[1]) )
CV_Error( CV_StsBadArg, "The total matrix width is not "
"divisible by the new number of columns" );
- header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
- header->step = header->cols * CV_ELEM_SIZE(mat->type);
- header->step &= new_rows > 1 ? -1 : 0;
- header->refcount = refcount;
- header->hdr_refcount = hdr_refcount;
+ header.type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
+ header.step = header.cols * CV_ELEM_SIZE(mat->type);
+ header.step &= new_rows > 1 ? -1 : 0;
+ header.refcount = refcount;
+ header.hdr_refcount = hdr_refcount;
+
+ if( sizeof_header == sizeof(CvMat) )
+ *(CvMat*)_header = header;
+ else
+ {
+ CvMatND* __header = (CvMatND*)_header;
+ cvGetMatND(&header, __header, 0);
+ if( new_dims > 0 )
+ __header->dims = new_dims;
+ }
}
else
{
CvMatND* header = (CvMatND*)_header;
if( sizeof_header != sizeof(CvMatND))
- CV_Error( CV_StsBadSize, "The header should be CvMatND" );
+ CV_Error( CV_StsBadSize, "The output header should be CvMatND" );
if( !new_sizes )
{
if( !CV_IS_MATND( arr ))
- CV_Error( CV_StsBadArg, "The source array must be CvMatND" );
+ CV_Error( CV_StsBadArg, "The input array must be CvMatND" );
{
CvMatND* mat = (CvMatND*)arr;
}
}
- if( !coi )
+ if( coi )
CV_Error( CV_BadCOI, "COI is not supported by this operation" );
result = _header;
if( !image )
CV_Error( CV_HeaderIsNull, "" );
- if( rect.x > image->width || rect.y > image->height )
- CV_Error( CV_BadROISize, "" );
-
- if( rect.x + rect.width < 0 || rect.y + rect.height < 0 )
- CV_Error( CV_BadROISize, "" );
-
- if( rect.x < 0 )
- {
- rect.width += rect.x;
- rect.x = 0;
- }
-
- if( rect.y < 0 )
- {
- rect.height += rect.y;
- rect.y = 0;
- }
-
- if( rect.x + rect.width > image->width )
- rect.width = image->width - rect.x;
-
- if( rect.y + rect.height > image->height )
- rect.height = image->height - rect.y;
+ // allow zero ROI width or height
+ CV_Assert( rect.width >= 0 && rect.height >= 0 &&
+ rect.x < image->width && rect.y < image->height &&
+ rect.x + rect.width >= (int)(rect.width > 0) &&
+ rect.y + rect.height >= (int)(rect.height > 0) );
+
+ rect.width += rect.x;
+ rect.height += rect.y;
+
+ rect.x = std::max(rect.x, 0);
+ rect.y = std::max(rect.y, 0);
+ rect.width = std::min(rect.width, image->width);
+ rect.height = std::min(rect.height, image->height);
+
+ rect.width -= rect.x;
+ rect.height -= rect.y;
if( image->roi )
{