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
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************/
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* lightweight convolution with 3x3 kernel */
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid icvSepConvSmall3_32f( float* src, int src_step, float* dst, int dst_step,
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvSize src_size, const float* kx, const float* ky, float* buffer )
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int  dst_width, buffer_step = 0;
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int  x, y;
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( src && dst && src_size.width > 2 && src_size.height > 2 &&
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            (src_step & 3) == 0 && (dst_step & 3) == 0 &&
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            (kx || ky) && (buffer || !kx || !ky));
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_step /= sizeof(src[0]);
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_step /= sizeof(dst[0]);
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_width = src_size.width - 2;
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !kx )
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* set vars, so that vertical convolution
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           will write results into destination ROI and
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           horizontal convolution won't run */
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src_size.width = dst_width;
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer_step = dst_step;
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer = dst;
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst_width = 0;
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( src_step >= src_size.width && dst_step >= dst_width );
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_size.height -= 3;
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !ky )
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* set vars, so that vertical convolution won't run and
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           horizontal convolution will write results into destination ROI */
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src_size.height += 3;
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer_step = src_step;
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer = src;
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src_size.width = 0;
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y <= src_size.height; y++, src += src_step,
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                           dst += dst_step,
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                           buffer += buffer_step )
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float* src2 = src + src_step;
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float* src3 = src + src_step*2;
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < src_size.width; x++ )
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buffer[x] = (float)(ky[0]*src[x] + ky[1]*src2[x] + ky[2]*src3[x]);
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < dst_width; x++ )
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[x] = (float)(kx[0]*buffer[x] + kx[1]*buffer[x+1] + kx[2]*buffer[x+2]);
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             Sobel & Scharr Derivative Filters
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/////////////////////////////// Old IPP derivative filters ///////////////////////////////
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// still used in corner detectors (see cvcorner.cpp)
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterSobelVert_8u16s_C1R_t icvFilterSobelVert_8u16s_C1R_p = 0;
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterSobelHoriz_8u16s_C1R_t icvFilterSobelHoriz_8u16s_C1R_p = 0;
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterSobelVertSecond_8u16s_C1R_t icvFilterSobelVertSecond_8u16s_C1R_p = 0;
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterSobelHorizSecond_8u16s_C1R_t icvFilterSobelHorizSecond_8u16s_C1R_p = 0;
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterSobelCross_8u16s_C1R_t icvFilterSobelCross_8u16s_C1R_p = 0;
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterSobelVert_32f_C1R_t icvFilterSobelVert_32f_C1R_p = 0;
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterSobelHoriz_32f_C1R_t icvFilterSobelHoriz_32f_C1R_p = 0;
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterSobelVertSecond_32f_C1R_t icvFilterSobelVertSecond_32f_C1R_p = 0;
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterSobelHorizSecond_32f_C1R_t icvFilterSobelHorizSecond_32f_C1R_p = 0;
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterSobelCross_32f_C1R_t icvFilterSobelCross_32f_C1R_p = 0;
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterScharrVert_8u16s_C1R_t icvFilterScharrVert_8u16s_C1R_p = 0;
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterScharrHoriz_8u16s_C1R_t icvFilterScharrHoriz_8u16s_C1R_p = 0;
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterScharrVert_32f_C1R_t icvFilterScharrVert_32f_C1R_p = 0;
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilterScharrHoriz_32f_C1R_t icvFilterScharrHoriz_32f_C1R_p = 0;
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn///////////////////////////////// New IPP derivative filters /////////////////////////////
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define IPCV_FILTER_PTRS( name )                    \
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilter##name##GetBufSize_8u16s_C1R_t             \
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFilter##name##GetBufSize_8u16s_C1R_p = 0;    \
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilter##name##Border_8u16s_C1R_t                 \
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFilter##name##Border_8u16s_C1R_p = 0;        \
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilter##name##GetBufSize_32f_C1R_t               \
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFilter##name##GetBufSize_32f_C1R_p = 0;      \
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFilter##name##Border_32f_C1R_t                   \
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFilter##name##Border_32f_C1R_p = 0;
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_FILTER_PTRS( ScharrHoriz )
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_FILTER_PTRS( ScharrVert )
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_FILTER_PTRS( SobelHoriz )
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_FILTER_PTRS( SobelNegVert )
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_FILTER_PTRS( SobelHorizSecond )
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_FILTER_PTRS( SobelVertSecond )
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_FILTER_PTRS( SobelCross )
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennIPCV_FILTER_PTRS( Laplacian )
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvDeriv3x3GetBufSizeIPPFunc)
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( CvSize roi, int* bufsize );
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvDerivGetBufSizeIPPFunc)
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( CvSize roi, int masksize, int* bufsize );
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvDeriv3x3IPPFunc_8u )
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( const void* src, int srcstep, void* dst, int dststep,
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      CvSize size, int bordertype, uchar bordervalue, void* buffer );
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvDeriv3x3IPPFunc_32f )
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( const void* src, int srcstep, void* dst, int dststep,
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      CvSize size, int bordertype, float bordervalue, void* buffer );
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvDerivIPPFunc_8u )
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( const void* src, int srcstep, void* dst, int dststep,
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      CvSize size, int masksize, int bordertype,
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      uchar bordervalue, void* buffer );
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvDerivIPPFunc_32f )
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ( const void* src, int srcstep, void* dst, int dststep,
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      CvSize size, int masksize, int bordertype,
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      float bordervalue, void* buffer );
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//////////////////////////////////////////////////////////////////////////////////////////
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSobel( const void* srcarr, void* dstarr, int dx, int dy, int aperture_size )
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSepFilter filter;
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* buffer = 0;
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int local_alloc = 0;
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvSobel" );
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int origin = 0;
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int src_type, dst_type;
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, *src = (CvMat*)srcarr;
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat dststub, *dst = (CvMat*)dstarr;
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(src) )
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( src = cvGetMat( src, &srcstub ));
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(dst) )
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( dst = cvGetMat( dst, &dststub ));
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CV_IS_IMAGE_HDR( srcarr ))
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        origin = ((IplImage*)srcarr)->origin;
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_type = CV_MAT_TYPE( src->type );
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_type = CV_MAT_TYPE( dst->type );
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_SIZES_EQ( src, dst ))
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "src and dst have different sizes" );
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ((aperture_size == CV_SCHARR || aperture_size == 3 || aperture_size == 5) &&
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dx <= 2 && dy <= 2 && dx + dy <= 2 && icvFilterSobelNegVertBorder_8u16s_C1R_p) &&
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (src_type == CV_8UC1 && dst_type == CV_16SC1/* ||
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src_type == CV_32FC1 && dst_type == CV_32FC1*/) )
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvDerivGetBufSizeIPPFunc ipp_sobel_getbufsize_func = 0;
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvDerivIPPFunc_8u ipp_sobel_func_8u = 0;
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvDerivIPPFunc_32f ipp_sobel_func_32f = 0;
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvDeriv3x3GetBufSizeIPPFunc ipp_scharr_getbufsize_func = 0;
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvDeriv3x3IPPFunc_8u ipp_scharr_func_8u = 0;
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvDeriv3x3IPPFunc_32f ipp_scharr_func_32f = 0;
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( aperture_size == CV_SCHARR )
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( dx == 1 && dy == 0 )
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( src_type == CV_8U )
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_scharr_func_8u = icvFilterScharrVertBorder_8u16s_C1R_p,
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_scharr_getbufsize_func = icvFilterScharrVertGetBufSize_8u16s_C1R_p;
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_scharr_func_32f = icvFilterScharrVertBorder_32f_C1R_p,
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_scharr_getbufsize_func = icvFilterScharrVertGetBufSize_32f_C1R_p;
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( dx == 0 && dy == 1 )
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( src_type == CV_8U )
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_scharr_func_8u = icvFilterScharrHorizBorder_8u16s_C1R_p,
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_scharr_getbufsize_func = icvFilterScharrHorizGetBufSize_8u16s_C1R_p;
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_scharr_func_32f = icvFilterScharrHorizBorder_32f_C1R_p,
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_scharr_getbufsize_func = icvFilterScharrHorizGetBufSize_32f_C1R_p;
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadArg, "Scharr filter can only be used to compute 1st image derivatives" );
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( dx == 1 && dy == 0 )
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( src_type == CV_8U )
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_8u = icvFilterSobelNegVertBorder_8u16s_C1R_p,
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_getbufsize_func = icvFilterSobelNegVertGetBufSize_8u16s_C1R_p;
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_32f = icvFilterSobelNegVertBorder_32f_C1R_p,
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_getbufsize_func = icvFilterSobelNegVertGetBufSize_32f_C1R_p;
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( dx == 0 && dy == 1 )
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( src_type == CV_8U )
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_8u = icvFilterSobelHorizBorder_8u16s_C1R_p,
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_getbufsize_func = icvFilterSobelHorizGetBufSize_8u16s_C1R_p;
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_32f = icvFilterSobelHorizBorder_32f_C1R_p,
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_getbufsize_func = icvFilterSobelHorizGetBufSize_32f_C1R_p;
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( dx == 2 && dy == 0 )
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( src_type == CV_8U )
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_8u = icvFilterSobelVertSecondBorder_8u16s_C1R_p,
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_getbufsize_func = icvFilterSobelVertSecondGetBufSize_8u16s_C1R_p;
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_32f = icvFilterSobelVertSecondBorder_32f_C1R_p,
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_getbufsize_func = icvFilterSobelVertSecondGetBufSize_32f_C1R_p;
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( dx == 0 && dy == 2 )
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( src_type == CV_8U )
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_8u = icvFilterSobelHorizSecondBorder_8u16s_C1R_p,
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_getbufsize_func = icvFilterSobelHorizSecondGetBufSize_8u16s_C1R_p;
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_32f = icvFilterSobelHorizSecondBorder_32f_C1R_p,
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_getbufsize_func = icvFilterSobelHorizSecondGetBufSize_32f_C1R_p;
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( dx == 1 && dy == 1 )
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( src_type == CV_8U )
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_8u = icvFilterSobelCrossBorder_8u16s_C1R_p,
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_getbufsize_func = icvFilterSobelCrossGetBufSize_8u16s_C1R_p;
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_32f = icvFilterSobelCrossBorder_32f_C1R_p,
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_getbufsize_func = icvFilterSobelCrossGetBufSize_32f_C1R_p;
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ((ipp_sobel_func_8u || ipp_sobel_func_32f) && ipp_sobel_getbufsize_func) ||
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ((ipp_scharr_func_8u || ipp_scharr_func_32f) && ipp_scharr_getbufsize_func) )
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int bufsize = 0, masksize = aperture_size == 3 ? 33 : 55;
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvSize size = cvGetMatSize( src );
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* src_ptr = src->data.ptr;
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* dst_ptr = dst->data.ptr;
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int src_step = src->step ? src->step : CV_STUB_STEP;
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int dst_step = dst->step ? dst->step : CV_STUB_STEP;
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const int bordertype = 1; // replication border
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvStatus status;
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            status = ipp_sobel_getbufsize_func ?
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ipp_sobel_getbufsize_func( size, masksize, &bufsize ) :
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ipp_scharr_getbufsize_func( size, &bufsize );
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 )
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( bufsize <= CV_MAX_LOCAL_SIZE )
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buffer = cvStackAlloc( bufsize );
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    local_alloc = 1;
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_CALL( buffer = cvAlloc( bufsize ));
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                status =
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_8u ? ipp_sobel_func_8u( src_ptr, src_step, dst_ptr, dst_step,
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                           size, masksize, bordertype, 0, buffer ) :
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_sobel_func_32f ? ipp_sobel_func_32f( src_ptr, src_step, dst_ptr, dst_step,
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                             size, masksize, bordertype, 0, buffer ) :
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_scharr_func_8u ? ipp_scharr_func_8u( src_ptr, src_step, dst_ptr, dst_step,
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                             size, bordertype, 0, buffer ) :
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_scharr_func_32f ? ipp_scharr_func_32f( src_ptr, src_step, dst_ptr, dst_step,
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                               size, bordertype, 0, buffer ) :
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CV_NOTDEFINED_ERR;
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 &&
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ((dx == 0 && dy == 1 && origin) || (dx == 1 && dy == 1 && !origin))) // negate the output
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvSubRS( dst, cvScalarAll(0), dst );
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 )
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                EXIT;
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( filter.init_deriv( src->cols, src_type, dst_type, dx, dy,
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                aperture_size, origin ? CvSepFilter::FLIP_KERNEL : 0));
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( filter.process( src, dst ));
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buffer && !local_alloc )
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buffer );
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                     Laplacian Filter
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvLaplaceRow_8u32s( const uchar* src, int* dst, void* params );
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvLaplaceRow_8u32f( const uchar* src, float* dst, void* params );
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvLaplaceRow_32f( const float* src, float* dst, void* params );
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvLaplaceCol_32s16s( const int** src, short* dst, int dst_step,
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  int count, void* params );
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvLaplaceCol_32f( const float** src, float* dst, int dst_step,
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               int count, void* params );
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvLaplaceFilter::CvLaplaceFilter()
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    normalized = basic_laplacian = false;
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvLaplaceFilter::CvLaplaceFilter( int _max_width, int _src_type, int _dst_type, bool _normalized,
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  int _ksize, int _border_mode, CvScalar _border_value )
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    normalized = basic_laplacian = false;
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    init( _max_width, _src_type, _dst_type, _normalized, _ksize, _border_mode, _border_value );
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvLaplaceFilter::~CvLaplaceFilter()
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    clear();
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvLaplaceFilter::get_work_params()
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int min_rows = max_ky*2 + 3, rows = MAX(min_rows,10), row_sz;
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int width = max_width, trow_sz = 0;
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dst_depth = CV_MAT_DEPTH(dst_type);
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int work_depth = dst_depth < CV_32F ? CV_32S : CV_32F;
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_type = CV_MAKETYPE( work_depth, CV_MAT_CN(dst_type)*2 );
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    trow_sz = cvAlign( (max_width + ksize.width - 1)*CV_ELEM_SIZE(src_type), ALIGN );
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    row_sz = cvAlign( width*CV_ELEM_SIZE(work_type), ALIGN );
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buf_size = rows*row_sz;
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buf_size = MIN( buf_size, 1 << 16 );
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buf_size = MAX( buf_size, min_rows*row_sz );
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    max_rows = (buf_size/row_sz)*3 + max_ky*2 + 8;
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buf_size += trow_sz;
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvLaplaceFilter::init( int _max_width, int _src_type, int _dst_type, bool _normalized,
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int _ksize0, int _border_mode, CvScalar _border_value )
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat *kx = 0, *ky = 0;
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "CvLaplaceFilter::init" );
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int src_depth = CV_MAT_DEPTH(_src_type), dst_depth = CV_MAT_DEPTH(_dst_type);
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int _ksize = MAX( _ksize0, 3 );
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    normalized = _normalized;
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    basic_laplacian = _ksize0 == 1;
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ((src_depth != CV_8U || (dst_depth != CV_16S && dst_depth != CV_32F)) &&
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (src_depth != CV_32F || dst_depth != CV_32F)) ||
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_MAT_CN(_src_type) != CV_MAT_CN(_dst_type) )
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats,
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "Laplacian can either transform 8u->16s, or 8u->32f, or 32f->32f.\n"
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "The number of channels must be the same." );
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( _ksize < 1 || _ksize > CV_MAX_SOBEL_KSIZE || _ksize % 2 == 0 )
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "kernel size must be within 1..7 and odd" );
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( kx = cvCreateMat( 1, _ksize, CV_32F ));
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( ky = cvCreateMat( 1, _ksize, CV_32F ));
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSepFilter::init_sobel_kernel( kx, ky, 2, 0, 0 );
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSepFilter::init( _max_width, _src_type, _dst_type, kx, ky,
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       cvPoint(-1,-1), _border_mode, _border_value );
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    x_func = 0;
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    y_func = 0;
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src_depth == CV_8U )
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( dst_depth == CV_16S )
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x_func = (CvRowFilterFunc)icvLaplaceRow_8u32s;
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            y_func = (CvColumnFilterFunc)icvLaplaceCol_32s16s;
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( dst_depth == CV_32F )
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x_func = (CvRowFilterFunc)icvLaplaceRow_8u32f;
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            y_func = (CvColumnFilterFunc)icvLaplaceCol_32f;
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( src_depth == CV_32F )
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( dst_depth == CV_32F )
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x_func = (CvRowFilterFunc)icvLaplaceRow_32f;
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            y_func = (CvColumnFilterFunc)icvLaplaceCol_32f;
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !x_func || !y_func )
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "" );
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat( &kx );
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat( &ky );
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvLaplaceFilter::init( int _max_width, int _src_type, int _dst_type,
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            bool _is_separable, CvSize _ksize,
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvPoint _anchor, int _border_mode,
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvScalar _border_value )
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSepFilter::init( _max_width, _src_type, _dst_type, _is_separable,
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       _ksize, _anchor, _border_mode, _border_value );
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid CvLaplaceFilter::init( int _max_width, int _src_type, int _dst_type,
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            const CvMat* _kx, const CvMat* _ky,
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvPoint _anchor, int _border_mode,
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvScalar _border_value )
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSepFilter::init( _max_width, _src_type, _dst_type, _kx, _ky,
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       _anchor, _border_mode, _border_value );
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_LAPLACE_ROW( flavor, srctype, dsttype, load_macro )         \
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void                                                             \
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvLaplaceRow_##flavor( const srctype* src, dsttype* dst, void* params )\
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                       \
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvLaplaceFilter* state = (const CvLaplaceFilter*)params;      \
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvMat* _kx = state->get_x_kernel();                           \
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvMat* _ky = state->get_y_kernel();                           \
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const dsttype* kx = (dsttype*)_kx->data.ptr;                        \
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const dsttype* ky = (dsttype*)_ky->data.ptr;                        \
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ksize = _kx->cols + _kx->rows - 1;                              \
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i = 0, j, k, width = state->get_width();                        \
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cn = CV_MAT_CN(state->get_src_type());                          \
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ksize2 = ksize/2, ksize2n = ksize2*cn;                          \
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const srctype* s = src + ksize2n;                                   \
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool basic_laplacian = state->is_basic_laplacian();                 \
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    kx += ksize2;                                                       \
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ky += ksize2;                                                       \
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    width *= cn;                                                        \
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( basic_laplacian )                                               \
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < width; i++ )                                    \
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dsttype s0 = load_macro(s[i]);                              \
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dsttype s1 = (dsttype)(s[i-cn] - s0*2 + s[i+cn]);           \
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = s0; dst[i+width] = s1;                             \
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( ksize == 3 )                                               \
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < width; i++ )                                    \
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dsttype s0 = (dsttype)(s[i-cn] + s[i]*2 + s[i+cn]);         \
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dsttype s1 = (dsttype)(s[i-cn] - s[i]*2 + s[i+cn]);         \
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = s0; dst[i+width] = s1;                             \
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( ksize == 5 )                                               \
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < width; i++ )                                    \
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dsttype s0 = (dsttype)(s[i-2*cn]+(s[i-cn]+s[i+cn])*4+s[i]*6+s[i+2*cn]);\
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dsttype s1 = (dsttype)(s[i-2*cn]-s[i]*2+s[i+2*cn]);         \
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = s0; dst[i+width] = s1;                             \
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else                                                                \
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < width; i++, s++ )                               \
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dsttype s0 = ky[0]*load_macro(s[0]), s1 = kx[0]*load_macro(s[0]);\
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 1, j = cn; k <= ksize2; k++, j += cn )             \
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                           \
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dsttype t = load_macro(s[j] + s[-j]);                   \
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s0 += ky[k]*t; s1 += kx[k]*t;                           \
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                           \
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = s0; dst[i+width] = s1;                             \
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_LAPLACE_ROW( 8u32s, uchar, int, CV_NOP )
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_LAPLACE_ROW( 8u32f, uchar, float, CV_8TO32F )
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_LAPLACE_ROW( 32f, float, float, CV_NOP )
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvLaplaceCol_32s16s( const int** src, short* dst,
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      int dst_step, int count, void* params )
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvLaplaceFilter* state = (const CvLaplaceFilter*)params;
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvMat* _kx = state->get_x_kernel();
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvMat* _ky = state->get_y_kernel();
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int* kx = (const int*)_kx->data.ptr;
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int* ky = (const int*)_ky->data.ptr;
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ksize = _kx->cols + _kx->rows - 1, ksize2 = ksize/2;
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i = 0, k, width = state->get_width();
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cn = CV_MAT_CN(state->get_src_type());
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool basic_laplacian = state->is_basic_laplacian();
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool normalized = state->is_normalized();
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int shift = ksize - 1, delta = (1 << shift) >> 1;
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    width *= cn;
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src += ksize2;
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    kx += ksize2;
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ky += ksize2;
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_step /= sizeof(dst[0]);
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( basic_laplacian || !normalized )
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        normalized = false;
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        shift = delta = 0;
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( ; count--; dst += dst_step, src++ )
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ksize == 3 )
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const int *src0 = src[-1], *src1 = src[0], *src2 = src[1];
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( basic_laplacian )
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i <= width - 2; i += 2 )
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s0 = src0[i] - src1[i]*2 + src2[i] + src1[i+width];
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s1 = src0[i+1] - src1[i+1]*2 + src2[i+1] + src1[i+width+1];
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = (short)s0; dst[i+1] = (short)s1;
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( ; i < width; i++ )
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = (short)(src0[i] - src1[i]*2 + src2[i] + src1[i+width]);
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( !normalized )
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i <= width - 2; i += 2 )
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s0 = src0[i] - src1[i]*2 + src2[i] +
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src0[i+width] + src1[i+width]*2 + src2[i+width];
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s1 = src0[i+1] - src1[i+1]*2 + src2[i+1] +
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src0[i+width+1] + src1[i+width+1]*2 + src2[i+width+1];
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = (short)s0; dst[i+1] = (short)s1;
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i <= width - 2; i += 2 )
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s0 = CV_DESCALE(src0[i] - src1[i]*2 + src2[i] +
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src0[i+width] + src1[i+width]*2 + src2[i+width], 2);
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s1 = CV_DESCALE(src0[i+1] - src1[i+1]*2 + src2[i+1] +
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src0[i+width+1] + src1[i+width+1]*2 + src2[i+width+1],2);
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = (short)s0; dst[i+1] = (short)s1;
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( ksize == 5 )
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const int *src0 = src[-2], *src1 = src[-1], *src2 = src[0], *src3 = src[1], *src4 = src[2];
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !normalized )
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i <= width - 2; i += 2 )
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s0 = src0[i] - src2[i]*2 + src4[i] + src0[i+width] + src4[i+width] +
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             (src1[i+width] + src3[i+width])*4 + src2[i+width]*6;
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s1 = src0[i+1] - src2[i+1]*2 + src4[i+1] + src0[i+width+1] +
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src4[i+width+1] + (src1[i+width+1] + src3[i+width+1])*4 +
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src2[i+width+1]*6;
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = (short)s0; dst[i+1] = (short)s1;
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i <= width - 2; i += 2 )
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s0 = CV_DESCALE(src0[i] - src2[i]*2 + src4[i] +
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src0[i+width] + src4[i+width] +
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             (src1[i+width] + src3[i+width])*4 + src2[i+width]*6, 4);
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s1 = CV_DESCALE(src0[i+1] - src2[i+1]*2 + src4[i+1] +
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src0[i+width+1] + src4[i+width+1] +
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             (src1[i+width+1] + src3[i+width+1])*4 + src2[i+width+1]*6, 4);
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = (short)s0; dst[i+1] = (short)s1;
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !normalized )
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i <= width - 2; i += 2 )
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s0 = kx[0]*src[0][i] + ky[0]*src[0][i+width];
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s1 = kx[0]*src[0][i+1] + ky[0]*src[0][i+width+1];
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 1; k <= ksize2; k++ )
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        const int* src1 = src[k] + i, *src2 = src[-k] + i;
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int fx = kx[k], fy = ky[k];
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        s0 += fx*(src1[0] + src2[0]) + fy*(src1[width] + src2[width]);
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        s1 += fx*(src1[1] + src2[1]) + fy*(src1[width+1] + src2[width+1]);
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = CV_CAST_16S(s0); dst[i+1] = CV_CAST_16S(s1);
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i <= width - 2; i += 2 )
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s0 = kx[0]*src[0][i] + ky[0]*src[0][i+width];
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int s1 = kx[0]*src[0][i+1] + ky[0]*src[0][i+width+1];
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 1; k <= ksize2; k++ )
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        const int* src1 = src[k] + i, *src2 = src[-k] + i;
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int fx = kx[k], fy = ky[k];
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        s0 += fx*(src1[0] + src2[0]) + fy*(src1[width] + src2[width]);
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        s1 += fx*(src1[1] + src2[1]) + fy*(src1[width+1] + src2[width+1]);
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s0 = CV_DESCALE( s0, shift ); s1 = CV_DESCALE( s1, shift );
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = (short)s0; dst[i+1] = (short)s1;
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; i < width; i++ )
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int s0 = kx[0]*src[0][i] + ky[0]*src[0][i+width];
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 1; k <= ksize2; k++ )
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const int* src1 = src[k] + i, *src2 = src[-k] + i;
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s0 += kx[k]*(src1[0] + src2[0]) + ky[k]*(src1[width] + src2[width]);
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            s0 = (s0 + delta) >> shift;
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = CV_CAST_16S(s0);
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvLaplaceCol_32f( const float** src, float* dst,
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int dst_step, int count, void* params )
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvLaplaceFilter* state = (const CvLaplaceFilter*)params;
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvMat* _kx = state->get_x_kernel();
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvMat* _ky = state->get_y_kernel();
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const float* kx = (const float*)_kx->data.ptr;
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const float* ky = (const float*)_ky->data.ptr;
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ksize = _kx->cols + _kx->rows - 1, ksize2 = ksize/2;
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i = 0, k, width = state->get_width();
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cn = CV_MAT_CN(state->get_src_type());
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool basic_laplacian = state->is_basic_laplacian();
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool normalized = state->is_normalized();
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float scale = 1.f/(1 << (ksize - 1));
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    width *= cn;
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src += ksize2;
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    kx += ksize2;
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ky += ksize2;
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_step /= sizeof(dst[0]);
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( basic_laplacian || !normalized )
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        normalized = false;
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        scale = 1.f;
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( ; count--; dst += dst_step, src++ )
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ksize == 3 )
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const float *src0 = src[-1], *src1 = src[0], *src2 = src[1];
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( basic_laplacian )
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i <= width - 2; i += 2 )
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float s0 = src0[i] - src1[i]*2 + src2[i] + src1[i+width];
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float s1 = src0[i+1] - src1[i+1]*2 + src2[i+1] + src1[i+width+1];
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = s0; dst[i+1] = s1;
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( ; i < width; i++ )
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = src0[i] - src1[i]*2 + src2[i] + src1[i+width];
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( !normalized )
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i <= width - 2; i += 2 )
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float s0 = src0[i] - src1[i]*2 + src2[i] +
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src0[i+width] + src1[i+width]*2 + src2[i+width];
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float s1 = src0[i+1] - src1[i+1]*2 + src2[i+1] +
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src0[i+width+1] + src1[i+width+1]*2 + src2[i+width+1];
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = s0; dst[i+1] = s1;
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i <= width - 2; i += 2 )
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float s0 = (src0[i] - src1[i]*2 + src2[i] +
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src0[i+width] + src1[i+width]*2 + src2[i+width])*scale;
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float s1 = (src0[i+1] - src1[i+1]*2 + src2[i+1] +
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             src0[i+width+1] + src1[i+width+1]*2 + src2[i+width+1])*scale;
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[i] = s0; dst[i+1] = s1;
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( ksize == 5 )
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const float *src0 = src[-2], *src1 = src[-1], *src2 = src[0], *src3 = src[1], *src4 = src[2];
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i <= width - 2; i += 2 )
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float s0 = (src0[i] - src2[i]*2 + src4[i] +
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         src0[i+width] + src4[i+width] +
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         (src1[i+width] + src3[i+width])*4 + src2[i+width]*6)*scale;
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float s1 = (src0[i+1] - src2[i+1]*2 + src4[i+1] +
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         src0[i+width+1] + src4[i+width+1] +
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         (src1[i+width+1] + src3[i+width+1])*4 + src2[i+width+1]*6)*scale;
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i] = s0; dst[i+1] = s1;
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i <= width - 2; i += 2 )
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float s0 = kx[0]*src[0][i] + ky[0]*src[0][i+width];
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float s1 = kx[0]*src[0][i+1] + ky[0]*src[0][i+width+1];
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 1; k <= ksize2; k++ )
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const float* src1 = src[k] + i, *src2 = src[-k] + i;
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float fx = kx[k], fy = ky[k];
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s0 += fx*(src1[0] + src2[0]) + fy*(src1[width] + src2[width]);
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s1 += fx*(src1[1] + src2[1]) + fy*(src1[width+1] + src2[width+1]);
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s0 *= scale; s1 *= scale;
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i] = s0; dst[i+1] = s1;
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; i < width; i++ )
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float s0 = kx[0]*src[0][i] + ky[0]*src[0][i+width];
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 1; k <= ksize2; k++ )
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const float* src1 = src[k] + i, *src2 = src[-k] + i;
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s0 += kx[k]*(src1[0] + src2[0]) + ky[k]*(src1[width] + src2[width]);
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i] = s0*scale;
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvLaplace( const void* srcarr, void* dstarr, int aperture_size )
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvLaplaceFilter laplacian;
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* buffer = 0;
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int local_alloc = 0;
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvLaplace" );
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, *src = (CvMat*)srcarr;
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat dststub, *dst = (CvMat*)dstarr;
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int src_type, dst_type;
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( src = cvGetMat( src, &srcstub ));
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( dst = cvGetMat( dst, &dststub ));
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_type = CV_MAT_TYPE(src->type);
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_type = CV_MAT_TYPE(dst->type);
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (aperture_size == 3 || aperture_size == 5) &&
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (src_type == CV_8UC1 && dst_type == CV_16SC1/* ||
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src_type == CV_32FC1 && dst_type == CV_32FC1*/) )
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvDerivGetBufSizeIPPFunc ipp_laplace_getbufsize_func = 0;
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvDerivIPPFunc_8u ipp_laplace_func_8u = 0;
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvDerivIPPFunc_32f ipp_laplace_func_32f = 0;
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( src_type == CV_8U )
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ipp_laplace_func_8u = icvFilterLaplacianBorder_8u16s_C1R_p,
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ipp_laplace_getbufsize_func = icvFilterLaplacianGetBufSize_8u16s_C1R_p;
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ipp_laplace_func_32f = icvFilterLaplacianBorder_32f_C1R_p,
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ipp_laplace_getbufsize_func = icvFilterLaplacianGetBufSize_32f_C1R_p;
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (ipp_laplace_func_8u || ipp_laplace_func_32f) && ipp_laplace_getbufsize_func )
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int bufsize = 0, masksize = aperture_size == 3 ? 33 : 55;
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvSize size = cvGetMatSize( src );
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* src_ptr = src->data.ptr;
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* dst_ptr = dst->data.ptr;
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int src_step = src->step ? src->step : CV_STUB_STEP;
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int dst_step = dst->step ? dst->step : CV_STUB_STEP;
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const int bordertype = 1; // replication border
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvStatus status;
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            status = ipp_laplace_getbufsize_func( size, masksize, &bufsize );
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 )
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( bufsize <= CV_MAX_LOCAL_SIZE )
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buffer = cvStackAlloc( bufsize );
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    local_alloc = 1;
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_CALL( buffer = cvAlloc( bufsize ));
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                status =
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_laplace_func_8u ? ipp_laplace_func_8u( src_ptr, src_step, dst_ptr, dst_step,
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                               size, masksize, bordertype, 0, buffer ) :
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ipp_laplace_func_32f ? ipp_laplace_func_32f( src_ptr, src_step, dst_ptr, dst_step,
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                 size, masksize, bordertype, 0, buffer ) :
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CV_NOTDEFINED_ERR;
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 )
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                EXIT;
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( laplacian.init( src->cols, src_type, dst_type,
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             false, aperture_size ));
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( laplacian.process( src, dst ));
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buffer && !local_alloc )
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buffer );
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
880