Home | History | Annotate | Download | only in src
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                        Intel License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
     14 // Third party copyrights are property of their respective owners.
     15 //
     16 // Redistribution and use in source and binary forms, with or without modification,
     17 // are permitted provided that the following conditions are met:
     18 //
     19 //   * Redistribution's of source code must retain the above copyright notice,
     20 //     this list of conditions and the following disclaimer.
     21 //
     22 //   * Redistribution's in binary form must reproduce the above copyright notice,
     23 //     this list of conditions and the following disclaimer in the documentation
     24 //     and/or other materials provided with the distribution.
     25 //
     26 //   * The name of Intel Corporation may not be used to endorse or promote products
     27 //     derived from this software without specific prior written permission.
     28 //
     29 // This software is provided by the copyright holders and contributors "as is" and
     30 // any express or implied warranties, including, but not limited to, the implied
     31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     32 // In no event shall the Intel Corporation or contributors be liable for any direct,
     33 // indirect, incidental, special, exemplary, or consequential damages
     34 // (including, but not limited to, procurement of substitute goods or services;
     35 // loss of use, data, or profits; or business interruption) however caused
     36 // and on any theory of liability, whether in contract, strict liability,
     37 // or tort (including negligence or otherwise) arising in any way out of
     38 // the use of this software, even if advised of the possibility of such damage.
     39 //
     40 //M*/
     41 
     42 /* ////////////////////////////////////////////////////////////////////
     43 //
     44 //  CvMat basic operations: cvCopy, cvSet
     45 //
     46 // */
     47 
     48 #include "_cxcore.h"
     49 
     50 /////////////////////////////////////////////////////////////////////////////////////////
     51 //                                                                                     //
     52 //                                  L/L COPY & SET FUNCTIONS                           //
     53 //                                                                                     //
     54 /////////////////////////////////////////////////////////////////////////////////////////
     55 
     56 
     57 IPCVAPI_IMPL( CvStatus, icvCopy_8u_C1R, ( const uchar* src, int srcstep,
     58                                           uchar* dst, int dststep, CvSize size ),
     59                                           (src, srcstep, dst, dststep, size) )
     60 {
     61     for( ; size.height--; src += srcstep, dst += dststep )
     62         memcpy( dst, src, size.width );
     63 
     64     return  CV_OK;
     65 }
     66 
     67 
     68 static CvStatus CV_STDCALL
     69 icvSet_8u_C1R( uchar* dst, int dst_step, CvSize size,
     70                const void* scalar, int pix_size )
     71 {
     72     int copy_len = 12*pix_size;
     73     uchar* dst_limit = dst + size.width;
     74 
     75     if( size.height-- )
     76     {
     77         while( dst + copy_len <= dst_limit )
     78         {
     79             memcpy( dst, scalar, copy_len );
     80             dst += copy_len;
     81         }
     82 
     83         memcpy( dst, scalar, dst_limit - dst );
     84     }
     85 
     86     if( size.height )
     87     {
     88         dst = dst_limit - size.width + dst_step;
     89 
     90         for( ; size.height--; dst += dst_step )
     91             memcpy( dst, dst - dst_step, size.width );
     92     }
     93 
     94     return CV_OK;
     95 }
     96 
     97 
     98 /////////////////////////////////////////////////////////////////////////////////////////
     99 //                                                                                     //
    100 //                                L/L COPY WITH MASK FUNCTIONS                         //
    101 //                                                                                     //
    102 /////////////////////////////////////////////////////////////////////////////////////////
    103 
    104 
    105 #define ICV_DEF_COPY_MASK_C1_CASE( type )   \
    106     for( i = 0; i <= size.width-2; i += 2 ) \
    107     {                                       \
    108         if( mask[i] )                       \
    109             dst[i] = src[i];                \
    110         if( mask[i+1] )                     \
    111             dst[i+1] = src[i+1];            \
    112     }                                       \
    113                                             \
    114     for( ; i < size.width; i++ )            \
    115     {                                       \
    116         if( mask[i] )                       \
    117             dst[i] = src[i];                \
    118     }
    119 
    120 #define ICV_DEF_COPY_MASK_C3_CASE( type )   \
    121     for( i = 0; i < size.width; i++ )       \
    122         if( mask[i] )                       \
    123         {                                   \
    124             type t0 = src[i*3];             \
    125             type t1 = src[i*3+1];           \
    126             type t2 = src[i*3+2];           \
    127                                             \
    128             dst[i*3] = t0;                  \
    129             dst[i*3+1] = t1;                \
    130             dst[i*3+2] = t2;                \
    131         }
    132 
    133 
    134 
    135 #define ICV_DEF_COPY_MASK_C4_CASE( type )   \
    136     for( i = 0; i < size.width; i++ )       \
    137         if( mask[i] )                       \
    138         {                                   \
    139             type t0 = src[i*4];             \
    140             type t1 = src[i*4+1];           \
    141             dst[i*4] = t0;                  \
    142             dst[i*4+1] = t1;                \
    143                                             \
    144             t0 = src[i*4+2];                \
    145             t1 = src[i*4+3];                \
    146             dst[i*4+2] = t0;                \
    147             dst[i*4+3] = t1;                \
    148         }
    149 
    150 
    151 #define ICV_DEF_COPY_MASK_2D( name, type, cn )              \
    152 IPCVAPI_IMPL( CvStatus,                                     \
    153 name,( const type* src, int srcstep, type* dst, int dststep,\
    154        CvSize size, const uchar* mask, int maskstep ),      \
    155        (src, srcstep, dst, dststep, size, mask, maskstep))  \
    156 {                                                           \
    157     srcstep /= sizeof(src[0]); dststep /= sizeof(dst[0]);   \
    158     for( ; size.height--; src += srcstep,                   \
    159             dst += dststep, mask += maskstep )              \
    160     {                                                       \
    161         int i;                                              \
    162         ICV_DEF_COPY_MASK_C##cn##_CASE( type )              \
    163     }                                                       \
    164                                                             \
    165     return  CV_OK;                                          \
    166 }
    167 
    168 
    169 #define ICV_DEF_SET_MASK_C1_CASE( type )    \
    170     for( i = 0; i <= size.width-2; i += 2 ) \
    171     {                                       \
    172         if( mask[i] )                       \
    173             dst[i] = s0;                    \
    174         if( mask[i+1] )                     \
    175             dst[i+1] = s0;                  \
    176     }                                       \
    177                                             \
    178     for( ; i < size.width; i++ )            \
    179     {                                       \
    180         if( mask[i] )                       \
    181             dst[i] = s0;                    \
    182     }
    183 
    184 
    185 #define ICV_DEF_SET_MASK_C3_CASE( type )    \
    186     for( i = 0; i < size.width; i++ )       \
    187         if( mask[i] )                       \
    188         {                                   \
    189             dst[i*3] = s0;                  \
    190             dst[i*3+1] = s1;                \
    191             dst[i*3+2] = s2;                \
    192         }
    193 
    194 #define ICV_DEF_SET_MASK_C4_CASE( type )    \
    195     for( i = 0; i < size.width; i++ )       \
    196         if( mask[i] )                       \
    197         {                                   \
    198             dst[i*4] = s0;                  \
    199             dst[i*4+1] = s1;                \
    200             dst[i*4+2] = s2;                \
    201             dst[i*4+3] = s3;                \
    202         }
    203 
    204 #define ICV_DEF_SET_MASK_2D( name, type, cn )       \
    205 IPCVAPI_IMPL( CvStatus,                             \
    206 name,( type* dst, int dststep,                      \
    207        const uchar* mask, int maskstep,             \
    208        CvSize size, const type* scalar ),           \
    209        (dst, dststep, mask, maskstep, size, scalar))\
    210 {                                                   \
    211     CV_UN_ENTRY_C##cn( type );                      \
    212     dststep /= sizeof(dst[0]);                      \
    213                                                     \
    214     for( ; size.height--; mask += maskstep,         \
    215                           dst += dststep )          \
    216     {                                               \
    217         int i;                                      \
    218         ICV_DEF_SET_MASK_C##cn##_CASE( type )       \
    219     }                                               \
    220                                                     \
    221     return CV_OK;                                   \
    222 }
    223 
    224 
    225 ICV_DEF_SET_MASK_2D( icvSet_8u_C1MR, uchar, 1 )
    226 ICV_DEF_SET_MASK_2D( icvSet_16s_C1MR, ushort, 1 )
    227 ICV_DEF_SET_MASK_2D( icvSet_8u_C3MR, uchar, 3 )
    228 ICV_DEF_SET_MASK_2D( icvSet_8u_C4MR, int, 1 )
    229 ICV_DEF_SET_MASK_2D( icvSet_16s_C3MR, ushort, 3 )
    230 ICV_DEF_SET_MASK_2D( icvSet_16s_C4MR, int64, 1 )
    231 ICV_DEF_SET_MASK_2D( icvSet_32f_C3MR, int, 3 )
    232 ICV_DEF_SET_MASK_2D( icvSet_32f_C4MR, int, 4 )
    233 ICV_DEF_SET_MASK_2D( icvSet_64s_C3MR, int64, 3 )
    234 ICV_DEF_SET_MASK_2D( icvSet_64s_C4MR, int64, 4 )
    235 
    236 ICV_DEF_COPY_MASK_2D( icvCopy_8u_C1MR, uchar, 1 )
    237 ICV_DEF_COPY_MASK_2D( icvCopy_16s_C1MR, ushort, 1 )
    238 ICV_DEF_COPY_MASK_2D( icvCopy_8u_C3MR, uchar, 3 )
    239 ICV_DEF_COPY_MASK_2D( icvCopy_8u_C4MR, int, 1 )
    240 ICV_DEF_COPY_MASK_2D( icvCopy_16s_C3MR, ushort, 3 )
    241 ICV_DEF_COPY_MASK_2D( icvCopy_16s_C4MR, int64, 1 )
    242 ICV_DEF_COPY_MASK_2D( icvCopy_32f_C3MR, int, 3 )
    243 ICV_DEF_COPY_MASK_2D( icvCopy_32f_C4MR, int, 4 )
    244 ICV_DEF_COPY_MASK_2D( icvCopy_64s_C3MR, int64, 3 )
    245 ICV_DEF_COPY_MASK_2D( icvCopy_64s_C4MR, int64, 4 )
    246 
    247 #define CV_DEF_INIT_COPYSET_TAB_2D( FUNCNAME, FLAG )                \
    248 static void icvInit##FUNCNAME##FLAG##Table( CvBtFuncTable* table )  \
    249 {                                                                   \
    250     table->fn_2d[1]  = (void*)icv##FUNCNAME##_8u_C1##FLAG;          \
    251     table->fn_2d[2]  = (void*)icv##FUNCNAME##_16s_C1##FLAG;         \
    252     table->fn_2d[3]  = (void*)icv##FUNCNAME##_8u_C3##FLAG;          \
    253     table->fn_2d[4]  = (void*)icv##FUNCNAME##_8u_C4##FLAG;          \
    254     table->fn_2d[6]  = (void*)icv##FUNCNAME##_16s_C3##FLAG;         \
    255     table->fn_2d[8]  = (void*)icv##FUNCNAME##_16s_C4##FLAG;         \
    256     table->fn_2d[12] = (void*)icv##FUNCNAME##_32f_C3##FLAG;         \
    257     table->fn_2d[16] = (void*)icv##FUNCNAME##_32f_C4##FLAG;         \
    258     table->fn_2d[24] = (void*)icv##FUNCNAME##_64s_C3##FLAG;         \
    259     table->fn_2d[32] = (void*)icv##FUNCNAME##_64s_C4##FLAG;         \
    260 }
    261 
    262 CV_DEF_INIT_COPYSET_TAB_2D( Set, MR )
    263 CV_DEF_INIT_COPYSET_TAB_2D( Copy, MR )
    264 
    265 /////////////////////////////////////////////////////////////////////////////////////////
    266 //                                                                                     //
    267 //                                H/L COPY & SET FUNCTIONS                             //
    268 //                                                                                     //
    269 /////////////////////////////////////////////////////////////////////////////////////////
    270 
    271 
    272 CvCopyMaskFunc
    273 icvGetCopyMaskFunc( int elem_size )
    274 {
    275     static CvBtFuncTable copym_tab;
    276     static int inittab = 0;
    277 
    278     if( !inittab )
    279     {
    280         icvInitCopyMRTable( &copym_tab );
    281         inittab = 1;
    282     }
    283     return (CvCopyMaskFunc)copym_tab.fn_2d[elem_size];
    284 }
    285 
    286 
    287 /* dst = src */
    288 CV_IMPL void
    289 cvCopy( const void* srcarr, void* dstarr, const void* maskarr )
    290 {
    291     CV_FUNCNAME( "cvCopy" );
    292 
    293     __BEGIN__;
    294 
    295     int pix_size;
    296     CvMat srcstub, *src = (CvMat*)srcarr;
    297     CvMat dststub, *dst = (CvMat*)dstarr;
    298     CvSize size;
    299 
    300     if( !CV_IS_MAT(src) || !CV_IS_MAT(dst) )
    301     {
    302         if( CV_IS_SPARSE_MAT(src) && CV_IS_SPARSE_MAT(dst))
    303         {
    304             CvSparseMat* src1 = (CvSparseMat*)src;
    305             CvSparseMat* dst1 = (CvSparseMat*)dst;
    306             CvSparseMatIterator iterator;
    307             CvSparseNode* node;
    308 
    309             dst1->dims = src1->dims;
    310             memcpy( dst1->size, src1->size, src1->dims*sizeof(src1->size[0]));
    311             dst1->valoffset = src1->valoffset;
    312             dst1->idxoffset = src1->idxoffset;
    313             cvClearSet( dst1->heap );
    314 
    315             if( src1->heap->active_count >= dst1->hashsize*CV_SPARSE_HASH_RATIO )
    316             {
    317                 CV_CALL( cvFree( &dst1->hashtable ));
    318                 dst1->hashsize = src1->hashsize;
    319                 CV_CALL( dst1->hashtable =
    320                     (void**)cvAlloc( dst1->hashsize*sizeof(dst1->hashtable[0])));
    321             }
    322 
    323             memset( dst1->hashtable, 0, dst1->hashsize*sizeof(dst1->hashtable[0]));
    324 
    325             for( node = cvInitSparseMatIterator( src1, &iterator );
    326                  node != 0; node = cvGetNextSparseNode( &iterator ))
    327             {
    328                 CvSparseNode* node_copy = (CvSparseNode*)cvSetNew( dst1->heap );
    329                 int tabidx = node->hashval & (dst1->hashsize - 1);
    330                 CV_MEMCPY_AUTO( node_copy, node, dst1->heap->elem_size );
    331                 node_copy->next = (CvSparseNode*)dst1->hashtable[tabidx];
    332                 dst1->hashtable[tabidx] = node_copy;
    333             }
    334             EXIT;
    335         }
    336         else if( CV_IS_MATND(src) || CV_IS_MATND(dst) )
    337         {
    338             CvArr* arrs[] = { src, dst };
    339             CvMatND stubs[3];
    340             CvNArrayIterator iterator;
    341 
    342             CV_CALL( cvInitNArrayIterator( 2, arrs, maskarr, stubs, &iterator ));
    343             pix_size = CV_ELEM_SIZE(iterator.hdr[0]->type);
    344 
    345             if( !maskarr )
    346             {
    347                 iterator.size.width *= pix_size;
    348                 if( iterator.size.width <= CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double))
    349                 {
    350                     do
    351                     {
    352                         memcpy( iterator.ptr[1], iterator.ptr[0], iterator.size.width );
    353                     }
    354                     while( cvNextNArraySlice( &iterator ));
    355                 }
    356                 else
    357                 {
    358                     do
    359                     {
    360                         icvCopy_8u_C1R( iterator.ptr[0], CV_STUB_STEP,
    361                                         iterator.ptr[1], CV_STUB_STEP, iterator.size );
    362                     }
    363                     while( cvNextNArraySlice( &iterator ));
    364                 }
    365             }
    366             else
    367             {
    368                 CvCopyMaskFunc func = icvGetCopyMaskFunc( pix_size );
    369                 if( !func )
    370                     CV_ERROR( CV_StsUnsupportedFormat, "" );
    371 
    372                 do
    373                 {
    374                     func( iterator.ptr[0], CV_STUB_STEP,
    375                           iterator.ptr[1], CV_STUB_STEP,
    376                           iterator.size,
    377                           iterator.ptr[2], CV_STUB_STEP );
    378                 }
    379                 while( cvNextNArraySlice( &iterator ));
    380             }
    381             EXIT;
    382         }
    383         else
    384         {
    385             int coi1 = 0, coi2 = 0;
    386             CV_CALL( src = cvGetMat( src, &srcstub, &coi1 ));
    387             CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 ));
    388 
    389             if( coi1 )
    390             {
    391                 CvArr* planes[] = { 0, 0, 0, 0 };
    392 
    393                 if( maskarr )
    394                     CV_ERROR( CV_StsBadArg, "COI + mask are not supported" );
    395 
    396                 planes[coi1-1] = dst;
    397                 CV_CALL( cvSplit( src, planes[0], planes[1], planes[2], planes[3] ));
    398                 EXIT;
    399             }
    400             else if( coi2 )
    401             {
    402                 CvArr* planes[] = { 0, 0, 0, 0 };
    403 
    404                 if( maskarr )
    405                     CV_ERROR( CV_StsBadArg, "COI + mask are not supported" );
    406 
    407                 planes[coi2-1] = src;
    408                 CV_CALL( cvMerge( planes[0], planes[1], planes[2], planes[3], dst ));
    409                 EXIT;
    410             }
    411         }
    412     }
    413 
    414     if( !CV_ARE_TYPES_EQ( src, dst ))
    415         CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
    416 
    417     if( !CV_ARE_SIZES_EQ( src, dst ))
    418         CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
    419 
    420     size = cvGetMatSize( src );
    421     pix_size = CV_ELEM_SIZE(src->type);
    422 
    423     if( !maskarr )
    424     {
    425         int src_step = src->step, dst_step = dst->step;
    426         size.width *= pix_size;
    427         if( CV_IS_MAT_CONT( src->type & dst->type ) && (src_step == dst_step) && (src_step == src->width * pix_size))
    428         {
    429             size.width *= size.height;
    430 
    431             if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE*
    432                               CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double))
    433             {
    434                 memcpy( dst->data.ptr, src->data.ptr, size.width );
    435                 EXIT;
    436             }
    437 
    438             size.height = 1;
    439             src_step = dst_step = CV_STUB_STEP;
    440         }
    441 
    442         if( src->data.ptr != dst->data.ptr )
    443             icvCopy_8u_C1R( src->data.ptr, src_step,
    444                             dst->data.ptr, dst_step, size );
    445     }
    446     else
    447     {
    448         CvCopyMaskFunc func = icvGetCopyMaskFunc(pix_size);
    449         CvMat maskstub, *mask = (CvMat*)maskarr;
    450         int src_step = src->step;
    451         int dst_step = dst->step;
    452         int mask_step;
    453 
    454         if( !CV_IS_MAT( mask ))
    455             CV_CALL( mask = cvGetMat( mask, &maskstub ));
    456         if( !CV_IS_MASK_ARR( mask ))
    457             CV_ERROR( CV_StsBadMask, "" );
    458 
    459         if( !CV_ARE_SIZES_EQ( src, mask ))
    460             CV_ERROR( CV_StsUnmatchedSizes, "" );
    461 
    462         mask_step = mask->step;
    463 
    464         if( CV_IS_MAT_CONT( src->type & dst->type & mask->type ))
    465         {
    466             size.width *= size.height;
    467             size.height = 1;
    468             src_step = dst_step = mask_step = CV_STUB_STEP;
    469         }
    470 
    471         if( !func )
    472             CV_ERROR( CV_StsUnsupportedFormat, "" );
    473 
    474         IPPI_CALL( func( src->data.ptr, src_step, dst->data.ptr, dst_step,
    475                          size, mask->data.ptr, mask_step ));
    476     }
    477 
    478     __END__;
    479 }
    480 
    481 
    482 /* dst(idx) = value */
    483 CV_IMPL void
    484 cvSet( void* arr, CvScalar value, const void* maskarr )
    485 {
    486     static CvBtFuncTable setm_tab;
    487     static int inittab = 0;
    488 
    489     CV_FUNCNAME( "cvSet" );
    490 
    491     __BEGIN__;
    492 
    493     CvMat stub, *mat = (CvMat*)arr;
    494     int pix_size, type;
    495     double buf[12];
    496     int mat_step;
    497     CvSize size;
    498 
    499     if( !value.val[0] && !value.val[1] &&
    500         !value.val[2] && !value.val[3] && !maskarr )
    501     {
    502         cvZero( arr );
    503         EXIT;
    504     }
    505 
    506     if( !CV_IS_MAT(mat))
    507     {
    508         if( CV_IS_MATND(mat))
    509         {
    510             CvMatND nstub;
    511             CvNArrayIterator iterator;
    512             int pix_size1;
    513 
    514             CV_CALL( cvInitNArrayIterator( 1, &arr, maskarr, &nstub, &iterator ));
    515 
    516             type = CV_MAT_TYPE(iterator.hdr[0]->type);
    517             pix_size1 = CV_ELEM_SIZE1(type);
    518             pix_size = pix_size1*CV_MAT_CN(type);
    519 
    520             CV_CALL( cvScalarToRawData( &value, buf, type, maskarr == 0 ));
    521 
    522             if( !maskarr )
    523             {
    524                 iterator.size.width *= pix_size;
    525                 do
    526                 {
    527                     icvSet_8u_C1R( iterator.ptr[0], CV_STUB_STEP,
    528                                    iterator.size, buf, pix_size1 );
    529                 }
    530                 while( cvNextNArraySlice( &iterator ));
    531             }
    532             else
    533             {
    534                 CvFunc2D_2A1P func = (CvFunc2D_2A1P)(setm_tab.fn_2d[pix_size]);
    535                 if( !func )
    536                     CV_ERROR( CV_StsUnsupportedFormat, "" );
    537 
    538                 do
    539                 {
    540                     func( iterator.ptr[0], CV_STUB_STEP,
    541                           iterator.ptr[1], CV_STUB_STEP,
    542                           iterator.size, buf );
    543                 }
    544                 while( cvNextNArraySlice( &iterator ));
    545             }
    546             EXIT;
    547         }
    548         else
    549         {
    550             int coi = 0;
    551             CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
    552 
    553             if( coi != 0 )
    554                 CV_ERROR( CV_BadCOI, "" );
    555         }
    556     }
    557 
    558     type = CV_MAT_TYPE( mat->type );
    559     pix_size = CV_ELEM_SIZE(type);
    560     size = cvGetMatSize( mat );
    561     mat_step = mat->step;
    562 
    563     if( !maskarr )
    564     {
    565         if( CV_IS_MAT_CONT( mat->type ))
    566         {
    567             size.width *= size.height;
    568 
    569             if( size.width <= (int)(CV_MAX_INLINE_MAT_OP_SIZE*sizeof(double)))
    570             {
    571                 if( type == CV_32FC1 )
    572                 {
    573                     float* dstdata = (float*)(mat->data.ptr);
    574                     float val = (float)value.val[0];
    575 
    576                     do
    577                     {
    578                         dstdata[size.width-1] = val;
    579                     }
    580                     while( --size.width );
    581 
    582                     EXIT;
    583                 }
    584 
    585                 if( type == CV_64FC1 )
    586                 {
    587                     double* dstdata = (double*)(mat->data.ptr);
    588                     double val = value.val[0];
    589 
    590                     do
    591                     {
    592                         dstdata[size.width-1] = val;
    593                     }
    594                     while( --size.width );
    595 
    596                     EXIT;
    597                 }
    598             }
    599 
    600             mat_step = CV_STUB_STEP;
    601             size.height = 1;
    602         }
    603 
    604         size.width *= pix_size;
    605         CV_CALL( cvScalarToRawData( &value, buf, type, 1 ));
    606 
    607         IPPI_CALL( icvSet_8u_C1R( mat->data.ptr, mat_step, size, buf,
    608                                   CV_ELEM_SIZE1(type)));
    609     }
    610     else
    611     {
    612         CvFunc2D_2A1P func;
    613         CvMat maskstub, *mask = (CvMat*)maskarr;
    614         int mask_step;
    615 
    616         CV_CALL( mask = cvGetMat( mask, &maskstub ));
    617 
    618         if( !CV_IS_MASK_ARR( mask ))
    619             CV_ERROR( CV_StsBadMask, "" );
    620 
    621         if( !inittab )
    622         {
    623             icvInitSetMRTable( &setm_tab );
    624             inittab = 1;
    625         }
    626 
    627         if( !CV_ARE_SIZES_EQ( mat, mask ))
    628             CV_ERROR( CV_StsUnmatchedSizes, "" );
    629 
    630         mask_step = mask->step;
    631 
    632         if( CV_IS_MAT_CONT( mat->type & mask->type ))
    633         {
    634             size.width *= size.height;
    635             mat_step = mask_step = CV_STUB_STEP;
    636             size.height = 1;
    637         }
    638 
    639         func = (CvFunc2D_2A1P)(setm_tab.fn_2d[pix_size]);
    640         if( !func )
    641             CV_ERROR( CV_StsUnsupportedFormat, "" );
    642 
    643         CV_CALL( cvScalarToRawData( &value, buf, type, 0 ));
    644 
    645         IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr,
    646                          mask_step, size, buf ));
    647     }
    648 
    649     __END__;
    650 }
    651 
    652 
    653 /****************************************************************************************\
    654 *                                          Clearing                                      *
    655 \****************************************************************************************/
    656 
    657 icvSetByte_8u_C1R_t icvSetByte_8u_C1R_p = 0;
    658 
    659 CvStatus CV_STDCALL
    660 icvSetZero_8u_C1R( uchar* dst, int dststep, CvSize size )
    661 {
    662     if( size.width + size.height > 256 && icvSetByte_8u_C1R_p )
    663         return icvSetByte_8u_C1R_p( 0, dst, dststep, size );
    664 
    665     for( ; size.height--; dst += dststep )
    666         memset( dst, 0, size.width );
    667 
    668     return CV_OK;
    669 }
    670 
    671 CV_IMPL void
    672 cvSetZero( CvArr* arr )
    673 {
    674     CV_FUNCNAME( "cvSetZero" );
    675 
    676     __BEGIN__;
    677 
    678     CvMat stub, *mat = (CvMat*)arr;
    679     CvSize size;
    680     int mat_step;
    681 
    682     if( !CV_IS_MAT( mat ))
    683     {
    684         if( CV_IS_MATND(mat))
    685         {
    686             CvMatND nstub;
    687             CvNArrayIterator iterator;
    688 
    689             CV_CALL( cvInitNArrayIterator( 1, &arr, 0, &nstub, &iterator ));
    690             iterator.size.width *= CV_ELEM_SIZE(iterator.hdr[0]->type);
    691 
    692             if( iterator.size.width <= CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double) )
    693             {
    694                 do
    695                 {
    696                     memset( iterator.ptr[0], 0, iterator.size.width );
    697                 }
    698                 while( cvNextNArraySlice( &iterator ));
    699             }
    700             else
    701             {
    702                 do
    703                 {
    704                     icvSetZero_8u_C1R( iterator.ptr[0], CV_STUB_STEP, iterator.size );
    705                 }
    706                 while( cvNextNArraySlice( &iterator ));
    707             }
    708             EXIT;
    709         }
    710         else if( CV_IS_SPARSE_MAT(mat))
    711         {
    712             CvSparseMat* mat1 = (CvSparseMat*)mat;
    713             cvClearSet( mat1->heap );
    714             if( mat1->hashtable )
    715                 memset( mat1->hashtable, 0, mat1->hashsize*sizeof(mat1->hashtable[0]));
    716             EXIT;
    717         }
    718         else
    719         {
    720             int coi = 0;
    721             CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
    722             if( coi != 0 )
    723                 CV_ERROR( CV_BadCOI, "coi is not supported" );
    724         }
    725     }
    726 
    727     size = cvGetMatSize( mat );
    728     size.width *= CV_ELEM_SIZE(mat->type);
    729     mat_step = mat->step;
    730 
    731     if( CV_IS_MAT_CONT( mat->type ))
    732     {
    733         size.width *= size.height;
    734 
    735         if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double) )
    736         {
    737             memset( mat->data.ptr, 0, size.width );
    738             EXIT;
    739         }
    740 
    741         mat_step = CV_STUB_STEP;
    742         size.height = 1;
    743     }
    744 
    745     IPPI_CALL( icvSetZero_8u_C1R( mat->data.ptr, mat_step, size ));
    746 
    747     __END__;
    748 }
    749 
    750 
    751 /****************************************************************************************\
    752 *                                          Flipping                                      *
    753 \****************************************************************************************/
    754 
    755 #define ICV_DEF_FLIP_HZ_CASE_C1( type ) \
    756     for( i = 0; i < (len+1)/2; i++ )    \
    757     {                                   \
    758         type t0 = src[i];               \
    759         type t1 = src[len - i - 1];     \
    760         dst[i] = t1;                    \
    761         dst[len - i - 1] = t0;          \
    762     }
    763 
    764 
    765 #define ICV_DEF_FLIP_HZ_CASE_C3( type ) \
    766     for( i = 0; i < (len+1)/2; i++ )    \
    767     {                                   \
    768         type t0 = src[i*3];             \
    769         type t1 = src[(len - i)*3 - 3]; \
    770         dst[i*3] = t1;                  \
    771         dst[(len - i)*3 - 3] = t0;      \
    772         t0 = src[i*3 + 1];              \
    773         t1 = src[(len - i)*3 - 2];      \
    774         dst[i*3 + 1] = t1;              \
    775         dst[(len - i)*3 - 2] = t0;      \
    776         t0 = src[i*3 + 2];              \
    777         t1 = src[(len - i)*3 - 1];      \
    778         dst[i*3 + 2] = t1;              \
    779         dst[(len - i)*3 - 1] = t0;      \
    780     }
    781 
    782 
    783 #define ICV_DEF_FLIP_HZ_CASE_C4( type ) \
    784     for( i = 0; i < (len+1)/2; i++ )    \
    785     {                                   \
    786         type t0 = src[i*4];             \
    787         type t1 = src[(len - i)*4 - 4]; \
    788         dst[i*4] = t1;                  \
    789         dst[(len - i)*4 - 4] = t0;      \
    790         t0 = src[i*4 + 1];              \
    791         t1 = src[(len - i)*4 - 3];      \
    792         dst[i*4 + 1] = t1;              \
    793         dst[(len - i)*4 - 3] = t0;      \
    794         t0 = src[i*4 + 2];              \
    795         t1 = src[(len - i)*4 - 2];      \
    796         dst[i*4 + 2] = t1;              \
    797         dst[(len - i)*4 - 2] = t0;      \
    798         t0 = src[i*4 + 3];              \
    799         t1 = src[(len - i)*4 - 1];      \
    800         dst[i*4 + 3] = t1;              \
    801         dst[(len - i)*4 - 1] = t0;      \
    802     }
    803 
    804 
    805 #define ICV_DEF_FLIP_HZ_FUNC( flavor, arrtype, cn )                 \
    806 static CvStatus CV_STDCALL                                          \
    807 icvFlipHorz_##flavor( const arrtype* src, int srcstep,              \
    808                       arrtype* dst, int dststep, CvSize size )      \
    809 {                                                                   \
    810     int i, len = size.width;                                        \
    811     srcstep /= sizeof(src[0]); dststep /= sizeof(dst[0]);           \
    812                                                                     \
    813     for( ; size.height--; src += srcstep, dst += dststep )          \
    814     {                                                               \
    815         ICV_DEF_FLIP_HZ_CASE_C##cn( arrtype )                       \
    816     }                                                               \
    817                                                                     \
    818     return CV_OK;                                                   \
    819 }
    820 
    821 
    822 ICV_DEF_FLIP_HZ_FUNC( 8u_C1R, uchar, 1 )
    823 ICV_DEF_FLIP_HZ_FUNC( 8u_C2R, ushort, 1 )
    824 ICV_DEF_FLIP_HZ_FUNC( 8u_C3R, uchar, 3 )
    825 ICV_DEF_FLIP_HZ_FUNC( 16u_C2R, int, 1 )
    826 ICV_DEF_FLIP_HZ_FUNC( 16u_C3R, ushort, 3 )
    827 ICV_DEF_FLIP_HZ_FUNC( 32s_C2R, int64, 1 )
    828 ICV_DEF_FLIP_HZ_FUNC( 32s_C3R, int, 3 )
    829 ICV_DEF_FLIP_HZ_FUNC( 64s_C2R, int, 4 )
    830 ICV_DEF_FLIP_HZ_FUNC( 64s_C3R, int64, 3 )
    831 ICV_DEF_FLIP_HZ_FUNC( 64s_C4R, int64, 4 )
    832 
    833 CV_DEF_INIT_PIXSIZE_TAB_2D( FlipHorz, R )
    834 
    835 
    836 static CvStatus
    837 icvFlipVert_8u_C1R( const uchar* src, int srcstep,
    838                     uchar* dst, int dststep, CvSize size )
    839 {
    840     int y, i;
    841     const uchar* src1 = src + (size.height - 1)*srcstep;
    842     uchar* dst1 = dst + (size.height - 1)*dststep;
    843 
    844     for( y = 0; y < (size.height + 1)/2; y++, src += srcstep, src1 -= srcstep,
    845                                               dst += dststep, dst1 -= dststep )
    846     {
    847         i = 0;
    848         if( ((size_t)(src)|(size_t)(dst)|(size_t)src1|(size_t)dst1) % sizeof(int) == 0 )
    849         {
    850             for( ; i <= size.width - 16; i += 16 )
    851             {
    852                 int t0 = ((int*)(src + i))[0];
    853                 int t1 = ((int*)(src1 + i))[0];
    854 
    855                 ((int*)(dst + i))[0] = t1;
    856                 ((int*)(dst1 + i))[0] = t0;
    857 
    858                 t0 = ((int*)(src + i))[1];
    859                 t1 = ((int*)(src1 + i))[1];
    860 
    861                 ((int*)(dst + i))[1] = t1;
    862                 ((int*)(dst1 + i))[1] = t0;
    863 
    864                 t0 = ((int*)(src + i))[2];
    865                 t1 = ((int*)(src1 + i))[2];
    866 
    867                 ((int*)(dst + i))[2] = t1;
    868                 ((int*)(dst1 + i))[2] = t0;
    869 
    870                 t0 = ((int*)(src + i))[3];
    871                 t1 = ((int*)(src1 + i))[3];
    872 
    873                 ((int*)(dst + i))[3] = t1;
    874                 ((int*)(dst1 + i))[3] = t0;
    875             }
    876 
    877             for( ; i <= size.width - 4; i += 4 )
    878             {
    879                 int t0 = ((int*)(src + i))[0];
    880                 int t1 = ((int*)(src1 + i))[0];
    881 
    882                 ((int*)(dst + i))[0] = t1;
    883                 ((int*)(dst1 + i))[0] = t0;
    884             }
    885         }
    886 
    887         for( ; i < size.width; i++ )
    888         {
    889             uchar t0 = src[i];
    890             uchar t1 = src1[i];
    891 
    892             dst[i] = t1;
    893             dst1[i] = t0;
    894         }
    895     }
    896 
    897     return CV_OK;
    898 }
    899 
    900 
    901 CV_IMPL void
    902 cvFlip( const CvArr* srcarr, CvArr* dstarr, int flip_mode )
    903 {
    904     static CvBtFuncTable tab;
    905     static int inittab = 0;
    906 
    907     CV_FUNCNAME( "cvFlip" );
    908 
    909     __BEGIN__;
    910 
    911     CvMat sstub, *src = (CvMat*)srcarr;
    912     CvMat dstub, *dst = (CvMat*)dstarr;
    913     CvSize size;
    914     CvFunc2D_2A func = 0;
    915     int pix_size;
    916 
    917     if( !inittab )
    918     {
    919         icvInitFlipHorzRTable( &tab );
    920         inittab = 1;
    921     }
    922 
    923     if( !CV_IS_MAT( src ))
    924     {
    925         int coi = 0;
    926         CV_CALL( src = cvGetMat( src, &sstub, &coi ));
    927         if( coi != 0 )
    928             CV_ERROR( CV_BadCOI, "coi is not supported" );
    929     }
    930 
    931     if( !dst )
    932         dst = src;
    933     else if( !CV_IS_MAT( dst ))
    934     {
    935         int coi = 0;
    936         CV_CALL( dst = cvGetMat( dst, &dstub, &coi ));
    937         if( coi != 0 )
    938             CV_ERROR( CV_BadCOI, "coi is not supported" );
    939     }
    940 
    941     if( !CV_ARE_TYPES_EQ( src, dst ))
    942         CV_ERROR( CV_StsUnmatchedFormats, "" );
    943 
    944     if( !CV_ARE_SIZES_EQ( src, dst ))
    945         CV_ERROR( CV_StsUnmatchedSizes, "" );
    946 
    947     size = cvGetMatSize( src );
    948     pix_size = CV_ELEM_SIZE( src->type );
    949 
    950     if( flip_mode == 0 )
    951     {
    952         size.width *= pix_size;
    953 
    954         IPPI_CALL( icvFlipVert_8u_C1R( src->data.ptr, src->step,
    955                                        dst->data.ptr, dst->step, size ));
    956     }
    957     else
    958     {
    959         int inplace = src->data.ptr == dst->data.ptr;
    960         uchar* dst_data = dst->data.ptr;
    961         int dst_step = dst->step;
    962 
    963         func = (CvFunc2D_2A)(tab.fn_2d[pix_size]);
    964 
    965         if( !func )
    966             CV_ERROR( CV_StsUnsupportedFormat, "" );
    967 
    968         if( flip_mode < 0 && !inplace )
    969         {
    970             dst_data += dst_step * (dst->height - 1);
    971             dst_step = -dst_step;
    972         }
    973 
    974         IPPI_CALL( func( src->data.ptr, src->step, dst_data, dst_step, size ));
    975 
    976         if( flip_mode < 0 && inplace )
    977         {
    978             size.width *= pix_size;
    979             IPPI_CALL( icvFlipVert_8u_C1R( dst->data.ptr, dst->step,
    980                                            dst->data.ptr, dst->step, size ));
    981         }
    982     }
    983 
    984     __END__;
    985 }
    986 
    987 
    988 CV_IMPL void
    989 cvRepeat( const CvArr* srcarr, CvArr* dstarr )
    990 {
    991     CV_FUNCNAME( "cvRepeat" );
    992 
    993     __BEGIN__;
    994 
    995     CvMat sstub, *src = (CvMat*)srcarr;
    996     CvMat dstub, *dst = (CvMat*)dstarr;
    997     CvSize srcsize, dstsize;
    998     int pix_size;
    999     int x, y, k, l;
   1000 
   1001     if( !CV_IS_MAT( src ))
   1002     {
   1003         int coi = 0;
   1004         CV_CALL( src = cvGetMat( src, &sstub, &coi ));
   1005         if( coi != 0 )
   1006             CV_ERROR( CV_BadCOI, "coi is not supported" );
   1007     }
   1008 
   1009     if( !CV_IS_MAT( dst ))
   1010     {
   1011         int coi = 0;
   1012         CV_CALL( dst = cvGetMat( dst, &dstub, &coi ));
   1013         if( coi != 0 )
   1014             CV_ERROR( CV_BadCOI, "coi is not supported" );
   1015     }
   1016 
   1017     if( !CV_ARE_TYPES_EQ( src, dst ))
   1018         CV_ERROR( CV_StsUnmatchedFormats, "" );
   1019 
   1020     srcsize = cvGetMatSize( src );
   1021     dstsize = cvGetMatSize( dst );
   1022     pix_size = CV_ELEM_SIZE( src->type );
   1023 
   1024     for( y = 0, k = 0; y < dstsize.height; y++ )
   1025     {
   1026         for( x = 0; x < dstsize.width; x += srcsize.width )
   1027         {
   1028             l = srcsize.width;
   1029             if( l > dstsize.width - x )
   1030                 l = dstsize.width - x;
   1031             memcpy( dst->data.ptr + y*dst->step + x*pix_size,
   1032                     src->data.ptr + k*src->step, l*pix_size );
   1033         }
   1034         if( ++k == srcsize.height )
   1035             k = 0;
   1036     }
   1037 
   1038     __END__;
   1039 }
   1040 
   1041 /* End of file. */
   1042 
   1043