16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cv.h"
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <limits.h>
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <stdio.h>
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define IPCV_MORPHOLOGY_PTRS( morphtype, flavor )               \
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icv##morphtype##Rect_##flavor##_C1R_t                       \
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icv##morphtype##Rect_##flavor##_C1R_p = 0;              \
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icv##morphtype##Rect_GetBufSize_##flavor##_C1R_t            \
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icv##morphtype##Rect_GetBufSize_##flavor##_C1R_p = 0;   \
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icv##morphtype##Rect_##flavor##_C3R_t                       \
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icv##morphtype##Rect_##flavor##_C3R_p = 0;              \
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icv##morphtype##Rect_GetBufSize_##flavor##_C3R_t            \
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icv##morphtype##Rect_GetBufSize_##flavor##_C3R_p = 0;   \
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icv##morphtype##Rect_##flavor##_C4R_t                       \
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icv##morphtype##Rect_##flavor##_C4R_p = 0;              \
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icv##morphtype##Rect_GetBufSize_##flavor##_C4R_t            \
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icv##morphtype##Rect_GetBufSize_##flavor##_C4R_p = 0;   \
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                \
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icv##morphtype##_##flavor##_C1R_t                           \
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icv##morphtype##_##flavor##_C1R_p = 0;                  \
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icv##morphtype##_##flavor##_C3R_t                           \
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icv##morphtype##_##flavor##_C3R_p = 0;                  \
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icv##morphtype##_##flavor##_C4R_t                           \
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icv##morphtype##_##flavor##_C4R_p = 0;
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define IPCV_MORPHOLOGY_INITALLOC_PTRS( flavor )                \
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvMorphInitAlloc_##flavor##_C1R_t                          \
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvMorphInitAlloc_##flavor##_C1R_p = 0;                 \
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvMorphInitAlloc_##flavor##_C3R_t                          \
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvMorphInitAlloc_##flavor##_C3R_p = 0;                 \
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvMorphInitAlloc_##flavor##_C4R_t                          \
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvMorphInitAlloc_##flavor##_C4R_p = 0;
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_MORPHOLOGY_PTRS( Erode, 8u )
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_MORPHOLOGY_PTRS( Erode, 16u )
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_MORPHOLOGY_PTRS( Erode, 32f )
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_MORPHOLOGY_PTRS( Dilate, 8u )
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_MORPHOLOGY_PTRS( Dilate, 16u )
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_MORPHOLOGY_PTRS( Dilate, 32f )
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_MORPHOLOGY_INITALLOC_PTRS( 8u )
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_MORPHOLOGY_INITALLOC_PTRS( 16u )
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_MORPHOLOGY_INITALLOC_PTRS( 32f )
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvMorphFree_t icvMorphFree_p = 0;
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     Basic Morphological Operations: Erosion & Dilation
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvErodeRectRow_8u( const uchar* src, uchar* dst, void* params );
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvErodeRectRow_16u( const ushort* src, ushort* dst, void* params );
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvErodeRectRow_32f( const int* src, int* dst, void* params );
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvDilateRectRow_8u( const uchar* src, uchar* dst, void* params );
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvDilateRectRow_16u( const ushort* src, ushort* dst, void* params );
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvDilateRectRow_32f( const int* src, int* dst, void* params );
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvErodeRectCol_8u( const uchar** src, uchar* dst, int dst_step,
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                int count, void* params );
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvErodeRectCol_16u( const ushort** src, ushort* dst, int dst_step,
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 int count, void* params );
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvErodeRectCol_32f( const int** src, int* dst, int dst_step,
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 int count, void* params );
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvDilateRectCol_8u( const uchar** src, uchar* dst, int dst_step,
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 int count, void* params );
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvDilateRectCol_16u( const ushort** src, ushort* dst, int dst_step,
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  int count, void* params );
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvDilateRectCol_32f( const int** src, int* dst, int dst_step,
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  int count, void* params );
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvErodeAny_8u( const uchar** src, uchar* dst, int dst_step,
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int count, void* params );
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvErodeAny_16u( const ushort** src, ushort* dst, int dst_step,
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             int count, void* params );
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvErodeAny_32f( const int** src, int* dst, int dst_step,
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             int count, void* params );
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvDilateAny_8u( const uchar** src, uchar* dst, int dst_step,
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             int count, void* params );
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvDilateAny_16u( const ushort** src, ushort* dst, int dst_step,
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              int count, void* params );
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvDilateAny_32f( const int** src, int* dst, int dst_step,
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              int count, void* params );
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvMorphology::CvMorphology()
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    element = 0;
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    el_sparse = 0;
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvMorphology::CvMorphology( int _operation, int _max_width, int _src_dst_type,
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int _element_shape, CvMat* _element,
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvSize _ksize, CvPoint _anchor,
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int _border_mode, CvScalar _border_value )
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    element = 0;
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    el_sparse = 0;
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    init( _operation, _max_width, _src_dst_type,
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn          _element_shape, _element, _ksize, _anchor,
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn          _border_mode, _border_value );
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvMorphology::clear()
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat( &element );
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &el_sparse );
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvBaseImageFilter::clear();
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvMorphology::~CvMorphology()
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    clear();
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvMorphology::init( int _operation, int _max_width, int _src_dst_type,
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         int _element_shape, CvMat* _element,
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         CvSize _ksize, CvPoint _anchor,
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         int _border_mode, CvScalar _border_value )
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "CvMorphology::init" );
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int depth = CV_MAT_DEPTH(_src_dst_type);
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int el_type = 0, nz = -1;
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( _operation != ERODE && _operation != DILATE )
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Unknown/unsupported morphological operation" );
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( _element_shape == CUSTOM )
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !CV_IS_MAT(_element) )
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg,
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "structuring element should be valid matrix if CUSTOM element shape is specified" );
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_type = CV_MAT_TYPE(_element->type);
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( el_type != CV_8UC1 && el_type != CV_32SC1 )
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnsupportedFormat, "the structuring element must have 8uC1 or 32sC1 type" );
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        _ksize = cvGetMatSize(_element);
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( nz = cvCountNonZero(_element));
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( nz == _ksize.width*_ksize.height )
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _element_shape = RECT;
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    operation = _operation;
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    el_shape = _element_shape;
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( CvBaseImageFilter::init( _max_width, _src_dst_type, _src_dst_type,
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        _element_shape == RECT, _ksize, _anchor, _border_mode, _border_value ));
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( el_shape == RECT )
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( operation == ERODE )
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( depth == CV_8U )
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x_func = (CvRowFilterFunc)icvErodeRectRow_8u,
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvErodeRectCol_8u;
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( depth == CV_16U )
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x_func = (CvRowFilterFunc)icvErodeRectRow_16u,
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvErodeRectCol_16u;
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( depth == CV_32F )
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x_func = (CvRowFilterFunc)icvErodeRectRow_32f,
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvErodeRectCol_32f;
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( operation == DILATE );
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( depth == CV_8U )
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x_func = (CvRowFilterFunc)icvDilateRectRow_8u,
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvDilateRectCol_8u;
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( depth == CV_16U )
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x_func = (CvRowFilterFunc)icvDilateRectRow_16u,
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvDilateRectCol_16u;
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( depth == CV_32F )
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x_func = (CvRowFilterFunc)icvDilateRectRow_32f,
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvDilateRectCol_32f;
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int i, j, k = 0;
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int cn = CV_MAT_CN(src_type);
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPoint* nz_loc;
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !(element && el_sparse &&
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _ksize.width == element->cols && _ksize.height == element->rows) )
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvReleaseMat( &element );
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &el_sparse );
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( element = cvCreateMat( _ksize.height, _ksize.width, CV_8UC1 ));
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( el_sparse = (uchar*)cvAlloc(
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ksize.width*ksize.height*(2*sizeof(int) + sizeof(uchar*))));
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( el_shape == CUSTOM )
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( cvConvert( _element, element ));
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( init_binary_element( element, el_shape, anchor ));
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( operation == ERODE )
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( depth == CV_8U )
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvErodeAny_8u;
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( depth == CV_16U )
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvErodeAny_16u;
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( depth == CV_32F )
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvErodeAny_32f;
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( operation == DILATE );
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( depth == CV_8U )
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvDilateAny_8u;
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( depth == CV_16U )
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvDilateAny_16u;
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( depth == CV_32F )
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y_func = (CvColumnFilterFunc)icvDilateAny_32f;
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        nz_loc = (CvPoint*)el_sparse;
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < ksize.height; i++ )
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < ksize.width; j++ )
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( element->data.ptr[i*element->step+j] )
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    nz_loc[k++] = cvPoint(j*cn,i);
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( k == 0 )
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            nz_loc[k++] = cvPoint(anchor.x*cn,anchor.y);
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_sparse_count = k;
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( depth == CV_32F && border_mode == IPL_BORDER_CONSTANT )
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int i, cn = CV_MAT_CN(src_type);
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int* bt = (int*)border_tab;
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < cn; i++ )
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            bt[i] = CV_TOGGLE_FLT(bt[i]);
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvMorphology::init( int _max_width, int _src_type, int _dst_type,
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         bool _is_separable, CvSize _ksize,
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         CvPoint _anchor, int _border_mode,
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         CvScalar _border_value )
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvBaseImageFilter::init( _max_width, _src_type, _dst_type, _is_separable,
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             _ksize, _anchor, _border_mode, _border_value );
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvMorphology::start_process( CvSlice x_range, int width )
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvBaseImageFilter::start_process( x_range, width );
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( el_shape == RECT )
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // cut the cyclic buffer off by 1 line if need, to make
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // the vertical part of separable morphological filter
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // always process 2 rows at once (except, may be,
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // for the last one in a stripe).
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int t = buf_max_count - max_ky*2;
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( t > 1 && t % 2 != 0 )
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf_max_count--;
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf_end -= buf_step;
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennint CvMorphology::fill_cyclic_buffer( const uchar* src, int src_step,
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      int y0, int y1, int y2 )
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, y = y0, bsz1 = border_tab_sz1, bsz = border_tab_sz;
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int pix_size = CV_ELEM_SIZE(src_type);
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int width_n = (prev_x_range.end_index - prev_x_range.start_index)*pix_size;
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CV_MAT_DEPTH(src_type) != CV_32F )
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CvBaseImageFilter::fill_cyclic_buffer( src, src_step, y0, y1, y2 );
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // fill the cyclic buffer
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( ; buf_count < buf_max_count && y < y2; buf_count++, y++, src += src_step )
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        uchar* trow = is_separable ? buf_end : buf_tail;
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < width_n; i += sizeof(int) )
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int t = *(int*)(src + i);
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *(int*)(trow + i + bsz1) = CV_TOGGLE_FLT(t);
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( border_mode != IPL_BORDER_CONSTANT )
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < bsz1; i++ )
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int j = border_tab[i];
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                trow[i] = trow[j];
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; i < bsz; i++ )
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int j = border_tab[i];
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                trow[i + width_n] = trow[j];
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const uchar *bt = (uchar*)border_tab;
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < bsz1; i++ )
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                trow[i] = bt[i];
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; i < bsz; i++ )
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                trow[i + width_n] = bt[i];
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( is_separable )
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x_func( trow, buf_tail, this );
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buf_tail += buf_step;
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buf_tail >= buf_end )
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf_tail = buf_start;
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return y - y0;
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvMorphology::init_binary_element( CvMat* element, int element_shape, CvPoint anchor )
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "CvMorphology::init_binary_element" );
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int type;
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, cols, rows;
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int r = 0, c = 0;
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double inv_r2 = 0;
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(element) )
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "element must be valid matrix" );
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    type = CV_MAT_TYPE(element->type);
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( type != CV_8UC1 && type != CV_32SC1 )
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "element must have 8uC1 or 32sC1 type" );
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( anchor.x == -1 )
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        anchor.x = element->cols/2;
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( anchor.y == -1 )
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        anchor.y = element->rows/2;
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (unsigned)anchor.x >= (unsigned)element->cols ||
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (unsigned)anchor.y >= (unsigned)element->rows )
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "anchor is outside of element" );
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( element_shape != RECT && element_shape != CROSS && element_shape != ELLIPSE )
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Unknown/unsupported element shape" );
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    rows = element->rows;
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cols = element->cols;
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( rows == 1 || cols == 1 )
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        element_shape = RECT;
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( element_shape == ELLIPSE )
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        r = rows/2;
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        c = cols/2;
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inv_r2 = r ? 1./((double)r*r) : 0;
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < rows; i++ )
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        uchar* ptr = element->data.ptr + i*element->step;
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int j1 = 0, j2 = 0, jx, t = 0;
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( element_shape == RECT || (element_shape == CROSS && i == anchor.y) )
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            j2 = cols;
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( element_shape == CROSS )
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            j1 = anchor.x, j2 = j1 + 1;
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int dy = i - r;
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( abs(dy) <= r )
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int dx = cvRound(c*sqrt(((double)r*r - dy*dy)*inv_r2));
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                j1 = MAX( c - dx, 0 );
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                j2 = MIN( c + dx + 1, cols );
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0, jx = j1; j < cols; )
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; j < jx; j++ )
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( type == CV_8UC1 )
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ptr[j] = (uchar)t;
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ((int*)ptr)[j] = t;
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( jx == j2 )
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                jx = cols, t = 0;
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                jx = j2, t = 1;
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_MORPH_RECT_ROW( name, flavor, arrtype,          \
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            worktype, update_extr_macro )   \
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void                                                 \
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennicv##name##RectRow_##flavor( const arrtype* src,            \
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             arrtype* dst, void* params )   \
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                           \
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvMorphology* state = (const CvMorphology*)params;\
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ksize = state->get_kernel_size().width;             \
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int width = state->get_width();                         \
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cn = CV_MAT_CN(state->get_src_type());              \
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, k;                                            \
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    width *= cn; ksize *= cn;                               \
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ksize == cn )                                       \
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                       \
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < width; i++ )                        \
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = src[i];                                \
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return;                                             \
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                       \
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( k = 0; k < cn; k++, src++, dst++ )                 \
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                       \
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= width - cn*2; i += cn*2 )          \
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                   \
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype* s = src + i;                     \
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype m = s[cn], t;                          \
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = cn*2; j < ksize; j += cn )             \
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                               \
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t = s[j]; update_extr_macro(m,t);           \
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                               \
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t = s[0]; update_extr_macro(t,m);               \
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = (arrtype)t;                            \
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t = s[j]; update_extr_macro(t,m);               \
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+cn] = (arrtype)t;                         \
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                   \
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; i < width; i += cn )                         \
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                   \
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype* s = src + i;                     \
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype m = s[0], t;                           \
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = cn; j < ksize; j += cn )               \
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                               \
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t = s[j]; update_extr_macro(m,t);           \
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                               \
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = (arrtype)m;                            \
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                   \
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                       \
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_ROW( Erode, 8u, uchar, int, CV_CALC_MIN_8U )
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_ROW( Dilate, 8u, uchar, int, CV_CALC_MAX_8U )
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_ROW( Erode, 16u, ushort, int, CV_CALC_MIN )
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_ROW( Dilate, 16u, ushort, int, CV_CALC_MAX )
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_ROW( Erode, 32f, int, int, CV_CALC_MIN )
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_ROW( Dilate, 32f, int, int, CV_CALC_MAX )
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_MORPH_RECT_COL( name, flavor, arrtype,          \
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        worktype, update_extr_macro, toggle_macro )         \
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void                                                 \
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennicv##name##RectCol_##flavor( const arrtype** src,           \
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    arrtype* dst, int dst_step, int count, void* params )   \
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                           \
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvMorphology* state = (const CvMorphology*)params;\
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ksize = state->get_kernel_size().height;            \
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int width = state->get_width();                         \
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cn = CV_MAT_CN(state->get_src_type());              \
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, k;                                               \
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    width *= cn;                                            \
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_step /= sizeof(dst[0]);                             \
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( ; ksize > 1 && count > 1; count -= 2,              \
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst += dst_step*2, src += 2 )       \
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                       \
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= width - 4; i += 4 )                \
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                   \
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype* sptr = src[1] + i;               \
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype s0 = sptr[0], s1 = sptr[1],            \
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s2 = sptr[2], s3 = sptr[3], t0, t1;         \
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 2; k < ksize; k++ )                    \
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                               \
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sptr = src[k] + i;                          \
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t0 = sptr[0]; t1 = sptr[1];                 \
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s0,t0);                   \
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s1,t1);                   \
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t0 = sptr[2]; t1 = sptr[3];                 \
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s2,t0);                   \
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s3,t1);                   \
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                               \
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sptr = src[0] + i;                              \
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = sptr[0]; t1 = sptr[1];                     \
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            update_extr_macro(t0,s0);                       \
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            update_extr_macro(t1,s1);                       \
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = (arrtype)toggle_macro(t0);             \
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+1] = (arrtype)toggle_macro(t1);           \
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = sptr[2]; t1 = sptr[3];                     \
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            update_extr_macro(t0,s2);                       \
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            update_extr_macro(t1,s3);                       \
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+2] = (arrtype)toggle_macro(t0);           \
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+3] = (arrtype)toggle_macro(t1);           \
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sptr = src[k] + i;                              \
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = sptr[0]; t1 = sptr[1];                     \
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            update_extr_macro(t0,s0);                       \
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            update_extr_macro(t1,s1);                       \
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+dst_step] = (arrtype)toggle_macro(t0);    \
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+dst_step+1] = (arrtype)toggle_macro(t1);  \
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = sptr[2]; t1 = sptr[3];                     \
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            update_extr_macro(t0,s2);                       \
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            update_extr_macro(t1,s3);                       \
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+dst_step+2] = (arrtype)toggle_macro(t0);  \
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+dst_step+3] = (arrtype)toggle_macro(t1);  \
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                   \
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; i < width; i++ )                             \
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                   \
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype* sptr = src[1] + i;               \
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype s0 = sptr[0], t0;                      \
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 2; k < ksize; k++ )                    \
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                               \
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sptr = src[k] + i; t0 = sptr[0];            \
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s0,t0);                   \
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                               \
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sptr = src[0] + i; t0 = sptr[0];                \
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            update_extr_macro(t0,s0);                       \
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = (arrtype)toggle_macro(t0);             \
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sptr = src[k] + i; t0 = sptr[0];                \
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            update_extr_macro(t0,s0);                       \
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+dst_step] = (arrtype)toggle_macro(t0);    \
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                   \
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                       \
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( ; count > 0; count--, dst += dst_step, src++ )     \
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                       \
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= width - 4; i += 4 )                \
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                   \
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype* sptr = src[0] + i;               \
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype s0 = sptr[0], s1 = sptr[1],            \
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s2 = sptr[2], s3 = sptr[3], t0, t1;         \
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 1; k < ksize; k++ )                    \
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                               \
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sptr = src[k] + i;                          \
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t0 = sptr[0]; t1 = sptr[1];                 \
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s0,t0);                   \
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s1,t1);                   \
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t0 = sptr[2]; t1 = sptr[3];                 \
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s2,t0);                   \
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s3,t1);                   \
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                               \
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = (arrtype)toggle_macro(s0);             \
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+1] = (arrtype)toggle_macro(s1);           \
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+2] = (arrtype)toggle_macro(s2);           \
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+3] = (arrtype)toggle_macro(s3);           \
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                   \
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; i < width; i++ )                             \
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                   \
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype* sptr = src[0] + i;               \
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype s0 = sptr[0], t0;                      \
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 1; k < ksize; k++ )                    \
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                               \
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sptr = src[k] + i; t0 = sptr[0];            \
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s0,t0);                   \
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                               \
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = (arrtype)toggle_macro(s0);             \
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                   \
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                       \
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_COL( Erode, 8u, uchar, int, CV_CALC_MIN_8U, CV_NOP )
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_COL( Dilate, 8u, uchar, int, CV_CALC_MAX_8U, CV_NOP )
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_COL( Erode, 16u, ushort, int, CV_CALC_MIN, CV_NOP )
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_COL( Dilate, 16u, ushort, int, CV_CALC_MAX, CV_NOP )
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_COL( Erode, 32f, int, int, CV_CALC_MIN, CV_TOGGLE_FLT )
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_RECT_COL( Dilate, 32f, int, int, CV_CALC_MAX, CV_TOGGLE_FLT )
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_MORPH_ANY( name, flavor, arrtype, worktype,     \
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       update_extr_macro, toggle_macro )    \
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void                                                 \
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennicv##name##Any_##flavor( const arrtype** src, arrtype* dst, \
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int dst_step, int count, void* params ) \
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                           \
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMorphology* state = (CvMorphology*)params;            \
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int width = state->get_width();                         \
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cn = CV_MAT_CN(state->get_src_type());              \
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, k;                                               \
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint* el_sparse = (CvPoint*)state->get_element_sparse_buf();\
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int el_count = state->get_element_sparse_count();       \
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const arrtype** el_ptr = (const arrtype**)(el_sparse + el_count);\
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const arrtype** el_end = el_ptr + el_count;             \
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    width *= cn;                                            \
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_step /= sizeof(dst[0]);                             \
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( ; count > 0; count--, dst += dst_step, src++ )     \
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                       \
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( k = 0; k < el_count; k++ )                     \
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            el_ptr[k] = src[el_sparse[k].y]+el_sparse[k].x; \
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= width - 4; i += 4 )                \
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                   \
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype** psptr = el_ptr;                 \
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype* sptr = *psptr++;                 \
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype s0 = sptr[i], s1 = sptr[i+1],          \
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     s2 = sptr[i+2], s3 = sptr[i+3], t;     \
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( psptr != el_end )                        \
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                               \
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sptr = *psptr++;                            \
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t = sptr[i];                                \
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s0,t);                    \
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t = sptr[i+1];                              \
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s1,t);                    \
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t = sptr[i+2];                              \
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s2,t);                    \
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t = sptr[i+3];                              \
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s3,t);                    \
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                               \
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = (arrtype)toggle_macro(s0);             \
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+1] = (arrtype)toggle_macro(s1);           \
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+2] = (arrtype)toggle_macro(s2);           \
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+3] = (arrtype)toggle_macro(s3);           \
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                   \
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; i < width; i++ )                             \
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                   \
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype* sptr = el_ptr[0] + i;            \
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype s0 = sptr[0], t0;                      \
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 1; k < el_count; k++ )                 \
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                               \
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sptr = el_ptr[k] + i;                       \
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t0 = sptr[0];                               \
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                update_extr_macro(s0,t0);                   \
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                               \
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                            \
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = (arrtype)toggle_macro(s0);             \
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                   \
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                       \
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_ANY( Erode, 8u, uchar, int, CV_CALC_MIN, CV_NOP )
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_ANY( Dilate, 8u, uchar, int, CV_CALC_MAX, CV_NOP )
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_ANY( Erode, 16u, ushort, int, CV_CALC_MIN, CV_NOP )
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_ANY( Dilate, 16u, ushort, int, CV_CALC_MAX, CV_NOP )
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_ANY( Erode, 32f, int, int, CV_CALC_MIN, CV_TOGGLE_FLT )
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_MORPH_ANY( Dilate, 32f, int, int, CV_CALC_MAX, CV_TOGGLE_FLT )
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/////////////////////////////////// External Interface /////////////////////////////////////
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL IplConvKernel *
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCreateStructuringElementEx( int cols, int rows,
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              int anchorX, int anchorY,
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              int shape, int *values )
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    IplConvKernel *element = 0;
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, size = rows * cols;
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int element_size = sizeof(*element) + size*sizeof(element->values[0]);
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvCreateStructuringElementEx" );
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !values && shape == CV_SHAPE_CUSTOM )
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR_FROM_STATUS( CV_NULLPTR_ERR );
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cols <= 0 || rows <= 0 ||
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (unsigned) anchorX >= (unsigned) cols ||
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (unsigned) anchorY >= (unsigned) rows )
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR_FROM_STATUS( CV_BADSIZE_ERR );
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( element = (IplConvKernel *)cvAlloc(element_size + 32));
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !element )
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR_FROM_STATUS( CV_OUTOFMEM_ERR );
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    element->nCols = cols;
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    element->nRows = rows;
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    element->anchorX = anchorX;
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    element->anchorY = anchorY;
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    element->nShiftR = shape < CV_SHAPE_ELLIPSE ? shape : CV_SHAPE_CUSTOM;
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    element->values = (int*)(element + 1);
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( shape == CV_SHAPE_CUSTOM )
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !values )
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsNullPtr, "Null pointer to the custom element mask" );
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < size; i++ )
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            element->values[i] = values[i];
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat el_hdr = cvMat( rows, cols, CV_32SC1, element->values );
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( CvMorphology::init_binary_element(&el_hdr,
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        shape, cvPoint(anchorX,anchorY)));
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cvGetErrStatus() < 0 )
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseStructuringElement( &element );
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return element;
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvReleaseStructuringElement( IplConvKernel ** element )
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvReleaseStructuringElement" );
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !element )
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( element );
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvMorphRectGetBufSizeFunc_IPP)
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( int width, CvSize el_size, int* bufsize );
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvMorphRectFunc_IPP)
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( const void* src, int srcstep, void* dst, int dststep,
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      CvSize roi, CvSize el_size, CvPoint el_anchor, void* buffer );
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvMorphCustomInitAllocFunc_IPP)
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( int width, const uchar* element, CvSize el_size,
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      CvPoint el_anchor, void** morphstate );
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvMorphCustomFunc_IPP)
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( const void* src, int srcstep, void* dst, int dststep,
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      CvSize roi, int bordertype, void* morphstate );
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvMorphOp( const void* srcarr, void* dstarr, IplConvKernel* element,
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int iterations, int mop )
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMorphology morphology;
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* buffer = 0;
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int local_alloc = 0;
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* morphstate = 0;
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* temp = 0;
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "icvMorphOp" );
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, coi1 = 0, coi2 = 0;
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, *src = (CvMat*)srcarr;
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat dststub, *dst = (CvMat*)dstarr;
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat el_hdr, *el = 0;
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size, el_size;
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint el_anchor;
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int el_shape;
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int type;
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool inplace;
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(src) )
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( src = cvGetMat( src, &srcstub, &coi1 ));
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src != &srcstub )
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        srcstub = *src;
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src = &srcstub;
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dstarr == srcarr )
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst = src;
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 ));
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !CV_ARE_TYPES_EQ( src, dst ))
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedFormats, "" );
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !CV_ARE_SIZES_EQ( src, dst ))
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes, "" );
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst != &dststub )
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dststub = *dst;
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst = &dststub;
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi1 != 0 || coi2 != 0 )
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, "" );
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    type = CV_MAT_TYPE( src->type );
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size = cvGetMatSize( src );
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    inplace = src->data.ptr == dst->data.ptr;
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( iterations == 0 || (element && element->nCols == 1 && element->nRows == 1))
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( src->data.ptr != dst->data.ptr )
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvCopy( src, dst );
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        EXIT;
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( element )
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_size = cvSize( element->nCols, element->nRows );
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_anchor = cvPoint( element->anchorX, element->anchorY );
8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_shape = (int)(element->nShiftR);
8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_shape = el_shape < CV_SHAPE_CUSTOM ? el_shape : CV_SHAPE_CUSTOM;
8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_size = cvSize(3,3);
8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_anchor = cvPoint(1,1);
8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_shape = CV_SHAPE_RECT;
8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( el_shape == CV_SHAPE_RECT && iterations > 1 )
8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_size.width = 1 + (el_size.width-1)*iterations;
8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_size.height = 1 + (el_size.height-1)*iterations;
8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_anchor.x *= iterations;
8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_anchor.y *= iterations;
8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iterations = 1;
8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( el_shape == CV_SHAPE_RECT && icvErodeRect_GetBufSize_8u_C1R_p )
9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMorphRectFunc_IPP rect_func = 0;
9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMorphRectGetBufSizeFunc_IPP rect_getbufsize_func = 0;
9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( mop == 0 )
9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( type == CV_8UC1 )
9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvErodeRect_GetBufSize_8u_C1R_p,
9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvErodeRect_8u_C1R_p;
9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_8UC3 )
9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvErodeRect_GetBufSize_8u_C3R_p,
9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvErodeRect_8u_C3R_p;
9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_8UC4 )
9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvErodeRect_GetBufSize_8u_C4R_p,
9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvErodeRect_8u_C4R_p;
9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_16UC1 )
9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvErodeRect_GetBufSize_16u_C1R_p,
9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvErodeRect_16u_C1R_p;
9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_16UC3 )
9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvErodeRect_GetBufSize_16u_C3R_p,
9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvErodeRect_16u_C3R_p;
9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_16UC4 )
9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvErodeRect_GetBufSize_16u_C4R_p,
9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvErodeRect_16u_C4R_p;
9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_32FC1 )
9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvErodeRect_GetBufSize_32f_C1R_p,
9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvErodeRect_32f_C1R_p;
9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_32FC3 )
9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvErodeRect_GetBufSize_32f_C3R_p,
9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvErodeRect_32f_C3R_p;
9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_32FC4 )
9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvErodeRect_GetBufSize_32f_C4R_p,
9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvErodeRect_32f_C4R_p;
9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( type == CV_8UC1 )
9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvDilateRect_GetBufSize_8u_C1R_p,
9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvDilateRect_8u_C1R_p;
9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_8UC3 )
9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvDilateRect_GetBufSize_8u_C3R_p,
9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvDilateRect_8u_C3R_p;
9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_8UC4 )
9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvDilateRect_GetBufSize_8u_C4R_p,
9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvDilateRect_8u_C4R_p;
9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_16UC1 )
9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvDilateRect_GetBufSize_16u_C1R_p,
9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvDilateRect_16u_C1R_p;
9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_16UC3 )
9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvDilateRect_GetBufSize_16u_C3R_p,
9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvDilateRect_16u_C3R_p;
9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_16UC4 )
9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvDilateRect_GetBufSize_16u_C4R_p,
9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvDilateRect_16u_C4R_p;
9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_32FC1 )
9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvDilateRect_GetBufSize_32f_C1R_p,
9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvDilateRect_32f_C1R_p;
9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_32FC3 )
9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvDilateRect_GetBufSize_32f_C3R_p,
9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvDilateRect_32f_C3R_p;
9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( type == CV_32FC4 )
9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_getbufsize_func = icvDilateRect_GetBufSize_32f_C4R_p,
9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                rect_func = icvDilateRect_32f_C4R_p;
9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( rect_getbufsize_func && rect_func )
9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int bufsize = 0;
9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvStatus status = rect_getbufsize_func( size.width, el_size, &bufsize );
9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 && bufsize > 0 )
9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( bufsize < CV_MAX_LOCAL_SIZE )
9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buffer = cvStackAlloc( bufsize );
9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    local_alloc = 1;
9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_CALL( buffer = cvAlloc( bufsize ));
9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 )
9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int src_step, dst_step = dst->step ? dst->step : CV_STUB_STEP;
9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( inplace )
9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_CALL( temp = cvCloneMat( dst ));
9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    src = temp;
9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                src_step = src->step ? src->step : CV_STUB_STEP;
9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                status = rect_func( src->data.ptr, src_step, dst->data.ptr,
9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    dst_step, size, el_size, el_anchor, buffer );
9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 )
9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                EXIT;
9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( el_shape == CV_SHAPE_CUSTOM && icvMorphInitAlloc_8u_C1R_p && icvMorphFree_p &&
10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             src->data.ptr != dst->data.ptr )
10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMorphCustomFunc_IPP custom_func = 0;
10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMorphCustomInitAllocFunc_IPP custom_initalloc_func = 0;
10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const int bordertype = 1; // replication border
10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( type == CV_8UC1 )
10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_initalloc_func = icvMorphInitAlloc_8u_C1R_p,
10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_func = mop == 0 ? icvErode_8u_C1R_p : icvDilate_8u_C1R_p;
10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( type == CV_8UC3 )
10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_initalloc_func = icvMorphInitAlloc_8u_C3R_p,
10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_func = mop == 0 ? icvErode_8u_C3R_p : icvDilate_8u_C3R_p;
10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( type == CV_8UC4 )
10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_initalloc_func = icvMorphInitAlloc_8u_C4R_p,
10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_func = mop == 0 ? icvErode_8u_C4R_p : icvDilate_8u_C4R_p;
10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( type == CV_16UC1 )
10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_initalloc_func = icvMorphInitAlloc_16u_C1R_p,
10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_func = mop == 0 ? icvErode_16u_C1R_p : icvDilate_16u_C1R_p;
10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( type == CV_16UC3 )
10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_initalloc_func = icvMorphInitAlloc_16u_C3R_p,
10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_func = mop == 0 ? icvErode_16u_C3R_p : icvDilate_16u_C3R_p;
10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( type == CV_16UC4 )
10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_initalloc_func = icvMorphInitAlloc_16u_C4R_p,
10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_func = mop == 0 ? icvErode_16u_C4R_p : icvDilate_16u_C4R_p;
10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( type == CV_32FC1 )
10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_initalloc_func = icvMorphInitAlloc_32f_C1R_p,
10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_func = mop == 0 ? icvErode_32f_C1R_p : icvDilate_32f_C1R_p;
10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( type == CV_32FC3 )
10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_initalloc_func = icvMorphInitAlloc_32f_C3R_p,
10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_func = mop == 0 ? icvErode_32f_C3R_p : icvDilate_32f_C3R_p;
10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( type == CV_32FC4 )
10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_initalloc_func = icvMorphInitAlloc_32f_C4R_p,
10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            custom_func = mop == 0 ? icvErode_32f_C4R_p : icvDilate_32f_C4R_p;
10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( custom_initalloc_func && custom_func )
10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar *src_ptr, *dst_ptr = dst->data.ptr;
10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int src_step, dst_step = dst->step ? dst->step : CV_STUB_STEP;
10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int el_len = el_size.width*el_size.height;
10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* el_mask = (uchar*)cvStackAlloc( el_len );
10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvStatus status;
10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < el_len; i++ )
10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                el_mask[i] = (uchar)(element->values[i] != 0);
10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            status = custom_initalloc_func( size.width, el_mask, el_size,
10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            el_anchor, &morphstate );
10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 && (inplace || iterations > 1) )
10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_CALL( temp = cvCloneMat( src ));
10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                src = temp;
10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            src_ptr = src->data.ptr;
10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            src_step = src->step ? src->step : CV_STUB_STEP;
10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < iterations && status >= 0 && morphstate; i++ )
10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar* t_ptr;
10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int t_step;
10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                status = custom_func( src_ptr, src_step, dst_ptr, dst_step,
10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      size, bordertype, morphstate );
10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_SWAP( src_ptr, dst_ptr, t_ptr );
10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_SWAP( src_step, dst_step, t_step );
10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( i == 0 && temp )
10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst_ptr = temp->data.ptr;
10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst_step = temp->step ? temp->step : CV_STUB_STEP;
10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 )
10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( iterations % 2 == 0 )
10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cvCopy( temp, dst );
10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                EXIT;
10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( el_shape != CV_SHAPE_RECT )
10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_hdr = cvMat( element->nRows, element->nCols, CV_32SC1, element->values );
10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el = &el_hdr;
10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        el_shape = CV_SHAPE_CUSTOM;
10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( morphology.init( mop, src->cols, src->type,
10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    el_shape, el, el_size, el_anchor ));
10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < iterations; i++ )
10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( morphology.process( src, dst ));
10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src = dst;
10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !local_alloc )
11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buffer );
11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( morphstate )
11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvMorphFree_p( morphstate );
11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat( &temp );
11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvErode( const void* src, void* dst, IplConvKernel* element, int iterations )
11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvMorphOp( src, dst, element, iterations, 0 );
11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvDilate( const void* src, void* dst, IplConvKernel* element, int iterations )
11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvMorphOp( src, dst, element, iterations, 1 );
11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvMorphologyEx( const void* src, void* dst,
11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                void* temp, IplConvKernel* element, int op, int iterations )
11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvMorhologyEx" );
11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (op == CV_MOP_GRADIENT ||
11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ((op == CV_MOP_TOPHAT || op == CV_MOP_BLACKHAT) && src == dst)) && temp == 0 )
11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_HeaderIsNull, "temp image required" );
11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( temp == src || temp == dst )
11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_HeaderIsNull, "temp image is equal to src or dst" );
11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch (op)
11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_MOP_OPEN:
11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvErode( src, dst, element, iterations ));
11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvDilate( dst, dst, element, iterations ));
11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_MOP_CLOSE:
11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvDilate( src, dst, element, iterations ));
11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvErode( dst, dst, element, iterations ));
11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_MOP_GRADIENT:
11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvErode( src, temp, element, iterations ));
11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvDilate( src, dst, element, iterations ));
11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvSub( dst, temp, dst ));
11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_MOP_TOPHAT:
11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( src != dst )
11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            temp = dst;
11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvErode( src, temp, element, iterations ));
11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvDilate( temp, temp, element, iterations ));
11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvSub( src, temp, dst ));
11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_MOP_BLACKHAT:
11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( src != dst )
11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            temp = dst;
11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvDilate( src, temp, element, iterations ));
11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvErode( temp, temp, element, iterations ));
11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvSub( temp, src, dst ));
11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default:
11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "unknown morphological operation" );
11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
1174