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