cvarithm.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 1,439 行 · 第 1/5 页

SVN-BASE
1,439
字号
        CvMatNDIterator iterator;
        CvFunc2D_2A1P func;

        if( maskarr )
            CV_ERROR( CV_StsBadMask,
            "This operation on multi-dimensional arrays does not support mask" );

        CV_CALL( icvPrepareArrayOp( 2, arrs, 0, stubs, &iterator ));

        sctype = type = CV_MAT_TYPE(iterator.hdr[0]->type);
        if( CV_MAT_DEPTH(sctype) < CV_32S )
            sctype = (type & CV_MAT_CN_MASK) | CV_32SC1;
        iterator.size.width *= CV_MAT_CN(type);

        func = (CvFunc2D_2A1P)(subr_tab.fn_2d[CV_MAT_DEPTH(type)]);
        if( !func )
            CV_ERROR( CV_StsUnsupportedFormat, "" );
       
        CV_CALL( cvScalarToRawData( &scalar, buf, sctype, 0 ));

        do
        {
            IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP,
                             iterator.ptr[1], CV_STUB_STEP,
                             iterator.size, buf ));
        }
        while( icvNextMatNDSlice( &iterator ));
        EXIT;
    }

    if( !CV_ARE_TYPES_EQ( src, dst ))
        CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );

    if( !CV_ARE_SIZES_EQ( src, dst ))
        CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );

    sctype = type = CV_MAT_TYPE(src->type);
    if( CV_MAT_DEPTH(sctype) < CV_32S )
        sctype = (type & CV_MAT_CN_MASK) | CV_32SC1;

    size = icvGetMatSize( src );

    if( !maskarr )
    {
        if( CV_IS_MAT_CONT( src->type & dst->type ))
        {
            size.width *= size.height;
            if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE )
            {
                if( type == CV_32FC1 )
                {
                    const float* srcdata = (const float*)(src->data.ptr);
                    float* dstdata = (float*)(dst->data.ptr);
                
                    do
                    {
                        dstdata[size.width-1] = (float)
                            (scalar.val[0] - srcdata[size.width-1]);
                    }
                    while( --size.width );

                    EXIT;
                }

                if( type == CV_64FC1 )
                {
                    const double* srcdata = (const double*)(src->data.ptr);
                    double* dstdata = (double*)(dst->data.ptr);
                
                    do
                    {
                        dstdata[size.width-1] =
                            scalar.val[0] - srcdata[size.width-1];
                    }
                    while( --size.width );

                    EXIT;
                }
            }

            src_step = dst_step = CV_STUB_STEP;
            size.height = 1;
        }
        else
        {
            src_step = src->step;
            dst_step = dst->step;
        }

        {
            size.width *= CV_MAT_CN( type );
            CvFunc2D_2A1P func = (CvFunc2D_2A1P)(subr_tab.fn_2d[CV_MAT_DEPTH(type)]);

            if( !func )
                CV_ERROR( CV_StsUnsupportedFormat, "" );

            CV_CALL( cvScalarToRawData( &scalar, buf, sctype, 1 ));

            IPPI_CALL( func( src->data.ptr, src_step,
                             dst->data.ptr, dst_step, size, buf ));
        }
    }
    else
    {
        CvMat maskstub, *mask = (CvMat*)maskarr;
        CvArithmUniMaskFunc2D func;
        int mask_step;

        if( !CV_IS_MAT(mask) )
            CV_CALL( mask = cvGetMat( mask, &maskstub ));

        if( !CV_IS_MASK_ARR(mask))
            CV_ERROR( CV_StsBadMask, "" );

        if( !CV_ARE_SIZES_EQ( mask, dst ))
            CV_ERROR( CV_StsUnmatchedSizes, "" );

        if( src->data.ptr != dst->data.ptr )
        {
            CV_CALL( cvCopy( src, dst, mask ));
        }

        if( CV_IS_MAT_CONT( dst->type & mask->type ))
        {
            size.width *= size.height;
            dst_step = mask_step = CV_STUB_STEP;
            size.height = 1;
        }
        else
        {
            dst_step = dst->step;
            mask_step = mask->step;
        }
        
        func = (CvArithmUniMaskFunc2D)(subrmask_tab.fn_2d[CV_MAT_DEPTH(type)]);

        if( !func )
            CV_ERROR( CV_StsUnsupportedFormat, "" );

        CV_CALL( cvScalarToRawData( &scalar, buf, sctype, 0 ));

        IPPI_CALL( func( dst->data.ptr, dst_step, mask->data.ptr,
                         mask_step, size, buf, CV_MAT_CN(type) ));
    }

    __END__;
}


/******************************* A D D ********************************/

CV_IMPL void
cvAdd( const void* srcarr1, const void* srcarr2,
       void* dstarr, const void* maskarr )
{
    static CvFuncTable addmask_tab;
    static CvFuncTable add_tab;
    static int inittab = 0, initmasktab = 0;

    CV_FUNCNAME( "cvAdd" );

    __BEGIN__;

    int type;
    int src1_step, src2_step, dst_step;
    CvMat srcstub1, *src1 = (CvMat*)srcarr1;
    CvMat srcstub2, *src2 = (CvMat*)srcarr2;
    CvMat dststub,  *dst = (CvMat*)dstarr;
    CvSize size;

    if( !CV_IS_MAT(src1) || !CV_IS_MAT(src2) || !CV_IS_MAT(dst))
    {
        if( CV_IS_MATND(src1) || CV_IS_MATND(src2) || CV_IS_MATND(dst))
        {
            CvArr* arrs[] = { src1, src2, dst };
            CvMatND stubs[3];
            CvMatNDIterator iterator;
            CvFunc2D_3A func;

            if( maskarr )
                CV_ERROR( CV_StsBadMask,
                "This operation on multi-dimensional arrays does not support mask" );

            CV_CALL( icvPrepareArrayOp( 3, arrs, 0, stubs, &iterator ));

            type = iterator.hdr[0]->type;
            iterator.size.width *= CV_MAT_CN(type);

            if( !inittab )
            {
                icvInitAddC1RTable( &add_tab );
                inittab = 1;
            }

            func = (CvFunc2D_3A)(add_tab.fn_2d[CV_MAT_DEPTH(type)]);
            if( !func )
                CV_ERROR( CV_StsUnsupportedFormat, "" );

            do
            {
                IPPI_CALL( func( iterator.ptr[0], CV_STUB_STEP,
                                 iterator.ptr[1], CV_STUB_STEP,
                                 iterator.ptr[2], CV_STUB_STEP,
                                 iterator.size ));
            }
            while( icvNextMatNDSlice( &iterator ));
            EXIT;
        }
        else
        {
            int coi1 = 0, coi2 = 0, coi3 = 0;
            
            CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi1 ));
            CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi2 ));
            CV_CALL( dst = cvGetMat( dst, &dststub, &coi3 ));
            if( coi1 + coi2 + coi3 != 0 )
                CV_ERROR( CV_BadCOI, "" );
        }
    }

    if( !CV_ARE_TYPES_EQ( src1, src2 ) || !CV_ARE_TYPES_EQ( src1, dst ))
        CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );

    if( !CV_ARE_SIZES_EQ( src1, src2 ) || !CV_ARE_SIZES_EQ( src1, dst ))
        CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );

    type = CV_MAT_TYPE(src1->type);
    size = icvGetMatSize( src1 );

    if( !maskarr )
    {
        int depth = CV_MAT_DEPTH(type);
        size.width *= CV_MAT_CN( type );

        if( CV_IS_MAT_CONT( src1->type & src2->type & dst->type ))
        {
            size.width *= size.height;
            if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE*
                              CV_MAX_INLINE_MAT_OP_SIZE )
            {
                if( depth == CV_32F )
                {
                    const float* src1data = (const float*)(src1->data.ptr);
                    const float* src2data = (const float*)(src2->data.ptr);
                    float* dstdata = (float*)(dst->data.ptr);
                
                    do
                    {
                        dstdata[size.width-1] = (float)
                            (src1data[size.width-1] + src2data[size.width-1]);
                    }
                    while( --size.width );

                    EXIT;
                }

                if( depth == CV_64F )
                {
                    const double* src1data = (const double*)(src1->data.ptr);
                    const double* src2data = (const double*)(src2->data.ptr);
                    double* dstdata = (double*)(dst->data.ptr);
                
                    do
                    {
                        dstdata[size.width-1] =
                            src1data[size.width-1] + src2data[size.width-1];
                    }
                    while( --size.width );

                    EXIT;
                }
            }

            src1_step = src2_step = dst_step = CV_STUB_STEP;
            size.height = 1;
        }
        else
        {
            src1_step = src1->step;
            src2_step = src2->step;
            dst_step = dst->step;
        }

        if( !inittab )
        {
            icvInitAddC1RTable( &add_tab );
            inittab = 1;
        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?