utils.cpp 8.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "precomp.hpp"

CV_IMPL CvSeq* cvPointSeqFromMat( int seq_kind, const CvArr* arr,
                                  CvContour* contour_header, CvSeqBlock* block )
{
    CV_Assert( arr != 0 && contour_header != 0 && block != 0 );

    int eltype;
    CvMat* mat = (CvMat*)arr;
    
    if( !CV_IS_MAT( mat ))
        CV_Error( CV_StsBadArg, "Input array is not a valid matrix" ); 

    eltype = CV_MAT_TYPE( mat->type );
    if( eltype != CV_32SC2 && eltype != CV_32FC2 )
        CV_Error( CV_StsUnsupportedFormat,
        "The matrix can not be converted to point sequence because of "
        "inappropriate element type" );

    if( (mat->width != 1 && mat->height != 1) || !CV_IS_MAT_CONT(mat->type))
        CV_Error( CV_StsBadArg,
        "The matrix converted to point sequence must be "
        "1-dimensional and continuous" );

    cvMakeSeqHeaderForArray(
            (seq_kind & (CV_SEQ_KIND_MASK|CV_SEQ_FLAG_CLOSED)) | eltype,
            sizeof(CvContour), CV_ELEM_SIZE(eltype), mat->data.ptr,
            mat->width*mat->height, (CvSeq*)contour_header, block );

    return (CvSeq*)contour_header;
}

74 75
namespace cv
{
76

77 78
static void copyMakeBorder_8u( const uchar* src, size_t srcstep, Size srcroi,
                               uchar* dst, size_t dststep, Size dstroi,
79
                               int top, int left, int cn, int borderType )
80 81
{
    const int isz = (int)sizeof(int);
82 83
    int i, j, k, elemSize = 1;
    bool intMode = false;
84 85 86 87

    if( (cn | srcstep | dststep | (size_t)src | (size_t)dst) % isz == 0 )
    {
        cn /= isz;
88 89
        elemSize = isz;
        intMode = true;
90 91
    }

92 93 94 95 96 97 98 99 100 101
    AutoBuffer<int> _tab((dstroi.width - srcroi.width)*cn);
    int* tab = _tab;
    int right = dstroi.width - srcroi.width - left;
    int bottom = dstroi.height - srcroi.height - top;
    
    for( i = 0; i < left; i++ )
    {
        j = borderInterpolate(i - left, srcroi.width, borderType)*cn;
        for( k = 0; k < cn; k++ )
            tab[i*cn + k] = j + k;
102
    }
103 104
    
    for( i = 0; i < right; i++ )
105
    {
106 107 108
        j = borderInterpolate(srcroi.width + i, srcroi.width, borderType)*cn;
        for( k = 0; k < cn; k++ )
            tab[(i+left)*cn + k] = j + k;
109 110 111 112 113
    }

    srcroi.width *= cn;
    dstroi.width *= cn;
    left *= cn;
114 115
    right *= cn;
    
116
    uchar* dstInner = dst + dststep*top + left*elemSize;
117

118
    for( i = 0; i < srcroi.height; i++, dstInner += dststep, src += srcstep )
119
    {
120 121
        if( dstInner != src )
            memcpy(dstInner, src, srcroi.width*elemSize);
122
        
123
        if( intMode )
124
        {
125 126 127 128 129 130
            const int* isrc = (int*)src;
            int* idstInner = (int*)dstInner;
            for( j = 0; j < left; j++ )
                idstInner[j - left] = isrc[tab[j]];
            for( j = 0; j < right; j++ )
                idstInner[j + srcroi.width] = isrc[tab[j + left]];
131
        }
132
        else
133 134
        {
            for( j = 0; j < left; j++ )
135 136 137
                dstInner[j - left] = src[tab[j]];
            for( j = 0; j < right; j++ )
                dstInner[j + srcroi.width] = src[tab[j + left]];
138 139
        }
    }
140 141 142 143 144
    
    dstroi.width *= elemSize;
    dst += dststep*top;
    
    for( i = 0; i < top; i++ )
145
    {
146 147
        j = borderInterpolate(i - top, srcroi.height, borderType);
        memcpy(dst + (i - top)*dststep, dst + j*dststep, dstroi.width);
148
    }
149 150
    
    for( i = 0; i < bottom; i++ )
151
    {
152 153
        j = borderInterpolate(i + srcroi.height, srcroi.height, borderType);
        memcpy(dst + (i + srcroi.height)*dststep, dst + j*dststep, dstroi.width);
154 155 156 157
    }
}


158 159
static void copyMakeConstBorder_8u( const uchar* src, size_t srcstep, Size srcroi,
                                    uchar* dst, size_t dststep, Size dstroi,
160
                                    int top, int left, int cn, const uchar* value )
161
{
162 163 164 165 166 167 168
    int i, j;
    AutoBuffer<uchar> _constBuf(dstroi.width*cn);
    uchar* constBuf = _constBuf;
    int right = dstroi.width - srcroi.width - left;
    int bottom = dstroi.height - srcroi.height - top;
    
    for( i = 0; i < dstroi.width; i++ )
169
    {
170 171
        for( j = 0; j < cn; j++ )
            constBuf[i*cn + j] = value[j];
172
    }
173 174 175 176 177 178 179 180 181
    
    srcroi.width *= cn;
    dstroi.width *= cn;
    left *= cn;
    right *= cn;
    
    uchar* dstInner = dst + dststep*top + left;
    
    for( i = 0; i < srcroi.height; i++, dstInner += dststep, src += srcstep )
182
    {
183 184 185
        if( dstInner != src )
            memcpy( dstInner, src, srcroi.width );
        memcpy( dstInner - left, constBuf, left );
186
        memcpy( dstInner + srcroi.width, constBuf, right );
187
    }
188 189 190 191 192 193 194 195
    
    dst += dststep*top;
    
    for( i = 0; i < top; i++ )
        memcpy(dst + (i - top)*dststep, constBuf, dstroi.width);
    
    for( i = 0; i < bottom; i++ )
        memcpy(dst + (i + srcroi.height)*dststep, constBuf, dstroi.width);
196 197
}

198
}
199
    
200
void cv::copyMakeBorder( InputArray _src, OutputArray _dst, int top, int bottom,
201
                         int left, int right, int borderType, const Scalar& value )
202
{
203
    Mat src = _src.getMat();
204
    CV_Assert( top >= 0 && bottom >= 0 && left >= 0 && right >= 0 );
205
    
206 207 208
    _dst.create( src.rows + top + bottom, src.cols + left + right, src.type() );
    Mat dst = _dst.getMat();
    
209 210 211
    if( borderType != BORDER_CONSTANT )
        copyMakeBorder_8u( src.data, src.step, src.size(),
                           dst.data, dst.step, dst.size(),
212
                           top, left, (int)src.elemSize(), borderType );
213
    else
214 215
    {
        double buf[4];
216 217 218
        scalarToRawData(value, buf, src.type());
        copyMakeConstBorder_8u( src.data, src.step, src.size(),
                                dst.data, dst.step, dst.size(),
219
                                top, left, (int)src.elemSize(), (uchar*)buf );
220
    }
221
}
222 223


224 225 226
CV_IMPL void
cvCopyMakeBorder( const CvArr* srcarr, CvArr* dstarr, CvPoint offset,
                  int borderType, CvScalar value )
227
{
228 229 230 231 232 233
    cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
    int left = offset.x, right = dst.cols - src.cols - left;
    int top = offset.y, bottom = dst.rows - src.rows - top;
    
    CV_Assert( dst.type() == src.type() );
    cv::copyMakeBorder( src, dst, top, bottom, left, right, borderType, value );
234 235 236
}

/* End of file. */