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/* ////////////////////////////////////////////////////////////////////
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  Geometrical transforms on images and matrices: rotation, zoom etc.
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// */
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cv.h"
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/************** interpolation constants and tables ***************/
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_WARP_MUL_ONE_8U(x)  ((x) << ICV_WARP_SHIFT)
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_WARP_DESCALE_8U(x)  CV_DESCALE((x), ICV_WARP_SHIFT*2)
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_WARP_CLIP_X(x)      ((unsigned)(x) < (unsigned)ssize.width ? \
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                (x) : (x) < 0 ? 0 : ssize.width - 1)
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_WARP_CLIP_Y(y)      ((unsigned)(y) < (unsigned)ssize.height ? \
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                (y) : (y) < 0 ? 0 : ssize.height - 1)
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennfloat icvLinearCoeffs[(ICV_LINEAR_TAB_SIZE+1)*2];
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid icvInitLinearCoeffTab()
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int inittab = 0;
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !inittab )
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( int i = 0; i <= ICV_LINEAR_TAB_SIZE; i++ )
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float x = (float)i/ICV_LINEAR_TAB_SIZE;
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvLinearCoeffs[i*2] = x;
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvLinearCoeffs[i*2+1] = 1.f - x;
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inittab = 1;
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennfloat icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE+1)*2];
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid icvInitCubicCoeffTab()
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int inittab = 0;
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !inittab )
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 0
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // classical Mitchell-Netravali filter
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const double B = 1./3;
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const double C = 1./3;
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const double p0 = (6 - 2*B)/6.;
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const double p2 = (-18 + 12*B + 6*C)/6.;
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const double p3 = (12 - 9*B - 6*C)/6.;
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const double q0 = (8*B + 24*C)/6.;
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const double q1 = (-12*B - 48*C)/6.;
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const double q2 = (6*B + 30*C)/6.;
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const double q3 = (-B - 6*C)/6.;
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define ICV_CUBIC_1(x)  (((x)*p3 + p2)*(x)*(x) + p0)
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define ICV_CUBIC_2(x)  ((((x)*q3 + q2)*(x) + q1)*(x) + q0)
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // alternative "sharp" filter
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const double A = -0.75;
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define ICV_CUBIC_1(x)  (((A + 2)*(x) - (A + 3))*(x)*(x) + 1)
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define ICV_CUBIC_2(x)  (((A*(x) - 5*A)*(x) + 8*A)*(x) - 4*A)
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( int i = 0; i <= ICV_CUBIC_TAB_SIZE; i++ )
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float x = (float)i/ICV_CUBIC_TAB_SIZE;
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvCubicCoeffs[i*2] = (float)ICV_CUBIC_1(x);
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x += 1.f;
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvCubicCoeffs[i*2+1] = (float)ICV_CUBIC_2(x);
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inittab = 1;
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*                                         Resize                                         *
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_NN_8u_C1R( const uchar* src, int srcstep, CvSize ssize,
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     uchar* dst, int dststep, CvSize dsize, int pix_size )
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* x_ofs = (int*)cvStackAlloc( dsize.width * sizeof(x_ofs[0]) );
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int pix_size4 = pix_size / sizeof(int);
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x, y, t;
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( x = 0; x < dsize.width; x++ )
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t = (ssize.width*x*2 + MIN(ssize.width, dsize.width) - 1)/(dsize.width*2);
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t -= t >= ssize.width;
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x_ofs[x] = t*pix_size;
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < dsize.height; y++, dst += dststep )
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const uchar* tsrc;
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t = (ssize.height*y*2 + MIN(ssize.height, dsize.height) - 1)/(dsize.height*2);
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t -= t >= ssize.height;
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        tsrc = src + srcstep*t;
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        switch( pix_size )
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        case 1:
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( x = 0; x <= dsize.width - 2; x += 2 )
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar t0 = tsrc[x_ofs[x]];
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar t1 = tsrc[x_ofs[x+1]];
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[x] = t0;
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[x+1] = t1;
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; x < dsize.width; x++ )
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[x] = tsrc[x_ofs[x]];
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        case 2:
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( x = 0; x < dsize.width; x++ )
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                *(ushort*)(dst + x*2) = *(ushort*)(tsrc + x_ofs[x]);
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        case 3:
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( x = 0; x < dsize.width; x++ )
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const uchar* _tsrc = tsrc + x_ofs[x];
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[x*3] = _tsrc[0]; dst[x*3+1] = _tsrc[1]; dst[x*3+2] = _tsrc[2];
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        case 4:
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( x = 0; x < dsize.width; x++ )
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                *(int*)(dst + x*4) = *(int*)(tsrc + x_ofs[x]);
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        case 6:
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( x = 0; x < dsize.width; x++ )
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const ushort* _tsrc = (const ushort*)(tsrc + x_ofs[x]);
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ushort* _tdst = (ushort*)(dst + x*6);
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _tdst[0] = _tsrc[0]; _tdst[1] = _tsrc[1]; _tdst[2] = _tsrc[2];
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        default:
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( x = 0; x < dsize.width; x++ )
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_MEMCPY_INT( dst + x*pix_size, tsrc + x_ofs[x], pix_size4 );
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct CvResizeAlpha
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int idx;
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    union
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float alpha;
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int ialpha;
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    };
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvResizeAlpha;
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  ICV_DEF_RESIZE_BILINEAR_FUNC( flavor, arrtype, worktype, alpha_field,  \
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       mul_one_macro, descale_macro )           \
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                                      \
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_Bilinear_##flavor##_CnR( const arrtype* src, int srcstep, CvSize ssize,\
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   arrtype* dst, int dststep, CvSize dsize,     \
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   int cn, int xmax,                            \
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   const CvResizeAlpha* xofs,                   \
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   const CvResizeAlpha* yofs,                   \
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   worktype* buf0, worktype* buf1 )             \
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                               \
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int prev_sy0 = -1, prev_sy1 = -1;                                           \
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int k, dx, dy;                                                              \
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srcstep /= sizeof(src[0]);                                                  \
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dststep /= sizeof(dst[0]);                                                  \
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dsize.width *= cn;                                                          \
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    xmax *= cn;                                                                 \
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( dy = 0; dy < dsize.height; dy++, dst += dststep )                      \
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                           \
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        worktype fy = yofs[dy].alpha_field, *swap_t;                            \
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int sy0 = yofs[dy].idx, sy1 = sy0 + (fy > 0 && sy0 < ssize.height-1);   \
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( sy0 == prev_sy0 && sy1 == prev_sy1 )                                \
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            k = 2;                                                              \
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( sy0 == prev_sy1 )                                              \
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                       \
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_SWAP( buf0, buf1, swap_t );                                      \
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            k = 1;                                                              \
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                       \
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else                                                                    \
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            k = 0;                                                              \
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; k < 2; k++ )                                                     \
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                       \
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype* _buf = k == 0 ? buf0 : buf1;                              \
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype* _src;                                                \
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int sy = k == 0 ? sy0 : sy1;                                        \
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( k == 1 && sy1 == sy0 )                                          \
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                memcpy( buf1, buf0, dsize.width*sizeof(buf0[0]) );              \
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;                                                       \
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _src = src + sy*srcstep;                                            \
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( dx = 0; dx < xmax; dx++ )                                      \
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int sx = xofs[dx].idx;                                          \
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                worktype fx = xofs[dx].alpha_field;                             \
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                worktype t = _src[sx];                                          \
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _buf[dx] = mul_one_macro(t) + fx*(_src[sx+cn] - t);             \
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; dx < dsize.width; dx++ )                                     \
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _buf[dx] = mul_one_macro(_src[xofs[dx].idx]);                   \
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                       \
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prev_sy0 = sy0;                                                         \
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prev_sy1 = sy1;                                                         \
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( sy0 == sy1 )                                                        \
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( dx = 0; dx < dsize.width; dx++ )                               \
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[dx] = (arrtype)descale_macro( mul_one_macro(buf0[dx]));     \
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else                                                                    \
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( dx = 0; dx < dsize.width; dx++ )                               \
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[dx] = (arrtype)descale_macro( mul_one_macro(buf0[dx]) +     \
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                  fy*(buf1[dx] - buf0[dx]));    \
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                           \
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                               \
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct CvDecimateAlpha
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int si, di;
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float alpha;
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvDecimateAlpha;
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  ICV_DEF_RESIZE_AREA_FAST_FUNC( flavor, arrtype, worktype, cast_macro ) \
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                                      \
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_AreaFast_##flavor##_CnR( const arrtype* src, int srcstep, CvSize ssize,\
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              arrtype* dst, int dststep, CvSize dsize, int cn,  \
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              const int* ofs, const int* xofs )                 \
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                               \
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dy, dx, k = 0;                                                          \
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int scale_x = ssize.width/dsize.width;                                      \
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int scale_y = ssize.height/dsize.height;                                    \
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int area = scale_x*scale_y;                                                 \
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float scale = 1.f/(scale_x*scale_y);                                        \
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srcstep /= sizeof(src[0]);                                                  \
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dststep /= sizeof(dst[0]);                                                  \
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dsize.width *= cn;                                                          \
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( dy = 0; dy < dsize.height; dy++, dst += dststep )                      \
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( dx = 0; dx < dsize.width; dx++ )                                   \
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                       \
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype* _src = src + dy*scale_y*srcstep + xofs[dx];          \
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype sum = 0;                                                   \
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k <= area - 4; k += 4 )                                 \
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum += _src[ofs[k]] + _src[ofs[k+1]] +                          \
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       _src[ofs[k+2]] + _src[ofs[k+3]];                         \
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; k < area; k++ )                                              \
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum += _src[ofs[k]];                                            \
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[dx] = (arrtype)cast_macro( sum*scale );                         \
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                       \
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                               \
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  ICV_DEF_RESIZE_AREA_FUNC( flavor, arrtype, load_macro, cast_macro )    \
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                                      \
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_Area_##flavor##_CnR( const arrtype* src, int srcstep, CvSize ssize,   \
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               arrtype* dst, int dststep, CvSize dsize,         \
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               int cn, const CvDecimateAlpha* xofs,             \
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               int xofs_count, float* buf, float* sum )         \
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                               \
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int k, sy, dx, cur_dy = 0;                                                  \
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float scale_y = (float)ssize.height/dsize.height;                           \
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srcstep /= sizeof(src[0]);                                                  \
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dststep /= sizeof(dst[0]);                                                  \
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dsize.width *= cn;                                                          \
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( sy = 0; sy < ssize.height; sy++, src += srcstep )                      \
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                           \
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( cn == 1 )                                                           \
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < xofs_count; k++ )                                   \
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int dxn = xofs[k].di;                                           \
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float alpha = xofs[k].alpha;                                    \
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[dxn] = buf[dxn] + load_macro(src[xofs[k].si])*alpha;        \
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( cn == 2 )                                                      \
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < xofs_count; k++ )                                   \
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int sxn = xofs[k].si;                                           \
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int dxn = xofs[k].di;                                           \
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float alpha = xofs[k].alpha;                                    \
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t0 = buf[dxn] + load_macro(src[sxn])*alpha;               \
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t1 = buf[dxn+1] + load_macro(src[sxn+1])*alpha;           \
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[dxn] = t0; buf[dxn+1] = t1;                                 \
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( cn == 3 )                                                      \
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < xofs_count; k++ )                                   \
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int sxn = xofs[k].si;                                           \
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int dxn = xofs[k].di;                                           \
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float alpha = xofs[k].alpha;                                    \
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t0 = buf[dxn] + load_macro(src[sxn])*alpha;               \
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t1 = buf[dxn+1] + load_macro(src[sxn+1])*alpha;           \
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t2 = buf[dxn+2] + load_macro(src[sxn+2])*alpha;           \
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[dxn] = t0; buf[dxn+1] = t1; buf[dxn+2] = t2;                \
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else                                                                    \
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < xofs_count; k++ )                                   \
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int sxn = xofs[k].si;                                           \
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int dxn = xofs[k].di;                                           \
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float alpha = xofs[k].alpha;                                    \
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t0 = buf[dxn] + load_macro(src[sxn])*alpha;               \
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t1 = buf[dxn+1] + load_macro(src[sxn+1])*alpha;           \
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[dxn] = t0; buf[dxn+1] = t1;                                 \
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t0 = buf[dxn+2] + load_macro(src[sxn+2])*alpha;                 \
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t1 = buf[dxn+3] + load_macro(src[sxn+3])*alpha;                 \
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[dxn+2] = t0; buf[dxn+3] = t1;                               \
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (cur_dy + 1)*scale_y <= sy + 1 || sy == ssize.height - 1 )          \
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                       \
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float beta = sy + 1 - (cur_dy+1)*scale_y, beta1;                    \
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            beta = MAX( beta, 0 );                                              \
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            beta1 = 1 - beta;                                                   \
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( fabs(beta) < 1e-3 )                                             \
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( dx = 0; dx < dsize.width; dx++ )                           \
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                               \
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[dx] = (arrtype)cast_macro(sum[dx] + buf[dx]);           \
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sum[dx] = buf[dx] = 0;                                      \
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                               \
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else                                                                \
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( dx = 0; dx < dsize.width; dx++ )                           \
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                               \
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[dx] = (arrtype)cast_macro(sum[dx] + buf[dx]*beta1);     \
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sum[dx] = buf[dx]*beta;                                     \
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[dx] = 0;                                                \
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                               \
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst += dststep;                                                     \
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cur_dy++;                                                           \
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                       \
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else                                                                    \
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( dx = 0; dx < dsize.width; dx += 2 )                            \
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t0 = sum[dx] + buf[dx];                                   \
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t1 = sum[dx+1] + buf[dx+1];                               \
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum[dx] = t0; sum[dx+1] = t1;                                   \
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[dx] = buf[dx+1] = 0;                                        \
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                           \
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                               \
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  ICV_DEF_RESIZE_BICUBIC_FUNC( flavor, arrtype, worktype, load_macro,    \
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      cast_macro1, cast_macro2 )                \
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                                      \
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_Bicubic_##flavor##_CnR( const arrtype* src, int srcstep, CvSize ssize,\
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  arrtype* dst, int dststep, CvSize dsize,      \
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  int cn, int xmin, int xmax,                   \
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  const CvResizeAlpha* xofs, float** buf )      \
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                               \
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float scale_y = (float)ssize.height/dsize.height;                           \
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dx, dy, sx, sy, sy2, ify;                                               \
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int prev_sy2 = -2;                                                          \
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    xmin *= cn; xmax *= cn;                                                     \
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dsize.width *= cn;                                                          \
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ssize.width *= cn;                                                          \
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srcstep /= sizeof(src[0]);                                                  \
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dststep /= sizeof(dst[0]);                                                  \
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( dy = 0; dy < dsize.height; dy++, dst += dststep )                      \
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                           \
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float w0, w1, w2, w3;                                                   \
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float fy, x, sum;                                                       \
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float *row, *row0, *row1, *row2, *row3;                                 \
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int k1, k = 4;                                                          \
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        fy = dy*scale_y;                                                        \
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sy = cvFloor(fy);                                                       \
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        fy -= sy;                                                               \
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ify = cvRound(fy*ICV_CUBIC_TAB_SIZE);                                   \
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sy2 = sy + 2;                                                           \
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( sy2 > prev_sy2 )                                                    \
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                       \
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int delta = prev_sy2 - sy + 2;                                      \
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < delta; k++ )                                        \
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_SWAP( buf[k], buf[k+4-delta], row );                         \
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                       \
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( sy += k - 1; k < 4; k++, sy++ )                                    \
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                       \
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const arrtype* _src = src + sy*srcstep;                             \
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            row = buf[k];                                                       \
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( sy < 0 )                                                        \
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;                                                       \
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( sy >= ssize.height )                                            \
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                assert( k > 0 );                                                \
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                memcpy( row, buf[k-1], dsize.width*sizeof(row[0]) );            \
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;                                                       \
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( dx = 0; dx < xmin; dx++ )                                      \
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int ifx = xofs[dx].ialpha, sx0 = xofs[dx].idx;                  \
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sx = sx0 + cn*2;                                                \
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                while( sx >= ssize.width )                                      \
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sx -= cn;                                                   \
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x = load_macro(_src[sx]);                                       \
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum = x*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE - ifx)*2 + 1];       \
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)(sx = sx0 + cn) < (unsigned)ssize.width )         \
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x = load_macro(_src[sx]);                                   \
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum += x*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE - ifx)*2];          \
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)(sx = sx0) < (unsigned)ssize.width )              \
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x = load_macro(_src[sx]);                                   \
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum += x*icvCubicCoeffs[ifx*2];                                 \
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)(sx = sx0 - cn) < (unsigned)ssize.width )         \
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x = load_macro(_src[sx]);                                   \
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                row[dx] = sum + x*icvCubicCoeffs[ifx*2 + 1];                    \
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; dx < xmax; dx++ )                                            \
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int ifx = xofs[dx].ialpha;                                      \
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int sx0 = xofs[dx].idx;                                         \
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                row[dx] = _src[sx0 - cn]*icvCubicCoeffs[ifx*2 + 1] +            \
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    _src[sx0]*icvCubicCoeffs[ifx*2] +                           \
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    _src[sx0 + cn]*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ifx)*2] + \
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    _src[sx0 + cn*2]*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ifx)*2+1];\
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; dx < dsize.width; dx++ )                                     \
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int ifx = xofs[dx].ialpha, sx0 = xofs[dx].idx;                  \
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x = load_macro(_src[sx0 - cn]);                                 \
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum = x*icvCubicCoeffs[ifx*2 + 1];                              \
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)(sx = sx0) < (unsigned)ssize.width )              \
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x = load_macro(_src[sx]);                                   \
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum += x*icvCubicCoeffs[ifx*2];                                 \
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)(sx = sx0 + cn) < (unsigned)ssize.width )         \
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x = load_macro(_src[sx]);                                   \
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum += x*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE - ifx)*2];          \
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)(sx = sx0 + cn*2) < (unsigned)ssize.width )       \
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x = load_macro(_src[sx]);                                   \
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                row[dx] = sum + x*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ifx)*2+1]; \
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( sy == 0 )                                                       \
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k1 = 0; k1 < k; k1++ )                                     \
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    memcpy( buf[k1], row, dsize.width*sizeof(row[0]));          \
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                       \
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prev_sy2 = sy2;                                                         \
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        row0 = buf[0]; row1 = buf[1];                                           \
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        row2 = buf[2]; row3 = buf[3];                                           \
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w0 = icvCubicCoeffs[ify*2+1];                                           \
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w1 = icvCubicCoeffs[ify*2];                                             \
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w2 = icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE - ify)*2];                      \
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w3 = icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE - ify)*2 + 1];                  \
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( dx = 0; dx < dsize.width; dx++ )                                   \
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                       \
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype val = cast_macro1( row0[dx]*w0 + row1[dx]*w1 +             \
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        row2[dx]*w2 + row3[dx]*w3 );            \
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[dx] = cast_macro2(val);                                         \
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                       \
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                           \
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                               \
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_BILINEAR_FUNC( 8u, uchar, int, ialpha,
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              ICV_WARP_MUL_ONE_8U, ICV_WARP_DESCALE_8U )
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_BILINEAR_FUNC( 16u, ushort, float, alpha, CV_NOP, cvRound )
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_BILINEAR_FUNC( 32f, float, float, alpha, CV_NOP, CV_NOP )
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_BICUBIC_FUNC( 8u, uchar, int, CV_8TO32F, cvRound, CV_CAST_8U )
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_BICUBIC_FUNC( 16u, ushort, int, CV_NOP, cvRound, CV_CAST_16U )
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_BICUBIC_FUNC( 32f, float, float, CV_NOP, CV_NOP, CV_NOP )
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_AREA_FAST_FUNC( 8u, uchar, int, cvRound )
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_AREA_FAST_FUNC( 16u, ushort, int, cvRound )
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_AREA_FAST_FUNC( 32f, float, float, CV_NOP )
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_AREA_FUNC( 8u, uchar, CV_8TO32F, cvRound )
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_AREA_FUNC( 16u, ushort, CV_NOP, cvRound )
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_RESIZE_AREA_FUNC( 32f, float, CV_NOP, CV_NOP )
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvInitResizeTab( CvFuncTable* bilin_tab,
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              CvFuncTable* bicube_tab,
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              CvFuncTable* areafast_tab,
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              CvFuncTable* area_tab )
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilin_tab->fn_2d[CV_8U] = (void*)icvResize_Bilinear_8u_CnR;
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilin_tab->fn_2d[CV_16U] = (void*)icvResize_Bilinear_16u_CnR;
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilin_tab->fn_2d[CV_32F] = (void*)icvResize_Bilinear_32f_CnR;
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bicube_tab->fn_2d[CV_8U] = (void*)icvResize_Bicubic_8u_CnR;
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bicube_tab->fn_2d[CV_16U] = (void*)icvResize_Bicubic_16u_CnR;
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bicube_tab->fn_2d[CV_32F] = (void*)icvResize_Bicubic_32f_CnR;
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    areafast_tab->fn_2d[CV_8U] = (void*)icvResize_AreaFast_8u_CnR;
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    areafast_tab->fn_2d[CV_16U] = (void*)icvResize_AreaFast_16u_CnR;
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    areafast_tab->fn_2d[CV_32F] = (void*)icvResize_AreaFast_32f_CnR;
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    area_tab->fn_2d[CV_8U] = (void*)icvResize_Area_8u_CnR;
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    area_tab->fn_2d[CV_16U] = (void*)icvResize_Area_16u_CnR;
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    area_tab->fn_2d[CV_32F] = (void*)icvResize_Area_32f_CnR;
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvResizeBilinearFunc)
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( const void* src, int srcstep, CvSize ssize,
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      void* dst, int dststep, CvSize dsize,
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      int cn, int xmax, const CvResizeAlpha* xofs,
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      const CvResizeAlpha* yofs, float* buf0, float* buf1 );
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvResizeBicubicFunc)
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( const void* src, int srcstep, CvSize ssize,
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      void* dst, int dststep, CvSize dsize,
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      int cn, int xmin, int xmax,
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      const CvResizeAlpha* xofs, float** buf );
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvResizeAreaFastFunc)
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( const void* src, int srcstep, CvSize ssize,
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      void* dst, int dststep, CvSize dsize,
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      int cn, const int* ofs, const int *xofs );
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvResizeAreaFunc)
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ( const void* src, int srcstep, CvSize ssize,
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      void* dst, int dststep, CvSize dsize,
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      int cn, const CvDecimateAlpha* xofs,
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      int xofs_count, float* buf, float* sum );
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn////////////////////////////////// IPP resize functions //////////////////////////////////
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_8u_C1R_t icvResize_8u_C1R_p = 0;
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_8u_C3R_t icvResize_8u_C3R_p = 0;
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_8u_C4R_t icvResize_8u_C4R_p = 0;
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_16u_C1R_t icvResize_16u_C1R_p = 0;
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_16u_C3R_t icvResize_16u_C3R_p = 0;
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_16u_C4R_t icvResize_16u_C4R_p = 0;
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_32f_C1R_t icvResize_32f_C1R_p = 0;
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_32f_C3R_t icvResize_32f_C3R_p = 0;
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvResize_32f_C4R_t icvResize_32f_C4R_p = 0;
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvResizeIPPFunc)
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn( const void* src, CvSize srcsize, int srcstep, CvRect srcroi,
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  void* dst, int dststep, CvSize dstroi,
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  double xfactor, double yfactor, int interpolation );
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//////////////////////////////////////////////////////////////////////////////////////////
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvResize( const CvArr* srcarr, CvArr* dstarr, int method )
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static CvFuncTable bilin_tab, bicube_tab, areafast_tab, area_tab;
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int inittab = 0;
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* temp_buf = 0;
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvResize" );
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, *src = (CvMat*)srcarr;
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat dststub, *dst = (CvMat*)dstarr;
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize ssize, dsize;
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float scale_x, scale_y;
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int k, sx, sy, dx, dy;
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int type, depth, cn;
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( src = cvGetMat( srcarr, &srcstub ));
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( dst = cvGetMat( dstarr, &dststub ));
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CV_ARE_SIZES_EQ( src, dst ))
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvCopy( src, dst ));
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        EXIT;
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_TYPES_EQ( src, dst ))
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats, "" );
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !inittab )
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvInitResizeTab( &bilin_tab, &bicube_tab, &areafast_tab, &area_tab );
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inittab = 1;
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ssize = cvGetMatSize( src );
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dsize = cvGetMatSize( dst );
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    type = CV_MAT_TYPE(src->type);
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    depth = CV_MAT_DEPTH(type);
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cn = CV_MAT_CN(type);
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    scale_x = (float)ssize.width/dsize.width;
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    scale_y = (float)ssize.height/dsize.height;
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( method == CV_INTER_CUBIC &&
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (MIN(ssize.width, dsize.width) <= 4 ||
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        MIN(ssize.height, dsize.height) <= 4) )
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        method = CV_INTER_LINEAR;
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( icvResize_8u_C1R_p &&
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        MIN(ssize.width, dsize.width) > 4 &&
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        MIN(ssize.height, dsize.height) > 4 )
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvResizeIPPFunc ipp_func =
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC1 ? icvResize_8u_C1R_p :
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC3 ? icvResize_8u_C3R_p :
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC4 ? icvResize_8u_C4R_p :
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_16UC1 ? icvResize_16u_C1R_p :
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_16UC3 ? icvResize_16u_C3R_p :
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_16UC4 ? icvResize_16u_C4R_p :
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC1 ? icvResize_32f_C1R_p :
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC3 ? icvResize_32f_C3R_p :
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC4 ? icvResize_32f_C4R_p : 0;
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ipp_func && (CV_INTER_NN < method && method < CV_INTER_AREA))
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int srcstep = src->step ? src->step : CV_STUB_STEP;
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int dststep = dst->step ? dst->step : CV_STUB_STEP;
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            IPPI_CALL( ipp_func( src->data.ptr, ssize, srcstep,
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 cvRect(0,0,ssize.width,ssize.height),
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 dst->data.ptr, dststep, dsize,
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 (double)dsize.width/ssize.width,
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 (double)dsize.height/ssize.height, 1 << method ));
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            EXIT;
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( method == CV_INTER_NN )
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IPPI_CALL( icvResize_NN_8u_C1R( src->data.ptr, src->step, ssize,
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        dst->data.ptr, dst->step, dsize,
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        CV_ELEM_SIZE(src->type)));
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( method == CV_INTER_LINEAR || method == CV_INTER_AREA )
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( method == CV_INTER_AREA &&
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ssize.width >= dsize.width && ssize.height >= dsize.height )
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // "area" method for (scale_x > 1 & scale_y > 1)
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int iscale_x = cvRound(scale_x);
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int iscale_y = cvRound(scale_y);
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( fabs(scale_x - iscale_x) < DBL_EPSILON &&
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                fabs(scale_y - iscale_y) < DBL_EPSILON )
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int area = iscale_x*iscale_y;
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int srcstep = src->step / CV_ELEM_SIZE(depth);
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int* ofs = (int*)cvStackAlloc( (area + dsize.width*cn)*sizeof(int) );
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int* xofs = ofs + area;
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvResizeAreaFastFunc func = (CvResizeAreaFastFunc)areafast_tab.fn_2d[depth];
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !func )
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsUnsupportedFormat, "" );
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( sy = 0, k = 0; sy < iscale_y; sy++ )
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( sx = 0; sx < iscale_x; sx++ )
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ofs[k++] = sy*srcstep + sx*cn;
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( dx = 0; dx < dsize.width; dx++ )
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sx = dx*iscale_x*cn;
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 0; k < cn; k++ )
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[dx*cn + k] = sx + k;
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                IPPI_CALL( func( src->data.ptr, src->step, ssize, dst->data.ptr,
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 dst->step, dsize, cn, ofs, xofs ));
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int buf_len = dsize.width*cn + 4, buf_size, xofs_count = 0;
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float scale = 1.f/(scale_x*scale_y);
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float *buf, *sum;
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvDecimateAlpha* xofs;
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvResizeAreaFunc func = (CvResizeAreaFunc)area_tab.fn_2d[depth];
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !func || cn > 4 )
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsUnsupportedFormat, "" );
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf_size = buf_len*2*sizeof(float) + ssize.width*2*sizeof(CvDecimateAlpha);
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( buf_size < CV_MAX_LOCAL_SIZE )
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf = (float*)cvStackAlloc(buf_size);
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_CALL( temp_buf = buf = (float*)cvAlloc(buf_size));
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum = buf + buf_len;
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                xofs = (CvDecimateAlpha*)(sum + buf_len);
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( dx = 0, k = 0; dx < dsize.width; dx++ )
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float fsx1 = dx*scale_x, fsx2 = fsx1 + scale_x;
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int sx1 = cvCeil(fsx1), sx2 = cvFloor(fsx2);
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    assert( (unsigned)sx1 < (unsigned)ssize.width );
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( sx1 > fsx1 )
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        assert( k < ssize.width*2 );
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[k].di = dx*cn;
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[k].si = (sx1-1)*cn;
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[k++].alpha = (sx1 - fsx1)*scale;
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( sx = sx1; sx < sx2; sx++ )
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        assert( k < ssize.width*2 );
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[k].di = dx*cn;
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[k].si = sx*cn;
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[k++].alpha = scale;
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( fsx2 - sx2 > 1e-3 )
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        assert( k < ssize.width*2 );
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        assert((unsigned)sx2 < (unsigned)ssize.width );
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[k].di = dx*cn;
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[k].si = sx2*cn;
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[k++].alpha = (fsx2 - sx2)*scale;
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                xofs_count = k;
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                memset( sum, 0, buf_len*sizeof(float) );
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                memset( buf, 0, buf_len*sizeof(float) );
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                IPPI_CALL( func( src->data.ptr, src->step, ssize, dst->data.ptr,
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 dst->step, dsize, cn, xofs, xofs_count, buf, sum ));
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else // true "area" method for the cases (scale_x > 1 & scale_y < 1) and
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             // (scale_x < 1 & scale_y > 1) is not implemented.
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             // instead, it is emulated via some variant of bilinear interpolation.
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float inv_scale_x = (float)dsize.width/ssize.width;
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float inv_scale_y = (float)dsize.height/ssize.height;
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int xmax = dsize.width, width = dsize.width*cn, buf_size;
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float *buf0, *buf1;
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvResizeAlpha *xofs, *yofs;
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int area_mode = method == CV_INTER_AREA;
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float fx, fy;
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvResizeBilinearFunc func = (CvResizeBilinearFunc)bilin_tab.fn_2d[depth];
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !func )
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsUnsupportedFormat, "" );
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf_size = width*2*sizeof(float) + (width + dsize.height)*sizeof(CvResizeAlpha);
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( buf_size < CV_MAX_LOCAL_SIZE )
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf0 = (float*)cvStackAlloc(buf_size);
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_CALL( temp_buf = buf0 = (float*)cvAlloc(buf_size));
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf1 = buf0 + width;
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            xofs = (CvResizeAlpha*)(buf1 + width);
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            yofs = xofs + width;
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( dx = 0; dx < dsize.width; dx++ )
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !area_mode )
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    fx = (float)((dx+0.5)*scale_x - 0.5);
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sx = cvFloor(fx);
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    fx -= sx;
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sx = cvFloor(dx*scale_x);
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    fx = (dx+1) - (sx+1)*inv_scale_x;
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    fx = fx <= 0 ? 0.f : fx - cvFloor(fx);
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( sx < 0 )
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    fx = 0, sx = 0;
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( sx >= ssize.width-1 )
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    fx = 0, sx = ssize.width-1;
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( xmax >= dsize.width )
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xmax = dx;
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( depth != CV_8U )
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 0, sx *= cn; k < cn; k++ )
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[dx*cn + k].idx = sx + k, xofs[dx*cn + k].alpha = fx;
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 0, sx *= cn; k < cn; k++ )
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[dx*cn + k].idx = sx + k,
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xofs[dx*cn + k].ialpha = CV_FLT_TO_FIX(fx, ICV_WARP_SHIFT);
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( dy = 0; dy < dsize.height; dy++ )
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !area_mode )
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    fy = (float)((dy+0.5)*scale_y - 0.5);
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sy = cvFloor(fy);
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    fy -= sy;
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( sy < 0 )
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        sy = 0, fy = 0;
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sy = cvFloor(dy*scale_y);
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    fy = (dy+1) - (sy+1)*inv_scale_y;
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    fy = fy <= 0 ? 0.f : fy - cvFloor(fy);
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                yofs[dy].idx = sy;
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( depth != CV_8U )
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    yofs[dy].alpha = fy;
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    yofs[dy].ialpha = CV_FLT_TO_FIX(fy, ICV_WARP_SHIFT);
8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            IPPI_CALL( func( src->data.ptr, src->step, ssize, dst->data.ptr,
8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             dst->step, dsize, cn, xmax, xofs, yofs, buf0, buf1 ));
8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( method == CV_INTER_CUBIC )
8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int width = dsize.width*cn, buf_size;
8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int xmin = dsize.width, xmax = -1;
8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvResizeAlpha* xofs;
8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float* buf[4];
8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvResizeBicubicFunc func = (CvResizeBicubicFunc)bicube_tab.fn_2d[depth];
8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !func )
8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnsupportedFormat, "" );
8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buf_size = width*(4*sizeof(float) + sizeof(xofs[0]));
8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buf_size < CV_MAX_LOCAL_SIZE )
9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf[0] = (float*)cvStackAlloc(buf_size);
9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( temp_buf = buf[0] = (float*)cvAlloc(buf_size));
9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( k = 1; k < 4; k++ )
9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf[k] = buf[k-1] + width;
9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        xofs = (CvResizeAlpha*)(buf[3] + width);
9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvInitCubicCoeffTab();
9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( dx = 0; dx < dsize.width; dx++ )
9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float fx = dx*scale_x;
9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sx = cvFloor(fx);
9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            fx -= sx;
9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ifx = cvRound(fx*ICV_CUBIC_TAB_SIZE);
9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( sx-1 >= 0 && xmin > dx )
9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                xmin = dx;
9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( sx+2 < ssize.width )
9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                xmax = dx + 1;
9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // at least one of 4 points should be within the image - to
9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // be able to set other points to the same value. see the loops
9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // for( dx = 0; dx < xmin; dx++ ) ... and for( ; dx < width; dx++ ) ...
9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( sx < -2 )
9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sx = -2;
9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( sx > ssize.width )
9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sx = ssize.width;
9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < cn; k++ )
9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                xofs[dx*cn + k].idx = sx*cn + k;
9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                xofs[dx*cn + k].ialpha = ifx;
9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IPPI_CALL( func( src->data.ptr, src->step, ssize, dst->data.ptr,
9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         dst->step, dsize, cn, xmin, xmax, xofs, buf ));
9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadFlag, "Unknown/unsupported interpolation method" );
9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &temp_buf );
9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*                                     WarpAffine                                         *
9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DEF_WARP_AFFINE_BILINEAR_FUNC( flavor, arrtype, worktype,       \
9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scale_alpha_macro, mul_one_macro, descale_macro, cast_macro )   \
9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                                  \
9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpAffine_Bilinear_##flavor##_CnR(                                      \
9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const arrtype* src, int step, CvSize ssize,                             \
9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    arrtype* dst, int dststep, CvSize dsize,                                \
9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const double* matrix, int cn,                                           \
9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const arrtype* fillval, const int* ofs )                                \
9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                           \
9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x, y, k;                                                            \
9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double  A12 = matrix[1], b1 = matrix[2];                                \
9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double  A22 = matrix[4], b2 = matrix[5];                                \
9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    step /= sizeof(src[0]);                                                 \
9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dststep /= sizeof(dst[0]);                                              \
9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < dsize.height; y++, dst += dststep )                     \
9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                       \
9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int xs = CV_FLT_TO_FIX( A12*y + b1, ICV_WARP_SHIFT );               \
9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int ys = CV_FLT_TO_FIX( A22*y + b2, ICV_WARP_SHIFT );               \
9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < dsize.width; x++ )                                  \
9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                   \
9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ixs = xs + ofs[x*2];                                        \
9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int iys = ys + ofs[x*2+1];                                      \
9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype a = scale_alpha_macro( ixs & ICV_WARP_MASK );          \
9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype b = scale_alpha_macro( iys & ICV_WARP_MASK );          \
9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            worktype p0, p1;                                                \
9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ixs >>= ICV_WARP_SHIFT;                                         \
9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            iys >>= ICV_WARP_SHIFT;                                         \
9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( (unsigned)ixs < (unsigned)(ssize.width - 1) &&              \
9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (unsigned)iys < (unsigned)(ssize.height - 1) )              \
9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                               \
9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const arrtype* ptr = src + step*iys + ixs*cn;               \
9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < cn; k++ )                                   \
9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                           \
9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p0 = mul_one_macro(ptr[k]) +                            \
9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        a * (ptr[k+cn] - ptr[k]);                           \
9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p1 = mul_one_macro(ptr[k+step]) +                       \
9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        a * (ptr[k+cn+step] - ptr[k+step]);                 \
9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p0 = descale_macro(mul_one_macro(p0) + b*(p1 - p0));    \
9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x*cn+k] = (arrtype)cast_macro(p0);                  \
9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                           \
9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                               \
9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( (unsigned)(ixs+1) < (unsigned)(ssize.width+1) &&       \
9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     (unsigned)(iys+1) < (unsigned)(ssize.height+1))        \
10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                               \
10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int x0 = ICV_WARP_CLIP_X( ixs );                            \
10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int y0 = ICV_WARP_CLIP_Y( iys );                            \
10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int x1 = ICV_WARP_CLIP_X( ixs + 1 );                        \
10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int y1 = ICV_WARP_CLIP_Y( iys + 1 );                        \
10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const arrtype* ptr0, *ptr1, *ptr2, *ptr3;                   \
10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr0 = src + y0*step + x0*cn;                               \
10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr1 = src + y0*step + x1*cn;                               \
10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr2 = src + y1*step + x0*cn;                               \
10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr3 = src + y1*step + x1*cn;                               \
10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < cn; k++ )                                   \
10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                           \
10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p0 = mul_one_macro(ptr0[k]) + a * (ptr1[k] - ptr0[k]);  \
10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p1 = mul_one_macro(ptr2[k]) + a * (ptr3[k] - ptr2[k]);  \
10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p0 = descale_macro( mul_one_macro(p0) + b*(p1 - p0) );  \
10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x*cn+k] = (arrtype)cast_macro(p0);                  \
10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                           \
10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                               \
10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( fillval )                                              \
10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < cn; k++ )                                   \
10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x*cn+k] = fillval[k];                               \
10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                   \
10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                       \
10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                           \
10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_WARP_SCALE_ALPHA(x) ((x)*(1./(ICV_WARP_MASK+1)))
10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_WARP_AFFINE_BILINEAR_FUNC( 8u, uchar, int, CV_NOP, ICV_WARP_MUL_ONE_8U,
10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   ICV_WARP_DESCALE_8U, CV_NOP )
10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//ICV_DEF_WARP_AFFINE_BILINEAR_FUNC( 8u, uchar, double, ICV_WARP_SCALE_ALPHA, CV_NOP,
10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                                   CV_NOP, ICV_WARP_CAST_8U )
10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_WARP_AFFINE_BILINEAR_FUNC( 16u, ushort, double, ICV_WARP_SCALE_ALPHA, CV_NOP,
10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   CV_NOP, cvRound )
10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_WARP_AFFINE_BILINEAR_FUNC( 32f, float, double, ICV_WARP_SCALE_ALPHA, CV_NOP,
10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   CV_NOP, CV_NOP )
10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvWarpAffineFunc)(
10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const void* src, int srcstep, CvSize ssize,
10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* dst, int dststep, CvSize dsize,
10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const double* matrix, int cn,
10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const void* fillval, const int* ofs );
10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvInitWarpAffineTab( CvFuncTable* bilin_tab )
10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilin_tab->fn_2d[CV_8U] = (void*)icvWarpAffine_Bilinear_8u_CnR;
10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilin_tab->fn_2d[CV_16U] = (void*)icvWarpAffine_Bilinear_16u_CnR;
10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilin_tab->fn_2d[CV_32F] = (void*)icvWarpAffine_Bilinear_32f_CnR;
10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/////////////////////////////// IPP warpaffine functions /////////////////////////////////
10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpAffineBack_8u_C1R_t icvWarpAffineBack_8u_C1R_p = 0;
10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpAffineBack_8u_C3R_t icvWarpAffineBack_8u_C3R_p = 0;
10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpAffineBack_8u_C4R_t icvWarpAffineBack_8u_C4R_p = 0;
10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpAffineBack_32f_C1R_t icvWarpAffineBack_32f_C1R_p = 0;
10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpAffineBack_32f_C3R_t icvWarpAffineBack_32f_C3R_p = 0;
10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpAffineBack_32f_C4R_t icvWarpAffineBack_32f_C4R_p = 0;
10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvWarpAffineBackIPPFunc)
10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn( const void* src, CvSize srcsize, int srcstep, CvRect srcroi,
10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  void* dst, int dststep, CvRect dstroi,
10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const double* coeffs, int interpolation );
10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//////////////////////////////////////////////////////////////////////////////////////////
10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvWarpAffine( const CvArr* srcarr, CvArr* dstarr, const CvMat* matrix,
10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              int flags, CvScalar fillval )
10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static CvFuncTable bilin_tab;
10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int inittab = 0;
10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvWarpAffine" );
10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, *src = (CvMat*)srcarr;
10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat dststub, *dst = (CvMat*)dstarr;
10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int k, type, depth, cn, *ofs = 0;
10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double src_matrix[6], dst_matrix[6];
10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double fillbuf[4];
10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int method = flags & 3;
10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcAb = cvMat( 2, 3, CV_64F, src_matrix ),
10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn          dstAb = cvMat( 2, 3, CV_64F, dst_matrix ),
10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn          A, b, invA, invAb;
10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvWarpAffineFunc func;
10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize ssize, dsize;
10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !inittab )
10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvInitWarpAffineTab( &bilin_tab );
10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inittab = 1;
10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( src = cvGetMat( srcarr, &srcstub ));
11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( dst = cvGetMat( dstarr, &dststub ));
11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_TYPES_EQ( src, dst ))
11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats, "" );
11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(matrix) || CV_MAT_CN(matrix->type) != 1 ||
11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_MAT_DEPTH(matrix->type) < CV_32F || matrix->rows != 2 || matrix->cols != 3 )
11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg,
11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "Transformation matrix should be 2x3 floating-point single-channel matrix" );
11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( flags & CV_WARP_INVERSE_MAP )
11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvConvertScale( matrix, &dstAb );
11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // [R|t] -> [R^-1 | -(R^-1)*t]
11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvConvertScale( matrix, &srcAb );
11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvGetCols( &srcAb, &A, 0, 2 );
11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvGetCol( &srcAb, &b, 2 );
11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvGetCols( &dstAb, &invA, 0, 2 );
11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvGetCol( &dstAb, &invAb, 2 );
11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvInvert( &A, &invA, CV_SVD );
11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvGEMM( &invA, &b, -1, 0, 0, &invAb );
11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    type = CV_MAT_TYPE(src->type);
11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    depth = CV_MAT_DEPTH(type);
11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cn = CV_MAT_CN(type);
11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cn > 4 )
11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, "" );
11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ssize = cvGetMatSize(src);
11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dsize = cvGetMatSize(dst);
11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( icvWarpAffineBack_8u_C1R_p && MIN( ssize.width, dsize.width ) >= 4 &&
11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        MIN( ssize.height, dsize.height ) >= 4 )
11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvWarpAffineBackIPPFunc ipp_func =
11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC1 ? icvWarpAffineBack_8u_C1R_p :
11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC3 ? icvWarpAffineBack_8u_C3R_p :
11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC4 ? icvWarpAffineBack_8u_C4R_p :
11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC1 ? icvWarpAffineBack_32f_C1R_p :
11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC3 ? icvWarpAffineBack_32f_C3R_p :
11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC4 ? icvWarpAffineBack_32f_C4R_p : 0;
11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ipp_func && CV_INTER_NN <= method && method <= CV_INTER_AREA )
11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int srcstep = src->step ? src->step : CV_STUB_STEP;
11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int dststep = dst->step ? dst->step : CV_STUB_STEP;
11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvRect srcroi = {0, 0, ssize.width, ssize.height};
11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvRect dstroi = {0, 0, dsize.width, dsize.height};
11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // this is not the most efficient way to fill outliers
11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( flags & CV_WARP_FILL_OUTLIERS )
11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvSet( dst, fillval );
11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( ipp_func( src->data.ptr, ssize, srcstep, srcroi,
11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          dst->data.ptr, dststep, dstroi,
11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          dstAb.data.db, 1 << method ) >= 0 )
11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                EXIT;
11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvScalarToRawData( &fillval, fillbuf, CV_MAT_TYPE(src->type), 0 );
11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ofs = (int*)cvStackAlloc( dst->cols*2*sizeof(ofs[0]) );
11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( k = 0; k < dst->cols; k++ )
11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ofs[2*k] = CV_FLT_TO_FIX( dst_matrix[0]*k, ICV_WARP_SHIFT );
11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ofs[2*k+1] = CV_FLT_TO_FIX( dst_matrix[3]*k, ICV_WARP_SHIFT );
11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*if( method == CV_INTER_LINEAR )*/
11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        func = (CvWarpAffineFunc)bilin_tab.fn_2d[depth];
11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !func )
11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnsupportedFormat, "" );
11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IPPI_CALL( func( src->data.ptr, src->step, ssize, dst->data.ptr,
11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         dst->step, dsize, dst_matrix, cn,
11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         flags & CV_WARP_FILL_OUTLIERS ? fillbuf : 0, ofs ));
11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvMat*
11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renncv2DRotationMatrix( CvPoint2D32f center, double angle,
11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double scale, CvMat* matrix )
11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvGetRotationMatrix" );
11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double m[2][3];
11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat M = cvMat( 2, 3, CV_64FC1, m );
11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double alpha, beta;
11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !matrix )
12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    angle *= CV_PI/180;
12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    alpha = cos(angle)*scale;
12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    beta = sin(angle)*scale;
12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m[0][0] = alpha;
12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m[0][1] = beta;
12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m[0][2] = (1-alpha)*center.x - beta*center.y;
12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m[1][0] = -beta;
12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m[1][1] = alpha;
12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m[1][2] = beta*center.x + (1-alpha)*center.y;
12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvConvert( &M, matrix );
12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return matrix;
12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*                                    WarpPerspective                                     *
12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DEF_WARP_PERSPECTIVE_BILINEAR_FUNC( flavor, arrtype, load_macro, cast_macro )\
12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                                  \
12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspective_Bilinear_##flavor##_CnR(                                 \
12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const arrtype* src, int step, CvSize ssize,                             \
12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    arrtype* dst, int dststep, CvSize dsize,                                \
12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const double* matrix, int cn,                                           \
12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const arrtype* fillval )                                                \
12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                           \
12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x, y, k;                                                            \
12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float A11 = (float)matrix[0], A12 = (float)matrix[1], A13 = (float)matrix[2];\
12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float A21 = (float)matrix[3], A22 = (float)matrix[4], A23 = (float)matrix[5];\
12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float A31 = (float)matrix[6], A32 = (float)matrix[7], A33 = (float)matrix[8];\
12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    step /= sizeof(src[0]);                                                 \
12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dststep /= sizeof(dst[0]);                                              \
12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < dsize.height; y++, dst += dststep )                     \
12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                       \
12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float xs0 = A12*y + A13;                                            \
12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float ys0 = A22*y + A23;                                            \
12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float ws = A32*y + A33;                                             \
12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < dsize.width; x++, xs0 += A11, ys0 += A21, ws += A31 )\
12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                   \
12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float inv_ws = 1.f/ws;                                          \
12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float xs = xs0*inv_ws;                                          \
12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float ys = ys0*inv_ws;                                          \
12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ixs = cvFloor(xs);                                          \
12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int iys = cvFloor(ys);                                          \
12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float a = xs - ixs;                                             \
12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float b = ys - iys;                                             \
12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float p0, p1;                                                   \
12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( (unsigned)ixs < (unsigned)(ssize.width - 1) &&              \
12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (unsigned)iys < (unsigned)(ssize.height - 1) )              \
12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                               \
12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const arrtype* ptr = src + step*iys + ixs*cn;               \
12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < cn; k++ )                                   \
12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                           \
12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p0 = load_macro(ptr[k]) +                               \
12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        a * (load_macro(ptr[k+cn]) - load_macro(ptr[k]));   \
12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p1 = load_macro(ptr[k+step]) +                          \
12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        a * (load_macro(ptr[k+cn+step]) -                   \
12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             load_macro(ptr[k+step]));                      \
12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x*cn+k] = (arrtype)cast_macro(p0 + b*(p1 - p0));    \
12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                           \
12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                               \
12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( (unsigned)(ixs+1) < (unsigned)(ssize.width+1) &&       \
12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     (unsigned)(iys+1) < (unsigned)(ssize.height+1))        \
12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                               \
12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int x0 = ICV_WARP_CLIP_X( ixs );                            \
12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int y0 = ICV_WARP_CLIP_Y( iys );                            \
12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int x1 = ICV_WARP_CLIP_X( ixs + 1 );                        \
12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int y1 = ICV_WARP_CLIP_Y( iys + 1 );                        \
12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const arrtype* ptr0, *ptr1, *ptr2, *ptr3;                   \
12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr0 = src + y0*step + x0*cn;                               \
12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr1 = src + y0*step + x1*cn;                               \
12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr2 = src + y1*step + x0*cn;                               \
12856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr3 = src + y1*step + x1*cn;                               \
12866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
12876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < cn; k++ )                                   \
12886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                           \
12896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p0 = load_macro(ptr0[k]) +                              \
12906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        a * (load_macro(ptr1[k]) - load_macro(ptr0[k]));    \
12916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    p1 = load_macro(ptr2[k]) +                              \
12926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        a * (load_macro(ptr3[k]) - load_macro(ptr2[k]));    \
12936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x*cn+k] = (arrtype)cast_macro(p0 + b*(p1 - p0));    \
12946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                           \
12956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                               \
12966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( fillval )                                              \
12976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < cn; k++ )                                   \
12986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x*cn+k] = fillval[k];                               \
12996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                   \
13006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                       \
13016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
13026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                           \
13036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_WARP_SCALE_ALPHA(x) ((x)*(1./(ICV_WARP_MASK+1)))
13076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_WARP_PERSPECTIVE_BILINEAR_FUNC( 8u, uchar, CV_8TO32F, cvRound )
13096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_WARP_PERSPECTIVE_BILINEAR_FUNC( 16u, ushort, CV_NOP, cvRound )
13106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_WARP_PERSPECTIVE_BILINEAR_FUNC( 32f, float, CV_NOP, CV_NOP )
13116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvWarpPerspectiveFunc)(
13136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const void* src, int srcstep, CvSize ssize,
13146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* dst, int dststep, CvSize dsize,
13156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const double* matrix, int cn, const void* fillval );
13166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvInitWarpPerspectiveTab( CvFuncTable* bilin_tab )
13186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
13196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilin_tab->fn_2d[CV_8U] = (void*)icvWarpPerspective_Bilinear_8u_CnR;
13206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilin_tab->fn_2d[CV_16U] = (void*)icvWarpPerspective_Bilinear_16u_CnR;
13216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilin_tab->fn_2d[CV_32F] = (void*)icvWarpPerspective_Bilinear_32f_CnR;
13226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
13236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/////////////////////////// IPP warpperspective functions ////////////////////////////////
13266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspectiveBack_8u_C1R_t icvWarpPerspectiveBack_8u_C1R_p = 0;
13286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspectiveBack_8u_C3R_t icvWarpPerspectiveBack_8u_C3R_p = 0;
13296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspectiveBack_8u_C4R_t icvWarpPerspectiveBack_8u_C4R_p = 0;
13306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspectiveBack_32f_C1R_t icvWarpPerspectiveBack_32f_C1R_p = 0;
13316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspectiveBack_32f_C3R_t icvWarpPerspectiveBack_32f_C3R_p = 0;
13326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspectiveBack_32f_C4R_t icvWarpPerspectiveBack_32f_C4R_p = 0;
13336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspective_8u_C1R_t icvWarpPerspective_8u_C1R_p = 0;
13356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspective_8u_C3R_t icvWarpPerspective_8u_C3R_p = 0;
13366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspective_8u_C4R_t icvWarpPerspective_8u_C4R_p = 0;
13376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspective_32f_C1R_t icvWarpPerspective_32f_C1R_p = 0;
13386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspective_32f_C3R_t icvWarpPerspective_32f_C3R_p = 0;
13396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvWarpPerspective_32f_C4R_t icvWarpPerspective_32f_C4R_p = 0;
13406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvWarpPerspectiveBackIPPFunc)
13426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn( const void* src, CvSize srcsize, int srcstep, CvRect srcroi,
13436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  void* dst, int dststep, CvRect dstroi,
13446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const double* coeffs, int interpolation );
13456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//////////////////////////////////////////////////////////////////////////////////////////
13476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
13496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvWarpPerspective( const CvArr* srcarr, CvArr* dstarr,
13506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   const CvMat* matrix, int flags, CvScalar fillval )
13516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
13526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static CvFuncTable bilin_tab;
13536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int inittab = 0;
13546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvWarpPerspective" );
13566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
13586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, *src = (CvMat*)srcarr;
13606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat dststub, *dst = (CvMat*)dstarr;
13616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int type, depth, cn;
13626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int method = flags & 3;
13636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double src_matrix[9], dst_matrix[9];
13646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double fillbuf[4];
13656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat A = cvMat( 3, 3, CV_64F, src_matrix ),
13666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn          invA = cvMat( 3, 3, CV_64F, dst_matrix );
13676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvWarpPerspectiveFunc func;
13686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize ssize, dsize;
13696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( method == CV_INTER_NN || method == CV_INTER_AREA )
13716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        method = CV_INTER_LINEAR;
13726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !inittab )
13746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
13756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvInitWarpPerspectiveTab( &bilin_tab );
13766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inittab = 1;
13776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
13786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( src = cvGetMat( srcarr, &srcstub ));
13806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( dst = cvGetMat( dstarr, &dststub ));
13816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_TYPES_EQ( src, dst ))
13836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats, "" );
13846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(matrix) || CV_MAT_CN(matrix->type) != 1 ||
13866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_MAT_DEPTH(matrix->type) < CV_32F || matrix->rows != 3 || matrix->cols != 3 )
13876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg,
13886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "Transformation matrix should be 3x3 floating-point single-channel matrix" );
13896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( flags & CV_WARP_INVERSE_MAP )
13916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvConvertScale( matrix, &invA );
13926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
13936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
13946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvConvertScale( matrix, &A );
13956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvInvert( &A, &invA, CV_SVD );
13966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
13976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    type = CV_MAT_TYPE(src->type);
13996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    depth = CV_MAT_DEPTH(type);
14006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cn = CV_MAT_CN(type);
14016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cn > 4 )
14026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, "" );
14036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ssize = cvGetMatSize(src);
14056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dsize = cvGetMatSize(dst);
14066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( icvWarpPerspectiveBack_8u_C1R_p )
14086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
14096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvWarpPerspectiveBackIPPFunc ipp_func =
14106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC1 ? icvWarpPerspectiveBack_8u_C1R_p :
14116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC3 ? icvWarpPerspectiveBack_8u_C3R_p :
14126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC4 ? icvWarpPerspectiveBack_8u_C4R_p :
14136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC1 ? icvWarpPerspectiveBack_32f_C1R_p :
14146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC3 ? icvWarpPerspectiveBack_32f_C3R_p :
14156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC4 ? icvWarpPerspectiveBack_32f_C4R_p : 0;
14166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ipp_func && CV_INTER_NN <= method && method <= CV_INTER_AREA &&
14186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            MIN(ssize.width,ssize.height) >= 4 && MIN(dsize.width,dsize.height) >= 4 )
14196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
14206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int srcstep = src->step ? src->step : CV_STUB_STEP;
14216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int dststep = dst->step ? dst->step : CV_STUB_STEP;
14226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvStatus status;
14236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvRect srcroi = {0, 0, ssize.width, ssize.height};
14246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvRect dstroi = {0, 0, dsize.width, dsize.height};
14256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // this is not the most efficient way to fill outliers
14276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( flags & CV_WARP_FILL_OUTLIERS )
14286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvSet( dst, fillval );
14296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            status = ipp_func( src->data.ptr, ssize, srcstep, srcroi,
14316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               dst->data.ptr, dststep, dstroi,
14326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               invA.data.db, 1 << method );
14336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 )
14346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                EXIT;
14356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ipp_func = type == CV_8UC1 ? icvWarpPerspective_8u_C1R_p :
14376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                type == CV_8UC3 ? icvWarpPerspective_8u_C3R_p :
14386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                type == CV_8UC4 ? icvWarpPerspective_8u_C4R_p :
14396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                type == CV_32FC1 ? icvWarpPerspective_32f_C1R_p :
14406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                type == CV_32FC3 ? icvWarpPerspective_32f_C3R_p :
14416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                type == CV_32FC4 ? icvWarpPerspective_32f_C4R_p : 0;
14426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( ipp_func )
14446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( flags & CV_WARP_INVERSE_MAP )
14466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cvInvert( &invA, &A, CV_SVD );
14476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                status = ipp_func( src->data.ptr, ssize, srcstep, srcroi,
14496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               dst->data.ptr, dststep, dstroi,
14506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               A.data.db, 1 << method );
14516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( status >= 0 )
14526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    EXIT;
14536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
14556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
14566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvScalarToRawData( &fillval, fillbuf, CV_MAT_TYPE(src->type), 0 );
14586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*if( method == CV_INTER_LINEAR )*/
14606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
14616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        func = (CvWarpPerspectiveFunc)bilin_tab.fn_2d[depth];
14626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !func )
14636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnsupportedFormat, "" );
14646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IPPI_CALL( func( src->data.ptr, src->step, ssize, dst->data.ptr,
14666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         dst->step, dsize, dst_matrix, cn,
14676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         flags & CV_WARP_FILL_OUTLIERS ? fillbuf : 0 ));
14686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
14696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
14716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Calculates coefficients of perspective transformation
14756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * which maps (xi,yi) to (ui,vi), (i=1,2,3,4):
14766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *
14776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *      c00*xi + c01*yi + c02
14786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * ui = ---------------------
14796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *      c20*xi + c21*yi + c22
14806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *
14816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *      c10*xi + c11*yi + c12
14826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * vi = ---------------------
14836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *      c20*xi + c21*yi + c22
14846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *
14856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * Coefficients are calculated by solving linear system:
14866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * / x0 y0  1  0  0  0 -x0*u0 -y0*u0 \ /c00\ /u0\
14876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * | x1 y1  1  0  0  0 -x1*u1 -y1*u1 | |c01| |u1|
14886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * | x2 y2  1  0  0  0 -x2*u2 -y2*u2 | |c02| |u2|
14896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * | x3 y3  1  0  0  0 -x3*u3 -y3*u3 |.|c10|=|u3|,
14906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * |  0  0  0 x0 y0  1 -x0*v0 -y0*v0 | |c11| |v0|
14916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * |  0  0  0 x1 y1  1 -x1*v1 -y1*v1 | |c12| |v1|
14926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * |  0  0  0 x2 y2  1 -x2*v2 -y2*v2 | |c20| |v2|
14936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * \  0  0  0 x3 y3  1 -x3*v3 -y3*v3 / \c21/ \v3/
14946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *
14956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * where:
14966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *   cij - matrix coefficients, c22 = 1
14976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */
14986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvMat*
14996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGetPerspectiveTransform( const CvPoint2D32f* src,
15006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          const CvPoint2D32f* dst,
15016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          CvMat* matrix )
15026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
15036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvGetPerspectiveTransform" );
15046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
15066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double a[8][8];
15086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double b[8], x[9];
15096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat A = cvMat( 8, 8, CV_64FC1, a );
15116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat B = cvMat( 8, 1, CV_64FC1, b );
15126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat X = cvMat( 8, 1, CV_64FC1, x );
15136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
15156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !src || !dst || !matrix )
15176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
15186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < 4; ++i )
15206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
15216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[i][0] = a[i+4][3] = src[i].x;
15226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[i][1] = a[i+4][4] = src[i].y;
15236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[i][2] = a[i+4][5] = 1;
15246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[i][3] = a[i][4] = a[i][5] =
15256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[i+4][0] = a[i+4][1] = a[i+4][2] = 0;
15266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[i][6] = -src[i].x*dst[i].x;
15276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[i][7] = -src[i].y*dst[i].x;
15286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[i+4][6] = -src[i].x*dst[i].y;
15296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a[i+4][7] = -src[i].y*dst[i].y;
15306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        b[i] = dst[i].x;
15316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        b[i+4] = dst[i].y;
15326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
15336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvSolve( &A, &B, &X, CV_SVD );
15356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    x[8] = 1;
15366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    X = cvMat( 3, 3, CV_64FC1, x );
15386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvConvert( &X, matrix );
15396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
15416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return matrix;
15436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
15446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Calculates coefficients of affine transformation
15466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * which maps (xi,yi) to (ui,vi), (i=1,2,3):
15476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *
15486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * ui = c00*xi + c01*yi + c02
15496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *
15506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * vi = c10*xi + c11*yi + c12
15516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *
15526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * Coefficients are calculated by solving linear system:
15536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * / x0 y0  1  0  0  0 \ /c00\ /u0\
15546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * | x1 y1  1  0  0  0 | |c01| |u1|
15556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * | x2 y2  1  0  0  0 | |c02| |u2|
15566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * |  0  0  0 x0 y0  1 | |c10| |v0|
15576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * |  0  0  0 x1 y1  1 | |c11| |v1|
15586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * \  0  0  0 x2 y2  1 / |c12| |v2|
15596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *
15606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * where:
15616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *   cij - matrix coefficients
15626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */
15636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvMat*
15646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGetAffineTransform( const CvPoint2D32f * src, const CvPoint2D32f * dst, CvMat * map_matrix )
15656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
15666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvGetAffineTransform" );
15676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
15696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat mA, mX, mB;
15716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double A[6*6];
15726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double B[6];
15736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	double x[6];
15746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
15756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvInitMatHeader(&mA, 6, 6, CV_64F, A);
15776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvInitMatHeader(&mB, 6, 1, CV_64F, B);
15786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	cvInitMatHeader(&mX, 6, 1, CV_64F, x);
15796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	if( !src || !dst || !map_matrix )
15816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		CV_ERROR( CV_StsNullPtr, "" );
15826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < 3; i++ )
15846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
15856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int j = i*12;
15866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int k = i*12+6;
15876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        A[j] = A[k+3] = src[i].x;
15886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        A[j+1] = A[k+4] = src[i].y;
15896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        A[j+2] = A[k+5] = 1;
15906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        A[j+3] = A[j+4] = A[j+5] = 0;
15916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        A[k] = A[k+1] = A[k+2] = 0;
15926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        B[i*2] = dst[i].x;
15936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        B[i*2+1] = dst[i].y;
15946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
15956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvSolve(&mA, &mB, &mX);
15966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    mX = cvMat( 2, 3, CV_64FC1, x );
15986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	cvConvert( &mX, map_matrix );
15996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	__END__;
16016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return map_matrix;
16026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
16036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
16056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*                          Generic Geometric Transformation: Remap                       *
16066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
16076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  ICV_DEF_REMAP_BILINEAR_FUNC( flavor, arrtype, load_macro, cast_macro ) \
16096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                                      \
16106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvRemap_Bilinear_##flavor##_CnR( const arrtype* src, int srcstep, CvSize ssize,\
16116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         arrtype* dst, int dststep, CvSize dsize,           \
16126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         const float* mapx, int mxstep,                     \
16136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         const float* mapy, int mystep,                     \
16146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         int cn, const arrtype* fillval )                   \
16156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                           \
16166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, k;                                                            \
16176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ssize.width--;                                                          \
16186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ssize.height--;                                                         \
16196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
16206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srcstep /= sizeof(src[0]);                                              \
16216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dststep /= sizeof(dst[0]);                                              \
16226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    mxstep /= sizeof(mapx[0]);                                              \
16236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    mystep /= sizeof(mapy[0]);                                              \
16246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
16256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < dsize.height; i++, dst += dststep,                      \
16266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  mapx += mxstep, mapy += mystep )          \
16276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                       \
16286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < dsize.width; j++ )                                  \
16296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                   \
16306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float _x = mapx[j], _y = mapy[j];                               \
16316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ix = cvFloor(_x), iy = cvFloor(_y);                         \
16326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
16336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( (unsigned)ix < (unsigned)ssize.width &&                     \
16346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (unsigned)iy < (unsigned)ssize.height )                     \
16356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                               \
16366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const arrtype* s = src + iy*srcstep + ix*cn;                \
16376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _x -= ix; _y -= iy;                                         \
16386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < cn; k++, s++ )                              \
16396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                           \
16406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float t0 = load_macro(s[0]), t1 = load_macro(s[srcstep]); \
16416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    t0 += _x*(load_macro(s[cn]) - t0);                      \
16426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    t1 += _x*(load_macro(s[srcstep + cn]) - t1);            \
16436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j*cn + k] = (arrtype)cast_macro(t0 + _y*(t1 - t0)); \
16446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                           \
16456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                               \
16466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( fillval )                                              \
16476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < cn; k++ )                                   \
16486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j*cn + k] = fillval[k];                             \
16496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                   \
16506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                       \
16516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                            \
16526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                           \
16536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
16546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  ICV_DEF_REMAP_BICUBIC_FUNC( flavor, arrtype, worktype,                 \
16576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                     load_macro, cast_macro1, cast_macro2 )     \
16586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                                      \
16596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvRemap_Bicubic_##flavor##_CnR( const arrtype* src, int srcstep, CvSize ssize, \
16606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         arrtype* dst, int dststep, CvSize dsize,               \
16616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         const float* mapx, int mxstep,                         \
16626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         const float* mapy, int mystep,                         \
16636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         int cn, const arrtype* fillval )                       \
16646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                               \
16656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, k;                                                                \
16666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ssize.width = MAX( ssize.width - 3, 0 );                                    \
16676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ssize.height = MAX( ssize.height - 3, 0 );                                  \
16686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
16696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srcstep /= sizeof(src[0]);                                                  \
16706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dststep /= sizeof(dst[0]);                                                  \
16716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    mxstep /= sizeof(mapx[0]);                                                  \
16726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    mystep /= sizeof(mapy[0]);                                                  \
16736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
16746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < dsize.height; i++, dst += dststep,                          \
16756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  mapx += mxstep, mapy += mystep )              \
16766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                           \
16776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < dsize.width; j++ )                                      \
16786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                       \
16796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ix = cvRound(mapx[j]*(1 << ICV_WARP_SHIFT));                    \
16806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int iy = cvRound(mapy[j]*(1 << ICV_WARP_SHIFT));                    \
16816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ifx = ix & ICV_WARP_MASK;                                       \
16826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ify = iy & ICV_WARP_MASK;                                       \
16836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ix >>= ICV_WARP_SHIFT;                                              \
16846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            iy >>= ICV_WARP_SHIFT;                                              \
16856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
16866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( (unsigned)(ix-1) < (unsigned)ssize.width &&                     \
16876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (unsigned)(iy-1) < (unsigned)ssize.height )                     \
16886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                   \
16896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < cn; k++ )                                       \
16906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                               \
16916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const arrtype* s = src + (iy-1)*srcstep + ix*cn + k;        \
16926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
16936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float t0 = load_macro(s[-cn])*icvCubicCoeffs[ifx*2 + 1] +   \
16946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[0])*icvCubicCoeffs[ifx*2] +         \
16956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[cn])*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ifx)*2] +\
16966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[cn*2])*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ifx)*2+1];\
16976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
16986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s += srcstep;                                               \
16996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
17006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float t1 = load_macro(s[-cn])*icvCubicCoeffs[ifx*2 + 1] +   \
17016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[0])*icvCubicCoeffs[ifx*2] +         \
17026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[cn])*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ifx)*2] +\
17036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[cn*2])*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ifx)*2+1];\
17046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
17056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s += srcstep;                                               \
17066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
17076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float t2 = load_macro(s[-cn])*icvCubicCoeffs[ifx*2 + 1] +   \
17086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[0])*icvCubicCoeffs[ifx*2] +         \
17096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[cn])*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ifx)*2] +\
17106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[cn*2])*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ifx)*2+1];\
17116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
17126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s += srcstep;                                               \
17136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
17146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float t3 = load_macro(s[-cn])*icvCubicCoeffs[ifx*2 + 1] +   \
17156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[0])*icvCubicCoeffs[ifx*2] +         \
17166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[cn])*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ifx)*2] +\
17176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               load_macro(s[cn*2])*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ifx)*2+1];\
17186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
17196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    worktype t = cast_macro1( t0*icvCubicCoeffs[ify*2 + 1] +    \
17206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               t1*icvCubicCoeffs[ify*2] +                       \
17216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               t2*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ify)*2] +  \
17226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               t3*icvCubicCoeffs[(ICV_CUBIC_TAB_SIZE-ify)*2+1] );\
17236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
17246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j*cn + k] = cast_macro2(t);                             \
17256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                               \
17266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                   \
17276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( fillval )                                                  \
17286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < cn; k++ )                                       \
17296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j*cn + k] = fillval[k];                                 \
17306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                       \
17316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                           \
17326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                \
17336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                               \
17346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
17356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_REMAP_BILINEAR_FUNC( 8u, uchar, CV_8TO32F, cvRound )
17386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_REMAP_BILINEAR_FUNC( 16u, ushort, CV_NOP, cvRound )
17396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_REMAP_BILINEAR_FUNC( 32f, float, CV_NOP, CV_NOP )
17406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_REMAP_BICUBIC_FUNC( 8u, uchar, int, CV_8TO32F, cvRound, CV_FAST_CAST_8U )
17426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_REMAP_BICUBIC_FUNC( 16u, ushort, int, CV_NOP, cvRound, CV_CAST_16U )
17436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_REMAP_BICUBIC_FUNC( 32f, float, float, CV_NOP, CV_NOP, CV_NOP )
17446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvRemapFunc)(
17466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const void* src, int srcstep, CvSize ssize,
17476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* dst, int dststep, CvSize dsize,
17486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const float* mapx, int mxstep,
17496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const float* mapy, int mystep,
17506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cn, const void* fillval );
17516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvInitRemapTab( CvFuncTable* bilinear_tab, CvFuncTable* bicubic_tab )
17536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
17546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilinear_tab->fn_2d[CV_8U] = (void*)icvRemap_Bilinear_8u_CnR;
17556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilinear_tab->fn_2d[CV_16U] = (void*)icvRemap_Bilinear_16u_CnR;
17566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bilinear_tab->fn_2d[CV_32F] = (void*)icvRemap_Bilinear_32f_CnR;
17576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bicubic_tab->fn_2d[CV_8U] = (void*)icvRemap_Bicubic_8u_CnR;
17596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bicubic_tab->fn_2d[CV_16U] = (void*)icvRemap_Bicubic_16u_CnR;
17606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bicubic_tab->fn_2d[CV_32F] = (void*)icvRemap_Bicubic_32f_CnR;
17616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
17626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/******************** IPP remap functions *********************/
17656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvRemapIPPFunc)(
17676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const void* src, CvSize srcsize, int srcstep, CvRect srcroi,
17686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const float* xmap, int xmapstep, const float* ymap, int ymapstep,
17696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* dst, int dststep, CvSize dstsize, int interpolation );
17706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvRemap_8u_C1R_t icvRemap_8u_C1R_p = 0;
17726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvRemap_8u_C3R_t icvRemap_8u_C3R_p = 0;
17736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvRemap_8u_C4R_t icvRemap_8u_C4R_p = 0;
17746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvRemap_32f_C1R_t icvRemap_32f_C1R_p = 0;
17766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvRemap_32f_C3R_t icvRemap_32f_C3R_p = 0;
17776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvRemap_32f_C4R_t icvRemap_32f_C4R_p = 0;
17786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/**************************************************************/
17806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_REMAP_SHIFT 5
17826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_REMAP_MASK ((1 << CV_REMAP_SHIFT) - 1)
17836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if CV_SSE2 && defined(__GNUC__)
17856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define align(x) __attribute__ ((aligned (x)))
17866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#elif CV_SSE2 && (defined(__ICL) || defined _MSC_VER && _MSC_VER >= 1300)
17876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define align(x) __declspec(align(x))
17886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
17896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define align(x)
17906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
17916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvRemapFixedPt_8u( const CvMat* src, CvMat* dst,
17936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvMat* xymap, const CvMat* amap, const uchar* fillval )
17946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
17956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int TABSZ = 1 << (CV_REMAP_SHIFT*2);
17966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static ushort align(8) atab[TABSZ][4];
17976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int inittab = 0;
17986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x, y, cols = src->cols, rows = src->rows;
18006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const uchar* sptr0 = src->data.ptr;
18016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int sstep = src->step;
18026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar fv0 = fillval[0], fv1 = fillval[1], fv2 = fillval[2], fv3 = fillval[3];
18036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cn = CV_MAT_CN(src->type);
18046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if CV_SSE2
18056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const uchar* sptr1 = sptr0 + sstep;
18066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __m128i br = _mm_set1_epi32((cols-2) + ((rows-2)<<16));
18076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __m128i xy2ofs = _mm_set1_epi32(1 + (sstep << 16));
18086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __m128i z = _mm_setzero_si128();
18096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int align(16) iofs0[4], iofs1[4];
18106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
18116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !inittab )
18136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( y = 0; y <= CV_REMAP_MASK; y++ )
18156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( x = 0; x <= CV_REMAP_MASK; x++ )
18166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
18176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int k = (y << CV_REMAP_SHIFT) + x;
18186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                atab[k][0] = (ushort)((CV_REMAP_MASK+1 - y)*(CV_REMAP_MASK+1 - x));
18196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                atab[k][1] = (ushort)((CV_REMAP_MASK+1 - y)*x);
18206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                atab[k][2] = (ushort)(y*(CV_REMAP_MASK+1 - x));
18216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                atab[k][3] = (ushort)(y*x);
18226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
18236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inittab = 1;
18246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < rows; y++ )
18276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const short* xy = (const short*)(xymap->data.ptr + xymap->step*y);
18296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const ushort* alpha = (const ushort*)(amap->data.ptr + amap->step*y);
18306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        uchar* dptr = (uchar*)(dst->data.ptr + dst->step*y);
18316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int x = 0;
18326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( cn == 1 )
18346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
18356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #if CV_SSE2
18366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; x <= cols - 8; x += 8 )
18376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
18386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                __m128i xy0 = _mm_load_si128( (const __m128i*)(xy + x*2));
18396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                __m128i xy1 = _mm_load_si128( (const __m128i*)(xy + x*2 + 8));
18406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                // 0|0|0|0|... <= x0|y0|x1|y1|... < cols-1|rows-1|cols-1|rows-1|... ?
18416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                __m128i mask0 = _mm_cmpeq_epi32(_mm_or_si128(_mm_cmpgt_epi16(z, xy0),
18426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                _mm_cmpgt_epi16(xy0,br)), z);
18436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                __m128i mask1 = _mm_cmpeq_epi32(_mm_or_si128(_mm_cmpgt_epi16(z, xy1),
18446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                _mm_cmpgt_epi16(xy1,br)), z);
18456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                __m128i ofs0 = _mm_and_si128(_mm_madd_epi16( xy0, xy2ofs ), mask0 );
18466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                __m128i ofs1 = _mm_and_si128(_mm_madd_epi16( xy1, xy2ofs ), mask1 );
18476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                unsigned i0, i1;
18486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                __m128i v0, v1, v2, v3, a0, a1, b0, b1;
18496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _mm_store_si128( (__m128i*)iofs0, ofs0 );
18506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _mm_store_si128( (__m128i*)iofs1, ofs1 );
18516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i0 = *(ushort*)(sptr0 + iofs0[0]) + (*(ushort*)(sptr0 + iofs0[1]) << 16);
18526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i1 = *(ushort*)(sptr0 + iofs0[2]) + (*(ushort*)(sptr0 + iofs0[3]) << 16);
18536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0 = _mm_unpacklo_epi32(_mm_cvtsi32_si128(i0), _mm_cvtsi32_si128(i1));
18546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i0 = *(ushort*)(sptr1 + iofs0[0]) + (*(ushort*)(sptr1 + iofs0[1]) << 16);
18556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i1 = *(ushort*)(sptr1 + iofs0[2]) + (*(ushort*)(sptr1 + iofs0[3]) << 16);
18566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v1 = _mm_unpacklo_epi32(_mm_cvtsi32_si128(i0), _mm_cvtsi32_si128(i1));
18576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0 = _mm_unpacklo_epi8(v0, z);
18586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v1 = _mm_unpacklo_epi8(v1, z);
18596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a0 = _mm_unpacklo_epi32(_mm_loadl_epi64((__m128i*)atab[alpha[x]]),
18616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        _mm_loadl_epi64((__m128i*)atab[alpha[x+1]]));
18626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a1 = _mm_unpacklo_epi32(_mm_loadl_epi64((__m128i*)atab[alpha[x+2]]),
18636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        _mm_loadl_epi64((__m128i*)atab[alpha[x+3]]));
18646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                b0 = _mm_unpacklo_epi64(a0, a1);
18656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                b1 = _mm_unpackhi_epi64(a0, a1);
18666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0 = _mm_madd_epi16(v0, b0);
18676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v1 = _mm_madd_epi16(v1, b1);
18686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0 = _mm_and_si128(_mm_add_epi32(v0, v1), mask0);
18696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i0 = *(ushort*)(sptr0 + iofs1[0]) + (*(ushort*)(sptr0 + iofs1[1]) << 16);
18716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i1 = *(ushort*)(sptr0 + iofs1[2]) + (*(ushort*)(sptr0 + iofs1[3]) << 16);
18726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v2 = _mm_unpacklo_epi32(_mm_cvtsi32_si128(i0), _mm_cvtsi32_si128(i1));
18736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i0 = *(ushort*)(sptr1 + iofs1[0]) + (*(ushort*)(sptr1 + iofs1[1]) << 16);
18746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i1 = *(ushort*)(sptr1 + iofs1[2]) + (*(ushort*)(sptr1 + iofs1[3]) << 16);
18756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v3 = _mm_unpacklo_epi32(_mm_cvtsi32_si128(i0), _mm_cvtsi32_si128(i1));
18766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v2 = _mm_unpacklo_epi8(v2, z);
18776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v3 = _mm_unpacklo_epi8(v3, z);
18786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a0 = _mm_unpacklo_epi32(_mm_loadl_epi64((__m128i*)atab[alpha[x+4]]),
18806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        _mm_loadl_epi64((__m128i*)atab[alpha[x+5]]));
18816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a1 = _mm_unpacklo_epi32(_mm_loadl_epi64((__m128i*)atab[alpha[x+6]]),
18826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        _mm_loadl_epi64((__m128i*)atab[alpha[x+7]]));
18836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                b0 = _mm_unpacklo_epi64(a0, a1);
18846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                b1 = _mm_unpackhi_epi64(a0, a1);
18856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v2 = _mm_madd_epi16(v2, b0);
18866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v3 = _mm_madd_epi16(v3, b1);
18876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v2 = _mm_and_si128(_mm_add_epi32(v2, v3), mask1);
18886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0 = _mm_srai_epi32(v0, CV_REMAP_SHIFT*2);
18906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v2 = _mm_srai_epi32(v2, CV_REMAP_SHIFT*2);
18916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0 = _mm_packus_epi16(_mm_packs_epi32(v0, v2), z);
18926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                _mm_storel_epi64( (__m128i*)(dptr + x), v0 );
18936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
18946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #endif
18956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; x < cols; x++ )
18976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
18986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int xi = xy[x*2], yi = xy[x*2+1];
18996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)yi >= (unsigned)(rows - 1) ||
19006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    (unsigned)xi >= (unsigned)(cols - 1))
19016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
19026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dptr[x] = fv0;
19036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
19046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
19056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
19066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const uchar* sptr = sptr0 + sstep*yi + xi;
19076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const ushort* a = atab[alpha[x]];
19086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dptr[x] = (uchar)((sptr[0]*a[0] + sptr[1]*a[1] + sptr[sstep]*a[2] +
19096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      sptr[sstep+1]*a[3])>>CV_REMAP_SHIFT*2);
19106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
19116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
19126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
19136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( cn == 3 )
19146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
19156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; x < cols; x++ )
19166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
19176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int xi = xy[x*2], yi = xy[x*2+1];
19186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)yi >= (unsigned)(rows - 1) ||
19196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    (unsigned)xi >= (unsigned)(cols - 1))
19206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
19216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dptr[x*3] = fv0; dptr[x*3+1] = fv1; dptr[x*3+2] = fv2;
19226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
19236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
19246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
19256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const uchar* sptr = sptr0 + sstep*yi + xi*3;
19266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const ushort* a = atab[alpha[x]];
19276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int v0, v1, v2;
19286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0 = (sptr[0]*a[0] + sptr[3]*a[1] +
19296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        sptr[sstep]*a[2] + sptr[sstep+3]*a[3])>>CV_REMAP_SHIFT*2;
19306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1 = (sptr[1]*a[0] + sptr[4]*a[1] +
19316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        sptr[sstep+1]*a[2] + sptr[sstep+4]*a[3])>>CV_REMAP_SHIFT*2;
19326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v2 = (sptr[2]*a[0] + sptr[5]*a[1] +
19336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        sptr[sstep+2]*a[2] + sptr[sstep+5]*a[3])>>CV_REMAP_SHIFT*2;
19346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dptr[x*3] = (uchar)v0; dptr[x*3+1] = (uchar)v1; dptr[x*3+2] = (uchar)v2;
19356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
19366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
19376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
19386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
19396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
19406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( cn == 4 );
19416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; x < cols; x++ )
19426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
19436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int xi = xy[x*2], yi = xy[x*2+1];
19446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)yi >= (unsigned)(rows - 1) ||
19456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    (unsigned)xi >= (unsigned)(cols - 1))
19466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
19476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dptr[x*4] = fv0; dptr[x*4+1] = fv1;
19486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dptr[x*4+2] = fv2; dptr[x*4+3] = fv3;
19496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
19506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
19516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
19526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const uchar* sptr = sptr0 + sstep*yi + xi*3;
19536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    const ushort* a = atab[alpha[x]];
19546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int v0, v1;
19556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0 = (sptr[0]*a[0] + sptr[4]*a[1] +
19566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        sptr[sstep]*a[2] + sptr[sstep+3]*a[3])>>CV_REMAP_SHIFT*2;
19576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1 = (sptr[1]*a[0] + sptr[5]*a[1] +
19586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        sptr[sstep+1]*a[2] + sptr[sstep+5]*a[3])>>CV_REMAP_SHIFT*2;
19596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dptr[x*4] = (uchar)v0; dptr[x*4+1] = (uchar)v1;
19606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0 = (sptr[2]*a[0] + sptr[6]*a[1] +
19616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        sptr[sstep+2]*a[2] + sptr[sstep+6]*a[3])>>CV_REMAP_SHIFT*2;
19626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1 = (sptr[3]*a[0] + sptr[7]*a[1] +
19636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        sptr[sstep+3]*a[2] + sptr[sstep+7]*a[3])>>CV_REMAP_SHIFT*2;
19646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dptr[x*4+2] = (uchar)v0; dptr[x*4+3] = (uchar)v1;
19656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
19666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
19676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
19686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
19696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
19706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
19736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvRemap( const CvArr* srcarr, CvArr* dstarr,
19746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn         const CvArr* _mapx, const CvArr* _mapy,
19756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn         int flags, CvScalar fillval )
19766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
19776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static CvFuncTable bilinear_tab;
19786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static CvFuncTable bicubic_tab;
19796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int inittab = 0;
19806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvRemap" );
19826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
19846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, *src = (CvMat*)srcarr;
19866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat dststub, *dst = (CvMat*)dstarr;
19876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat mxstub, *mapx = (CvMat*)_mapx;
19886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat mystub, *mapy = (CvMat*)_mapy;
19896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int type, depth, cn;
19906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bool fltremap;
19916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int method = flags & 3;
19926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double fillbuf[4];
19936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize ssize, dsize;
19946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !inittab )
19966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
19976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvInitRemapTab( &bilinear_tab, &bicubic_tab );
19986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvInitLinearCoeffTab();
19996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvInitCubicCoeffTab();
20006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inittab = 1;
20016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
20026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( src = cvGetMat( srcarr, &srcstub ));
20046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( dst = cvGetMat( dstarr, &dststub ));
20056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mapx = cvGetMat( mapx, &mxstub ));
20066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mapy = cvGetMat( mapy, &mystub ));
20076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_TYPES_EQ( src, dst ))
20096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats, "" );
20106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CV_MAT_TYPE(mapx->type) == CV_16SC1 && CV_MAT_TYPE(mapy->type) == CV_16SC2 )
20126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
20136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat* temp;
20146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_SWAP(mapx, mapy, temp);
20156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
20166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (CV_MAT_TYPE(mapx->type) != CV_32FC1 || CV_MAT_TYPE(mapy->type) != CV_32FC1) &&
20186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (CV_MAT_TYPE(mapx->type) != CV_16SC2 || CV_MAT_TYPE(mapy->type) != CV_16SC1))
20196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats, "Either both map arrays must have 32fC1 type, "
20206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "or one of them must be 16sC2 and the other one must be 16sC1" );
20216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_SIZES_EQ( mapx, mapy ) || !CV_ARE_SIZES_EQ( mapx, dst ))
20236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedSizes,
20246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "Both map arrays and the destination array must have the same size" );
20256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    fltremap = CV_MAT_TYPE(mapx->type) == CV_32FC1;
20276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    type = CV_MAT_TYPE(src->type);
20286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    depth = CV_MAT_DEPTH(type);
20296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cn = CV_MAT_CN(type);
20306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cn > 4 )
20316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, "" );
20326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ssize = cvGetMatSize(src);
20346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dsize = cvGetMatSize(dst);
20356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvScalarToRawData( &fillval, fillbuf, CV_MAT_TYPE(src->type), 0 );
20376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !fltremap )
20396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
20406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( CV_MAT_TYPE(src->type) != CV_8UC1 && CV_MAT_TYPE(src->type) != CV_8UC3 &&
20416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_MAT_TYPE(src->type) != CV_8UC4 )
20426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnsupportedFormat,
20436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "Only 8-bit input/output is supported by the fixed-point variant of cvRemap" );
20446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvRemapFixedPt_8u( src, dst, mapx, mapy, (uchar*)fillbuf );
20456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        EXIT;
20466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
20476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( icvRemap_8u_C1R_p )
20496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
20506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvRemapIPPFunc ipp_func =
20516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC1 ? icvRemap_8u_C1R_p :
20526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC3 ? icvRemap_8u_C3R_p :
20536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_8UC4 ? icvRemap_8u_C4R_p :
20546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC1 ? icvRemap_32f_C1R_p :
20556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC3 ? icvRemap_32f_C3R_p :
20566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            type == CV_32FC4 ? icvRemap_32f_C4R_p : 0;
20576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ipp_func )
20596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
20606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int srcstep = src->step ? src->step : CV_STUB_STEP;
20616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int dststep = dst->step ? dst->step : CV_STUB_STEP;
20626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int mxstep = mapx->step ? mapx->step : CV_STUB_STEP;
20636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int mystep = mapy->step ? mapy->step : CV_STUB_STEP;
20646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvStatus status;
20656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvRect srcroi = {0, 0, ssize.width, ssize.height};
20666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // this is not the most efficient way to fill outliers
20686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( flags & CV_WARP_FILL_OUTLIERS )
20696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvSet( dst, fillval );
20706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            status = ipp_func( src->data.ptr, ssize, srcstep, srcroi,
20726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               mapx->data.fl, mxstep, mapy->data.fl, mystep,
20736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               dst->data.ptr, dststep, dsize,
20746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               1 << (method == CV_INTER_NN || method == CV_INTER_LINEAR ||
20756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               method == CV_INTER_CUBIC ? method : CV_INTER_LINEAR) );
20766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( status >= 0 )
20776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                EXIT;
20786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
20796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
20806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
20826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvRemapFunc func = method == CV_INTER_CUBIC ?
20836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            (CvRemapFunc)bicubic_tab.fn_2d[depth] :
20846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            (CvRemapFunc)bilinear_tab.fn_2d[depth];
20856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !func )
20876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnsupportedFormat, "" );
20886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        func( src->data.ptr, src->step, ssize, dst->data.ptr, dst->step, dsize,
20906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              mapx->data.fl, mapx->step, mapy->data.fl, mapy->step,
20916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              cn, flags & CV_WARP_FILL_OUTLIERS ? fillbuf : 0 );
20926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
20936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
20956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
20966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
20986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvConvertMaps( const CvArr* arrx, const CvArr* arry,
20996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               CvArr* arrxy, CvArr* arra )
21006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
21016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvConvertMaps" );
21026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
21046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat xstub, *mapx = cvGetMat( arrx, &xstub );
21066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat ystub, *mapy = cvGetMat( arry, &ystub );
21076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat xystub, *mapxy = cvGetMat( arrxy, &xystub );
21086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat astub, *mapa = cvGetMat( arra, &astub );
21096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x, y, cols = mapx->cols, rows = mapx->rows;
21106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT( CV_ARE_SIZES_EQ(mapx, mapy) && CV_ARE_TYPES_EQ(mapx, mapy) &&
21126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_MAT_TYPE(mapx->type) == CV_32FC1 &&
21136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ARE_SIZES_EQ(mapxy, mapx) && CV_ARE_SIZES_EQ(mapxy, mapa) &&
21146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_MAT_TYPE(mapxy->type) == CV_16SC2 &&
21156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_MAT_TYPE(mapa->type) == CV_16SC1 );
21166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < rows; y++ )
21186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
21196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const float* xrow = (const float*)(mapx->data.ptr + mapx->step*y);
21206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const float* yrow = (const float*)(mapy->data.ptr + mapy->step*y);
21216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        short* xy = (short*)(mapxy->data.ptr + mapxy->step*y);
21226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        short* alpha = (short*)(mapa->data.ptr + mapa->step*y);
21236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < cols; x++ )
21256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
21266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int xi = cvRound(xrow[x]*(1 << CV_REMAP_SHIFT));
21276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int yi = cvRound(yrow[x]*(1 << CV_REMAP_SHIFT));
21286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            xy[x*2] = (short)(xi >> CV_REMAP_SHIFT);
21296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            xy[x*2+1] = (short)(yi >> CV_REMAP_SHIFT);
21306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            alpha[x] = (short)((xi & CV_REMAP_MASK) + ((yi & CV_REMAP_MASK)<<CV_REMAP_SHIFT));
21316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
21326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
21336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
21356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
21366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
21396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*                                   Log-Polar Transform                                  *
21406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
21416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* now it is done via Remap; more correct implementation should use
21436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   some super-sampling technique outside of the "fovea" circle */
21446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
21456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvLogPolar( const CvArr* srcarr, CvArr* dstarr,
21466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvPoint2D32f center, double M, int flags )
21476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
21486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* mapx = 0;
21496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat* mapy = 0;
21506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double* exp_tab = 0;
21516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float* buf = 0;
21526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvLogPolar" );
21546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
21566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, *src = (CvMat*)srcarr;
21586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat dststub, *dst = (CvMat*)dstarr;
21596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize ssize, dsize;
21606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( src = cvGetMat( srcarr, &srcstub ));
21626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( dst = cvGetMat( dstarr, &dststub ));
21636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_TYPES_EQ( src, dst ))
21656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats, "" );
21666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( M <= 0 )
21686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "M should be >0" );
21696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ssize = cvGetMatSize(src);
21716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dsize = cvGetMatSize(dst);
21726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mapx = cvCreateMat( dsize.height, dsize.width, CV_32F ));
21746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mapy = cvCreateMat( dsize.height, dsize.width, CV_32F ));
21756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !(flags & CV_WARP_INVERSE_MAP) )
21776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
21786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int phi, rho;
21796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( exp_tab = (double*)cvAlloc( dsize.width*sizeof(exp_tab[0])) );
21816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( rho = 0; rho < dst->width; rho++ )
21836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            exp_tab[rho] = exp(rho/M);
21846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( phi = 0; phi < dsize.height; phi++ )
21866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
21876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double cp = cos(phi*2*CV_PI/dsize.height);
21886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double sp = sin(phi*2*CV_PI/dsize.height);
21896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float* mx = (float*)(mapx->data.ptr + phi*mapx->step);
21906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float* my = (float*)(mapy->data.ptr + phi*mapy->step);
21916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( rho = 0; rho < dsize.width; rho++ )
21936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
21946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r = exp_tab[rho];
21956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double x = r*cp + center.x;
21966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double y = r*sp + center.y;
21976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                mx[rho] = (float)x;
21996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                my[rho] = (float)y;
22006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
22016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
22026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
22036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
22046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
22056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int x, y;
22066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat bufx, bufy, bufp, bufa;
22076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double ascale = (ssize.width-1)/(2*CV_PI);
22086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( buf = (float*)cvAlloc( 4*dsize.width*sizeof(buf[0]) ));
22106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bufx = cvMat( 1, dsize.width, CV_32F, buf );
22126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bufy = cvMat( 1, dsize.width, CV_32F, buf + dsize.width );
22136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bufp = cvMat( 1, dsize.width, CV_32F, buf + dsize.width*2 );
22146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bufa = cvMat( 1, dsize.width, CV_32F, buf + dsize.width*3 );
22156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < dsize.width; x++ )
22176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            bufx.data.fl[x] = (float)x - center.x;
22186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( y = 0; y < dsize.height; y++ )
22206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
22216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float* mx = (float*)(mapx->data.ptr + y*mapx->step);
22226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float* my = (float*)(mapy->data.ptr + y*mapy->step);
22236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( x = 0; x < dsize.width; x++ )
22256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                bufy.data.fl[x] = (float)y - center.y;
22266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 1
22286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvCartToPolar( &bufx, &bufy, &bufp, &bufa );
22296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( x = 0; x < dsize.width; x++ )
22316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                bufp.data.fl[x] += 1.f;
22326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvLog( &bufp, &bufp );
22346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( x = 0; x < dsize.width; x++ )
22366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
22376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double rho = bufp.data.fl[x]*M;
22386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double phi = bufa.data.fl[x]*ascale;
22396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                mx[x] = (float)rho;
22416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                my[x] = (float)phi;
22426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
22436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
22446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( x = 0; x < dsize.width; x++ )
22456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
22466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double xx = bufx.data.fl[x];
22476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double yy = bufy.data.fl[x];
22486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double p = log(sqrt(xx*xx + yy*yy) + 1.)*M;
22506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double a = atan2(yy,xx);
22516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( a < 0 )
22526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    a = 2*CV_PI + a;
22536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a *= ascale;
22546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                mx[x] = (float)p;
22566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                my[x] = (float)a;
22576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
22586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
22596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
22606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
22616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvRemap( src, dst, mapx, mapy, flags, cvScalarAll(0) );
22636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
22656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &exp_tab );
22676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &buf );
22686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat( &mapx );
22696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMat( &mapy );
22706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
22716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
2273