16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cv.h"
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         Down-sampling pyramids core functions
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//////////// Filtering macros /////////////
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* COMMON CASE */
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 1/16[1    4    6    4    1]       */
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* ...| x0 | x1 | x2 | x3 | x4 |...  */
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PD_FILTER( x0, x1, x2, x3, x4 ) ((x2)*6+((x1)+(x3))*4+(x0)+(x4))
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* MACROS FOR BORDERS */
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* | b I a | b | reflection used ("I" denotes the image boundary) */
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* LEFT/TOP */
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 1/16[1    4    6    4    1]       */
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*    | x2 | x1 I x0 | x1 | x2 |...  */
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PD_LT(x0,x1,x2)                 ((x0)*6 + (x1)*8 + (x2)*2)
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* RIGHT/BOTTOM */
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 1/16[1    4    6    4    1]       */
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* ...| x0 | x1 | x2 | x3 I x2 |     */
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PD_RB(x0,x1,x2,x3)              ((x0) + ((x1) + (x3))*4 + (x2)*7)
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* SINGULAR CASE ( width == 2 || height == 2 ) */
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 1/16[1    4    6    4    1]       */
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*    | x0 | x1 I x0 | x1 I x0 |     */
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PD_SINGULAR(x0,x1)    (((x0) + (x1))*8)
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PD_SCALE_INT(x)       (((x) + (1<<7)) >> 8)
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PD_SCALE_FLT(x)       ((x)*0.00390625f)
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PD_SZ  5
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn////////// generic macro ////////////
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DEF_PYR_DOWN_FUNC( flavor, type, worktype, _pd_scale_ )                     \
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                                              \
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrDownG5x5_##flavor##_CnR( const type* src, int srcstep, type* dst,                 \
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               int dststep, CvSize size, void *buf, int Cs )            \
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                                       \
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    worktype*  buffer = (worktype*)buf;  /* pointer to temporary buffer */              \
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    worktype*  rows[PD_SZ]; /* array of rows pointers. dim(rows) is PD_SZ */            \
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int  y, top_row = 0;                                                                \
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int  Wd = size.width/2, Wdn = Wd*Cs;                                                \
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int  buffer_step = Wdn;                                                             \
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int  pd_sz = (PD_SZ + 1)*buffer_step;                                               \
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int  fst = 0, lst = size.height <= PD_SZ/2 ? size.height : PD_SZ/2 + 1;             \
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( Cs == 1 || Cs == 3 );                                                       \
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srcstep /= sizeof(src[0]); dststep /= sizeof(dst[0]);                               \
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* main loop */                                                                     \
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < size.height; y += 2, dst += dststep )                               \
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                                   \
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* set first and last indices of buffer rows which are need to be filled */     \
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int x, y1, k = top_row;                                                         \
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int x1 = buffer_step;                                                           \
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        worktype *row01, *row23, *row4;                                                 \
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* assign rows pointers */                                                      \
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( y1 = 0; y1 < PD_SZ; y1++ )                                                 \
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            rows[y1] = buffer + k;                                                      \
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            k += buffer_step;                                                           \
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            k &= k < pd_sz ? -1 : 0;                                                    \
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        row01 = rows[0];                                                                \
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        row23 = rows[2];                                                                \
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        row4  = rows[4];                                                                \
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* fill new buffer rows with filtered source (horizontal conv) */               \
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( Cs == 1 )                                                                   \
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( size.width > PD_SZ/2 )                                                  \
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( y1 = fst; y1 < lst; y1++, src += srcstep )                         \
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    worktype *row = rows[y1];                                           \
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* process left & right bounds */                                   \
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row[0]    = PD_LT( src[0], src[1], src[2] );                        \
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row[Wd-1] = PD_RB( src[Wd*2-4], src[Wd*2-3],                        \
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       src[Wd*2-2], src[Wd*2-1]);                       \
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* other points (even) */                                           \
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( x = 1; x < Wd - 1; x++ )                                       \
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[x] = PD_FILTER( src[2*x-2], src[2*x-1], src[2*x],           \
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            src[2*x+1], src[2*x+2] );                   \
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else                                                                        \
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( y1 = fst; y1 < lst; y1++, src += srcstep )                         \
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    rows[y1][0] = PD_SINGULAR( src[0], src[1] );                        \
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else /* Cs == 3 */                                                              \
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( y1 = fst; y1 < lst; y1++, src += srcstep )                             \
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                worktype *row = rows[y1];                                               \
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( size.width > PD_SZ/2 )                                              \
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int c;                                                              \
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( c = 0; c < 3; c++ )                                            \
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        /* process left & right bounds  */                              \
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[c] = PD_LT( src[c], src[3+c], src[6+c] );                   \
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[Wdn-3+c] = PD_RB( src[Wdn*2-12+c], src[Wdn*2-9+c],          \
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              src[Wdn*2-6+c], src[Wdn*2-3+c] );         \
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* other points (even) */                                           \
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( x = 3; x < Wdn - 3; x += 3 )                                   \
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[x]   = PD_FILTER( src[2*x-6], src[2*x-3], src[2*x],         \
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              src[2*x+3], src[2*x+6] );                 \
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[x+1] = PD_FILTER( src[2*x-5], src[2*x-2], src[2*x+1],       \
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              src[2*x+4], src[2*x+7] );                 \
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[x+2] = PD_FILTER( src[2*x-4], src[2*x-1], src[2*x+2],       \
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              src[2*x+5], src[2*x+8] );                 \
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else /* size.width <= PD_SZ/2 */                                        \
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row[0] = PD_SINGULAR( src[0], src[3] );                             \
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row[1] = PD_SINGULAR( src[1], src[4] );                             \
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row[2] = PD_SINGULAR( src[2], src[5] );                             \
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* second pass. Do vertical conv and write results do destination image */      \
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( y > 0 )                                                                     \
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( y < size.height - PD_SZ/2 )                                             \
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( x = 0; x < Wdn; x++, x1++ )                                        \
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x] = (type)_pd_scale_( PD_FILTER( row01[x],  row01[x1],         \
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                               row23[x], row23[x1], row4[x] ));         \
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                top_row += 2*buffer_step;                                               \
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                top_row &= top_row < pd_sz ? -1 : 0;                                    \
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else /* bottom */                                                           \
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( x = 0; x < Wdn; x++, x1++ )                                        \
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x] = (type)_pd_scale_( PD_RB( row01[x], row01[x1],              \
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                      row23[x], row23[x1]));            \
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else                                                                            \
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( size.height > PD_SZ/2 ) /* top */                                       \
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( x = 0; x < Wdn; x++, x1++ )                                        \
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x] = (type)_pd_scale_( PD_LT( row01[x], row01[x1], row23[x] )); \
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else /* size.height <= PD_SZ/2 */                                           \
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( x = 0; x < Wdn; x++, x1++ )                                        \
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x] = (type)_pd_scale_( PD_SINGULAR( row01[x], row01[x1] ));     \
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            fst = PD_SZ - 2;                                                            \
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lst = y + 2 + PD_SZ/2 < size.height ? PD_SZ : size.height - y;                  \
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                                   \
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                                       \
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_DOWN_FUNC( 8u, uchar, int, PD_SCALE_INT )
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_DOWN_FUNC( 16s, short, int, PD_SCALE_INT )
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_DOWN_FUNC( 16u, ushort, int, PD_SCALE_INT )
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_DOWN_FUNC( 32f, float, float, PD_SCALE_FLT )
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_DOWN_FUNC( 64f, double, double, PD_SCALE_FLT )
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           Up-sampling pyramids core functions
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/////////// filtering macros //////////////
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* COMMON CASE: NON ZERO */
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 1/16[1    4   6    4   1]       */
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* ...| x0 | 0 | x1 | 0 | x2 |...  */
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PU_FILTER( x0, x1, x2 )         ((x1)*6 + (x0) + (x2))
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* ZERO POINT AT CENTER */
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 1/16[1   4    6   4    1]      */
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* ...| 0 | x0 | 0 | x1 | 0 |...  */
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PU_FILTER_ZI( x0, x1 )          (((x0) + (x1))*4)
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* MACROS FOR BORDERS */
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* | b I a | b | reflection */
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* LEFT/TOP */
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 1/16[1    4   6    4   1]       */
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*    | x1 | 0 I x0 | 0 | x1 |...  */
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PU_LT( x0, x1 )                 ((x0)*6 + (x1)*2)
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 1/16[1   4    6   4    1]       */
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*    | 0 I x0 | 0 | x1 | 0 |...   */
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PU_LT_ZI( x0, x1 )              PU_FILTER_ZI((x0),(x1))
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* RIGHT/BOTTOM: NON ZERO */
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 1/16[1    4   6    4   1]       */
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* ...| x0 | 0 | x1 | 0 I x1 |     */
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PU_RB( x0, x1 )                 ((x0) + (x1)*7)
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* RIGHT/BOTTOM: ZERO POINT AT CENTER */
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 1/16[1   4    6   4    1]       */
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* ...| 0 | x0 | 0 I x0 | 0 |      */
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PU_RB_ZI( x0 )                  ((x0)*8)
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* SINGULAR CASE */
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 1/16[1    4   6    4   1]       */
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*    | x0 | 0 I x0 | 0 I x0 |     */
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PU_SINGULAR( x0 )               PU_RB_ZI((x0)) /* <--| the same formulas */
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PU_SINGULAR_ZI( x0 )            PU_RB_ZI((x0)) /* <--| */
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* x/64  - scaling in up-sampling functions */
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PU_SCALE_INT(x)                 (((x) + (1<<5)) >> 6)
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PU_SCALE_FLT(x)                 ((x)*0.015625f)
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  PU_SZ  3
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//////////// generic macro /////////////
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DEF_PYR_UP_FUNC( flavor, type, worktype, _pu_scale_ )                       \
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                                              \
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrUpG5x5_##flavor##_CnR( const type* src, int srcstep, type* dst,                   \
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             int dststep, CvSize size, void *buf, int Cs )              \
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                                       \
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    worktype *buffer = (worktype*)buf;                                                  \
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    worktype *rows[PU_SZ];                                                              \
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int y, top_row = 0;                                                                 \
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int Wd = size.width * 2, Wdn = Wd * Cs, Wn = size.width * Cs;                       \
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int buffer_step = Wdn;                                                              \
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int pu_sz = PU_SZ*buffer_step;                                                      \
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int fst = 0, lst = size.height <= PU_SZ/2 ? size.height : PU_SZ/2 + 1;              \
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( Cs == 1 || Cs == 3 );                                                       \
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    srcstep /= sizeof(src[0]); dststep /= sizeof(dst[0]);                               \
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* main loop */                                                                     \
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < size.height; y++, dst += 2 * dststep )                              \
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                                   \
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int x, y1, k = top_row;                                                         \
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        worktype *row0, *row1, *row2;                                                   \
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        type *dst1;                                                                     \
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* assign rows pointers */                                                      \
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( y1 = 0; y1 < PU_SZ; y1++ )                                                 \
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            rows[y1] = buffer + k;                                                      \
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            k += buffer_step;                                                           \
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            k &= k < pu_sz ? -1 : 0;                                                    \
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        row0 = rows[0];                                                                 \
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        row1 = rows[1];                                                                 \
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        row2 = rows[2];                                                                 \
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst1 = dst + dststep;                                                           \
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* fill new buffer rows with filtered source (horizontal conv) */               \
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( Cs == 1 )                                                                   \
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( size.width > PU_SZ / 2 )                                                \
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( y1 = fst; y1 < lst; y1++, src += srcstep )                         \
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    worktype *row = rows[y1];                                           \
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* process left & right bounds */                                   \
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row[0] = PU_LT( src[0], src[1] );                                   \
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row[1] = PU_LT_ZI( src[0], src[1] );                                \
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row[size.width * 2 - 2] = PU_RB( src[size.width - 2],               \
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                     src[size.width - 1] );             \
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row[size.width * 2 - 1] = PU_RB_ZI( src[size.width - 1] );          \
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* other points */                                                  \
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( x = 1; x < size.width - 1; x++ )                               \
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[2 * x] = PU_FILTER( src[x - 1], src[x], src[x + 1] );       \
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[2 * x + 1] = PU_FILTER_ZI( src[x], src[x + 1] );            \
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else                /* size.width <= PU_SZ/2 */                             \
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( y1 = fst; y1 < lst; y1++, src += srcstep )                         \
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    worktype *row = rows[y1];                                           \
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    worktype val = src[0];                                              \
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row[0] = PU_SINGULAR( val );                                        \
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    row[1] = PU_SINGULAR_ZI( val );                                     \
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else                    /* Cs == 3 */                                           \
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( y1 = fst; y1 < lst; y1++, src += srcstep )                             \
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                worktype *row = rows[y1];                                               \
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( size.width > PU_SZ / 2 )                                            \
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int c;                                                              \
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( c = 0; c < 3; c++ )                                            \
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        /* process left & right bounds  */                              \
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[c] = PU_LT( src[c], src[3 + c] );                           \
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[3 + c] = PU_LT_ZI( src[c], src[3 + c] );                    \
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[Wn * 2 - 6 + c] = PU_RB( src[Wn - 6 + c], src[Wn - 3 + c]); \
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[Wn * 2 - 3 + c] = PU_RB_ZI( src[Wn - 3 + c] );              \
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* other points */                                                  \
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( x = 3; x < Wn - 3; x += 3 )                                    \
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[2 * x] = PU_FILTER( src[x - 3], src[x], src[x + 3] );       \
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[2 * x + 3] = PU_FILTER_ZI( src[x], src[x + 3] );            \
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[2 * x + 1] = PU_FILTER( src[x - 2], src[x + 1], src[x + 4]);\
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[2 * x + 4] = PU_FILTER_ZI( src[x + 1], src[x + 4] );        \
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[2 * x + 2] = PU_FILTER( src[x - 1], src[x + 2], src[x + 5]);\
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[2 * x + 5] = PU_FILTER_ZI( src[x + 2], src[x + 5] );        \
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else            /* size.width <= PU_SZ/2 */                             \
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int c;                                                              \
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( c = 0; c < 3; c++ )                                            \
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[c] = PU_SINGULAR( src[c] );                                 \
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        row[3 + c] = PU_SINGULAR_ZI( src[c] );                          \
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* second pass. Do vertical conv and write results do destination image */      \
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( y > 0 )                                                                     \
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( y < size.height - PU_SZ / 2 )                                           \
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( x = 0; x < Wdn; x++ )                                              \
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x] = (type)_pu_scale_( PU_FILTER( row0[x], row1[x], row2[x] )); \
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst1[x] = (type)_pu_scale_( PU_FILTER_ZI( row1[x], row2[x] ));      \
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                top_row += buffer_step;                                                 \
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                top_row &= top_row < pu_sz ? -1 : 0;                                    \
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else                /* bottom */                                            \
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( x = 0; x < Wdn; x++ )                                              \
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x] = (type)_pu_scale_( PU_RB( row0[x], row1[x] ));              \
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst1[x] = (type)_pu_scale_( PU_RB_ZI( row1[x] ));                   \
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else                                                                            \
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( size.height > PU_SZ / 2 ) /* top */                                     \
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( x = 0; x < Wdn; x++ )                                              \
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x] = (type)_pu_scale_( PU_LT( row0[x], row1[x] ));              \
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst1[x] = (type)_pu_scale_( PU_LT_ZI( row0[x], row1[x] ));          \
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else                /* size.height <= PU_SZ/2 */                            \
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( x = 0; x < Wdn; x++ )                                              \
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[x] = (type)_pu_scale_( PU_SINGULAR( row0[x] ));                 \
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst1[x] = (type)_pu_scale_( PU_SINGULAR_ZI( row0[x] ));             \
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            fst = PU_SZ - 1;                                                            \
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        lst = y < size.height - PU_SZ/2 - 1 ? PU_SZ : size.height + PU_SZ/2 - y - 1;    \
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                                   \
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                                       \
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_UP_FUNC( 8u, uchar, int, PU_SCALE_INT )
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_UP_FUNC( 16s, short, int, PU_SCALE_INT )
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_UP_FUNC( 16u, ushort, int, PU_SCALE_INT )
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_UP_FUNC( 32f, float, float, PU_SCALE_FLT )
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_UP_FUNC( 64f, double, double, PU_SCALE_FLT )
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrUpG5x5_GetBufSize( int roiWidth, CvDataType dataType,
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         int channels, int *bufSize )
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int bufStep;
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !bufSize )
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *bufSize = 0;
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( roiWidth < 0 )
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( channels != 1 && channels != 3 )
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_UNSUPPORTED_CHANNELS_ERR;
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bufStep = 2*roiWidth*channels;
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dataType == cv64f )
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bufStep *= sizeof(double);
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bufStep *= sizeof(int);
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *bufSize = bufStep * PU_SZ;
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrDownG5x5_GetBufSize( int roiWidth, CvDataType dataType,
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           int channels, int *bufSize )
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int bufStep;
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !bufSize )
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *bufSize = 0;
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( roiWidth < 0 || (roiWidth & 1) != 0 )
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( channels != 1 && channels != 3 )
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_UNSUPPORTED_CHANNELS_ERR;
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bufStep = 2*roiWidth*channels;
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dataType == cv64f )
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bufStep *= sizeof(double);
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bufStep *= sizeof(int);
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *bufSize = bufStep * (PD_SZ + 1);
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Downsampled image border completion
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DEF_PYR_BORDER_FUNC( flavor, arrtype, worktype, _pd_scale_ )                \
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                                              \
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrDownBorder_##flavor##_CnR( const arrtype *src, int src_step, CvSize src_size,     \
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          arrtype *dst, int dst_step, CvSize dst_size, int channels )   \
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                                       \
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int local_alloc = 0;                                                                \
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    worktype *buf = 0, *buf0 = 0;                                                       \
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const arrtype* src2;                                                                \
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    arrtype* dst2;                                                                      \
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int buf_size;                                                                       \
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j;                                                                           \
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int W = src_size.width, H = src_size.height;                                        \
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int Wd = dst_size.width, Hd = dst_size.height;                                      \
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int Wd_, Hd_;                                                                       \
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int Wn = W*channels;                                                                \
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int bufW;                                                                           \
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cols, rows; /* columns and rows to modify */                                    \
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( channels == 1 || channels == 3 );                                           \
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buf_size = MAX(src_size.width,src_size.height) * sizeof(buf[0]) * 2 * channels;     \
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buf_size > (1 << 14) )                                                          \
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                                   \
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buf = (worktype*)cvAlloc( buf_size );                                           \
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !buf )                                                                      \
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return CV_OUTOFMEM_ERR;                                                     \
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                                   \
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else                                                                                \
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                                   \
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buf = (worktype*)cvAlignPtr(alloca( buf_size+8 ), 8);                           \
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        local_alloc = 1;                                                                \
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                                   \
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buf0 = buf;                                                                         \
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_step /= sizeof(src[0]);                                                         \
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_step /= sizeof(dst[0]);                                                         \
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cols = (W & 1) + (Wd*2 > W);                                                        \
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    rows = (H & 1) + (Hd*2 > H);                                                        \
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src2 = src + (H-1)*src_step;                                                        \
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst2 = dst + (Hd - rows)*dst_step;                                                  \
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src += (W - 1)*channels;                                                            \
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst += (Wd - cols)*channels;                                                        \
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* part of row(column) from 1 to Wd_(Hd_) is processed using PD_FILTER macro */     \
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Wd_ = Wd - 1 + (cols == 1 && (W & 1) != 0);                                         \
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Hd_ = Hd - 1 + (rows == 1 && (H & 1) != 0);                                         \
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bufW = channels * cols;                                                             \
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /******************* STAGE 1. ******************/                                   \
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* do horizontal convolution of the 1-2 right columns and write results to buffer */\
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cols > 0 )                                                                      \
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                                   \
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( W <= 2 )                                                                    \
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( Wd == 1 );                                                          \
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < H; i++, src += src_step, buf += channels )                  \
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( channels == 1 )                                                     \
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[0] = PD_SINGULAR( src[1-Wn], src[0] );                          \
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else                                                                    \
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[0] = PD_SINGULAR( src[3-Wn], src[0] );                          \
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[1] = PD_SINGULAR( src[4-Wn], src[1] );                          \
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[2] = PD_SINGULAR( src[5-Wn], src[2] );                          \
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( (W == 3 && Wd == 1) || (W > 3 && !(Wd & 1)) )                          \
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < H; i++, src += src_step, buf += channels )                  \
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( channels == 1 )                                                     \
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[0] = PD_LT( src[-2], src[-1], src[0] );                         \
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else                                                                    \
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[0] = PD_LT( src[-6], src[-3], src[0] );                         \
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[1] = PD_LT( src[-5], src[-2], src[1] );                         \
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[2] = PD_LT( src[-4], src[-1], src[2] );                         \
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( W == 3 )                                                               \
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < H; i++, src += src_step, buf += channels*2 )                \
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( channels == 1 )                                                     \
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[0] = PD_LT( src[-2], src[-1], src[0] );                         \
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[1] = PD_LT( src[0], src[-1], src[-2] );                         \
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else                                                                    \
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[0] = PD_LT( src[-6], src[-3], src[0] );                         \
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[1] = PD_LT( src[-5], src[-2], src[1] );                         \
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[2] = PD_LT( src[-4], src[-1], src[2] );                         \
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[3] = PD_LT( src[0], src[-3], src[-6] );                         \
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[4] = PD_LT( src[1], src[-2], src[-5] );                         \
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[5] = PD_LT( src[2], src[-1], src[-4] );                         \
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( cols == 1 )                                                            \
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < H; i++, src += src_step, buf += channels )                  \
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( channels == 1 )                                                     \
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[0] = PD_FILTER( src[-4], src[-3], src[-2], src[-1], src[0]);    \
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else                                                                    \
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[0] = PD_FILTER( src[-12], src[-9], src[-6], src[-3], src[0]);   \
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[1] = PD_FILTER( src[-11], src[-8], src[-5], src[-2], src[1]);   \
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[2] = PD_FILTER( src[-10], src[-7], src[-4], src[-1], src[2]);   \
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else                                                                            \
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < H; i++, src += src_step, buf += channels*2 )                \
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( channels == 1 )                                                     \
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[0] = PD_FILTER( src[-4], src[-3], src[-2], src[-1], src[0] );   \
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[1] = PD_LT( src[0], src[-1], src[-2] );                         \
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else                                                                    \
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[0] = PD_FILTER( src[-12], src[-9], src[-6], src[-3], src[0] );  \
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[1] = PD_FILTER( src[-11], src[-8], src[-5], src[-2], src[1] );  \
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[2] = PD_FILTER( src[-10], src[-7], src[-4], src[-1], src[2] );  \
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[3] = PD_LT( src[0], src[-3], src[-6] );                         \
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[4] = PD_LT( src[1], src[-2], src[-5] );                         \
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[5] = PD_LT( src[2], src[-1], src[-4] );                         \
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buf = buf0;                                                                     \
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                                   \
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src = src2;                                                                         \
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /******************* STAGE 2. ******************/                                   \
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* do vertical convolution of the pre-processed right columns, */                   \
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* stored in buffer, and write results to the destination */                        \
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* do vertical convolution of the 1-2 bottom rows */                                \
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* and write results to the buffer */                                               \
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( H <= 2 )                                                                        \
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                                   \
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( cols > 0 )                                                                  \
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( Hd == 1 );                                                          \
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < bufW; j++ )                                                 \
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[j] = (arrtype)_pd_scale_( PD_SINGULAR( buf[j], buf[j+(H-1)*bufW] ));\
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( rows > 0 )                                                                  \
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < Wn; j++ )                                                   \
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[j] = PD_SINGULAR( src[j-src_step], src[j] );                        \
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                                   \
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( H == 3 )                                                                   \
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                                   \
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( cols > 0 )                                                                  \
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < bufW; j++ )                                                 \
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[j]= (arrtype)_pd_scale_(PD_LT( buf[j], buf[j+bufW], buf[j+bufW*2]));\
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( Hd == 2 )                                                               \
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst += dst_step;                                                        \
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < bufW; j++ )                                             \
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j] = (arrtype)_pd_scale_( PD_LT( buf[j+bufW*2],                 \
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                  buf[j+bufW], buf[j] ));               \
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( Hd == 1 )                                                                   \
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < Wn; j++ )                                                   \
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[j] = PD_LT( src[j-src_step*2], src[j - src_step], src[j] );         \
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else                                                                            \
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < Wn; j++ )                                                   \
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[j] = PD_LT( src[j-src_step*2], src[j - src_step], src[j] );         \
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[j+Wn] = PD_LT( src[j],src[j-src_step],src[j-src_step*2] );          \
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                                   \
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else                                                                                \
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                                   \
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( cols > 0 )                                                                  \
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* top of the right border */                                               \
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < bufW; j++ )                                                 \
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[j]=(arrtype)_pd_scale_( PD_LT( buf[j], buf[j+bufW], buf[j+bufW*2]));\
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* middle part of the right border */                                       \
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf += bufW*2;                                                              \
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst += dst_step;                                                            \
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 1; i < Hd_; i++, dst += dst_step, buf += bufW*2 )                  \
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < bufW; j++ )                                             \
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j] = (arrtype)_pd_scale_( PD_FILTER( buf[j-bufW*2], buf[j-bufW],\
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                  buf[j], buf[j+bufW], buf[j+bufW*2] ));\
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* bottom of the right border */                                            \
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !(H & 1) )                                                              \
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < bufW; j++ )                                             \
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j] = (arrtype)_pd_scale_( PD_RB( buf[j-bufW*2], buf[j-bufW],    \
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                         buf[j], buf[j+bufW] ));        \
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( rows > 1 )                                                         \
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < bufW; j++ )                                             \
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[j]=(arrtype)_pd_scale_( PD_LT( buf[j-bufW*2],                   \
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                buf[j-bufW], buf[j]));                  \
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf = buf0;                                                                 \
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( rows > 0 )                                                                  \
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !(H & 1) )                                                              \
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < Wn; j++ )                                               \
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[j] = PD_LT( src[j], src[j-src_step], src[j-src_step*2] );       \
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( cols == 1 )                                                        \
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < Wn; j++ )                                               \
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[j] = PD_FILTER( src[j-src_step*4], src[j-src_step*3],           \
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        src[j-src_step*2], src[j-src_step], src[j] );   \
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else                                                                        \
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < Wn; j++ )                                               \
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[j] = PD_FILTER( src[j-src_step*4], src[j-src_step*3],           \
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        src[j-src_step*2], src[j-src_step], src[j] );   \
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf[j+Wn] = PD_LT( src[j], src[j-src_step], src[j-src_step*2] );    \
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                                   \
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /******************* STAGE 3. ******************/                                   \
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* do horizontal convolution of the pre-processed bottom rows,*/                    \
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* stored in buffer, and write results to the destination */                        \
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( rows > 0 )                                                                      \
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                                   \
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst = dst2;                                                                     \
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( W <= 2 )                                                                    \
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( Wd == 1 );                                                          \
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; rows--; dst += dst_step, buf += Wn )                                 \
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( channels == 1 )                                                     \
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[0] = (arrtype)_pd_scale_( PD_SINGULAR( buf[0], buf[Wn-1] ));    \
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else                                                                    \
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[0] = (arrtype)_pd_scale_( PD_SINGULAR( buf[0], buf[Wn-3] ));    \
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[1] = (arrtype)_pd_scale_( PD_SINGULAR( buf[1], buf[Wn-2] ));    \
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[2] = (arrtype)_pd_scale_( PD_SINGULAR( buf[2], buf[Wn-1] ));    \
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( W == 3 )                                                               \
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( Wd == 1 )                                                               \
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( ; rows--; dst += dst_step, buf += Wn )                             \
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( channels == 1 )                                                 \
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[0] = (arrtype)_pd_scale_( PD_LT(buf[0], buf[1], buf[2] ));  \
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else                                                                \
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[0] = (arrtype)_pd_scale_( PD_LT(buf[0], buf[3], buf[6] ));  \
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[1] = (arrtype)_pd_scale_( PD_LT(buf[1], buf[4], buf[7] ));  \
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[2] = (arrtype)_pd_scale_( PD_LT(buf[2], buf[5], buf[8] ));  \
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else                                                                        \
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( ; rows--; dst += dst_step, buf += Wn )                             \
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( channels == 1 )                                                 \
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[0] = (arrtype)_pd_scale_( PD_LT(buf[0], buf[1], buf[2] ));  \
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[1] = (arrtype)_pd_scale_( PD_LT(buf[2], buf[1], buf[0] ));  \
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else                                                                \
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[0] = (arrtype)_pd_scale_( PD_LT(buf[0], buf[3], buf[6] ));  \
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[1] = (arrtype)_pd_scale_( PD_LT(buf[1], buf[4], buf[7] ));  \
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[2] = (arrtype)_pd_scale_( PD_LT(buf[2], buf[5], buf[8] ));  \
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[3] = (arrtype)_pd_scale_( PD_LT(buf[6], buf[3], buf[0] ));  \
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[4] = (arrtype)_pd_scale_( PD_LT(buf[7], buf[4], buf[1] ));  \
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[5] = (arrtype)_pd_scale_( PD_LT(buf[8], buf[5], buf[2] ));  \
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else                                                                            \
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                                               \
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; rows--; dst += dst_step, buf += Wn )                                 \
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                                           \
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( channels == 1 )                                                     \
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* left part of the bottom row */                                   \
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[0] = (arrtype)_pd_scale_( PD_LT( buf[0], buf[1], buf[2] ));     \
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* middle part of the bottom row */                                 \
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( i = 1; i < Wd_; i++ )                                          \
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[i] = (arrtype)_pd_scale_( PD_FILTER(buf[i*2-2], buf[i*2-1], \
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                    buf[i*2],buf[i*2+1], buf[i*2+2] )); \
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* right part of the bottom row */                                  \
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( !(W & 1) )                                                      \
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[i] = (arrtype)_pd_scale_( PD_RB( buf[i*2-2],buf[i*2-1],     \
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                    buf[i*2], buf[i*2+1] ));            \
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else if( cols > 1 )                                                 \
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[i] = (arrtype)_pd_scale_( PD_LT( buf[i*2-2],                \
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                    buf[i*2-1], buf[i*2] ));            \
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else                                                                    \
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {                                                                       \
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* left part of the bottom row */                                   \
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[0] = (arrtype)_pd_scale_( PD_LT( buf[0], buf[3], buf[6] ));     \
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[1] = (arrtype)_pd_scale_( PD_LT( buf[1], buf[4], buf[7] ));     \
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dst[2] = (arrtype)_pd_scale_( PD_LT( buf[2], buf[5], buf[8] ));     \
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* middle part of the bottom row */                                 \
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( i = 3; i < Wd_*3; i++ )                                        \
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[i] = (arrtype)_pd_scale_( PD_FILTER(buf[i*2-6], buf[i*2-3], \
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                      buf[i*2],buf[i*2+3], buf[i*2+6]));\
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* right part of the bottom row */                                  \
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( !(W & 1) )                                                      \
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[i] = (arrtype)_pd_scale_( PD_RB( buf[i*2-6],buf[i*2-3],     \
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                    buf[i*2], buf[i*2+3] ));            \
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[i+1] = (arrtype)_pd_scale_( PD_RB( buf[i*2-5],buf[i*2-2],   \
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                    buf[i*2+1], buf[i*2+4] ));          \
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[i+2] = (arrtype)_pd_scale_( PD_RB( buf[i*2-4],buf[i*2-1],   \
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                    buf[i*2+2], buf[i*2+5] ));          \
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else if( cols > 1 )                                                 \
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {                                                                   \
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[i] = (arrtype)_pd_scale_( PD_LT( buf[i*2-6], buf[i*2-3], buf[i*2] ));   \
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[i+1] = (arrtype)_pd_scale_( PD_LT( buf[i*2-5], buf[i*2-2], buf[i*2+1]));\
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dst[i+2] = (arrtype)_pd_scale_( PD_LT( buf[i*2-4], buf[i*2-1], buf[i*2+2]));\
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }                                                                   \
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }                                                                       \
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                                           \
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                                               \
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                                   \
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !local_alloc )                                                                  \
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buf0 );                                                                \
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                                        \
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                                       \
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DEF_INIT_PYR_TABLE( FUNCNAME )                          \
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvInit##FUNCNAME##Table( CvFuncTable* tab )            \
8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                   \
8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_8U] = (void*)icv##FUNCNAME##_8u_CnR;              \
8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_8S] = 0;                                          \
8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_16S] = (void*)icv##FUNCNAME##_16s_CnR;            \
8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_16U] = (void*)icv##FUNCNAME##_16u_CnR;            \
8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_32F] = (void*)icv##FUNCNAME##_32f_CnR;            \
8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_64F] = (void*)icv##FUNCNAME##_64f_CnR;            \
8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvInitPyrDownBorderTable( CvFuncTable* tab );
8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_INIT_PYR_TABLE( PyrUpG5x5 )
8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_INIT_PYR_TABLE( PyrDownG5x5 )
8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvPyrDownBorderFunc)( const void* src, int srcstep,
8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                     CvSize srcsize, void* dst,
8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                     int dststep, CvSize dstsize, int cn );
8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn////////////////////////////// IPP pyramid functions /////////////////////////////////////
8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrDown_Gauss5x5_8u_C1R_t icvPyrDown_Gauss5x5_8u_C1R_p = 0;
9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrDown_Gauss5x5_8u_C3R_t icvPyrDown_Gauss5x5_8u_C3R_p = 0;
9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrDown_Gauss5x5_32f_C1R_t icvPyrDown_Gauss5x5_32f_C1R_p = 0;
9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrDown_Gauss5x5_32f_C3R_t icvPyrDown_Gauss5x5_32f_C3R_p = 0;
9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrUp_Gauss5x5_8u_C1R_t icvPyrUp_Gauss5x5_8u_C1R_p = 0;
9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrUp_Gauss5x5_8u_C3R_t icvPyrUp_Gauss5x5_8u_C3R_p = 0;
9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrUp_Gauss5x5_32f_C1R_t icvPyrUp_Gauss5x5_32f_C1R_p = 0;
9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrUp_Gauss5x5_32f_C3R_t icvPyrUp_Gauss5x5_32f_C3R_p = 0;
9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrUpGetBufSize_Gauss5x5_t icvPyrUpGetBufSize_Gauss5x5_p = 0;
9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPyrDownGetBufSize_Gauss5x5_t icvPyrDownGetBufSize_Gauss5x5_p = 0;
9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvPyramidFunc)
9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn( const void* src, int srcstep, void* dst,
9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  int dststep, CvSize size, void* buffer, int cn );
9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvPyramidIPPFunc)
9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn( const void* src, int srcstep, void* dst, int dststep, CvSize size, void* buffer );
9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//////////////////////////////////////////////////////////////////////////////////////////
9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*                                 External functions                                     *
9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPyrUp( const void* srcarr, void* dstarr, int _filter )
9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static CvFuncTable pyrup_tab;
9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int inittab = 0;
9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void *buffer = 0;
9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int local_alloc = 0;
9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvPyrUp" );
9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coi1 = 0, coi2 = 0;
9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int buffer_size = 0;
9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int type, depth, cn;
9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, *src = (CvMat*)srcarr;
9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat dststub, *dst = (CvMat*)dstarr;
9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvFilter filter = (CvFilter) _filter;
9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPyramidFunc func;
9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPyramidIPPFunc ipp_func = 0;
9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int use_ipp = 0;
9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size;
9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !inittab )
9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvInitPyrUpG5x5Table( &pyrup_tab );
9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inittab = 1;
9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( src = cvGetMat( src, &srcstub, &coi1 ));
9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 ));
9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi1 != 0 || coi2 != 0 )
9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, "" );
9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( filter != CV_GAUSSIAN_5x5 )
9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "this filter type not supported" );
9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_TYPES_EQ( src, dst ))
9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats, "" );
9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src->cols*2 != dst->cols || src->rows*2 != dst->rows )
9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedSizes, "" );
9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size = cvGetMatSize(src);
9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    type = CV_MAT_TYPE(src->type);
9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    depth = CV_MAT_DEPTH(type);
9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cn = CV_MAT_CN(type);
9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cn != 1 && cn != 3 )
9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "The images must have 1 or 3 channel" );
9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    func = (CvPyramidFunc)pyrup_tab.fn_2d[depth];
9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !func )
9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "" );
9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( icvPyrUpGetBufSize_Gauss5x5_p )
9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ipp_func = type == CV_8UC1 ? icvPyrUp_Gauss5x5_8u_C1R_p :
9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   type == CV_8UC3 ? icvPyrUp_Gauss5x5_8u_C3R_p :
9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   type == CV_32FC1 ? icvPyrUp_Gauss5x5_32f_C1R_p :
9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   type == CV_32FC3 ? icvPyrUp_Gauss5x5_32f_C3R_p : 0;
9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        use_ipp = ipp_func && icvPyrUpGetBufSize_Gauss5x5_p( size.width,
9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvDepthToDataType(type), cn, &buffer_size ) >= 0;
9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !use_ipp )
9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvPyrUpG5x5_GetBufSize( size.width, icvDepthToDataType(type), cn, &buffer_size );
9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buffer_size <= CV_MAX_LOCAL_SIZE )
9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer = cvStackAlloc( buffer_size );
10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        local_alloc = 1;
10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( buffer = cvAlloc( buffer_size ));
10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !use_ipp )
10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        func( src->data.ptr, src->step, dst->data.ptr, dst->step, size, buffer, cn );
10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IPPI_CALL( ipp_func( src->data.ptr, src->step ? src->step : CV_STUB_STEP,
10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst->data.ptr, dst->step ? dst->step : CV_STUB_STEP, size, buffer ));
10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buffer && !local_alloc )
10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buffer );
10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPyrDown( const void* srcarr, void* dstarr, int _filter )
10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static CvFuncTable pyrdown_tab;
10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static CvFuncTable pyrdownborder_tab;
10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int inittab = 0;
10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void *buffer = 0;
10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int local_alloc = 0;
10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvPyrDown" );
10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coi1 = 0, coi2 = 0;
10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int buffer_size = 0;
10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int type, depth, cn;
10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, *src = (CvMat*)srcarr;
10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat dststub, *dst = (CvMat*)dstarr;
10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvFilter filter = (CvFilter) _filter;
10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPyramidFunc func;
10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPyramidIPPFunc ipp_func = 0;
10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int use_ipp = 0;
10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize src_size, src_size2, dst_size;
10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !inittab )
10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvInitPyrDownG5x5Table( &pyrdown_tab );
10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvInitPyrDownBorderTable( &pyrdownborder_tab );
10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inittab = 1;
10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( src = cvGetMat( src, &srcstub, &coi1 ));
10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 ));
10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi1 != 0 || coi2 != 0 )
10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, "" );
10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( filter != CV_GAUSSIAN_5x5 )
10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "this filter type not supported" );
10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_TYPES_EQ( src, dst ))
10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats, "" );
10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_size = cvGetMatSize(src);
10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_size = cvGetMatSize(dst);
10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_size2.width = src_size.width & -2;
10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_size2.height = src_size.height & -2;
10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (unsigned)(dst_size.width - src_size.width/2) > 1 ||
10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (unsigned)(dst_size.height - src_size.height/2) > 1 )
10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedSizes, "" );
10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // current restriction of PyrDownBorder*
10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (src_size.width <= 2 && dst_size.width != 1) ||
10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (src_size.height <= 2 && dst_size.height != 1) )
10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedSizes, "" );
10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*if( src->data.ptr == dst->data.ptr )
10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsInplaceNotSupported, "" );*/
10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    type = CV_MAT_TYPE(src->type);
10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    depth = CV_MAT_DEPTH(type);
10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cn = CV_MAT_CN(type);
10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cn != 1 && cn != 3 )
10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "The images must have 1 or 3 channel" );
10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    func = (CvPyramidFunc)pyrdown_tab.fn_2d[depth];
10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !func )
10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "" );
10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( icvPyrDownGetBufSize_Gauss5x5_p )
10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ipp_func = type == CV_8UC1 ? icvPyrDown_Gauss5x5_8u_C1R_p :
10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   type == CV_8UC3 ? icvPyrDown_Gauss5x5_8u_C3R_p :
10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   type == CV_32FC1 ? icvPyrDown_Gauss5x5_32f_C1R_p :
10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   type == CV_32FC3 ? icvPyrDown_Gauss5x5_32f_C3R_p : 0;
10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        use_ipp = ipp_func && icvPyrDownGetBufSize_Gauss5x5_p( src_size2.width,
10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvDepthToDataType(type), cn, &buffer_size ) >= 0;
11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !use_ipp )
11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvPyrDownG5x5_GetBufSize( src_size2.width,
11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDepthToDataType(type), cn, &buffer_size );
11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buffer_size <= CV_MAX_LOCAL_SIZE )
11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer = cvStackAlloc( buffer_size );
11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        local_alloc = 1;
11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( buffer = cvAlloc( buffer_size ));
11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !use_ipp )
11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        func( src->data.ptr, src->step, dst->data.ptr,
11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              dst->step, src_size2, buffer, cn );
11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IPPI_CALL( ipp_func( src->data.ptr, src->step ? src->step : CV_STUB_STEP,
11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst->data.ptr, dst->step ? dst->step : CV_STUB_STEP, src_size2, buffer ));
11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src_size.width != dst_size.width*2 || src_size.height != dst_size.height*2 )
11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPyrDownBorderFunc border_func = (CvPyrDownBorderFunc)
11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            pyrdownborder_tab.fn_2d[CV_MAT_DEPTH(type)];
11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !border_func )
11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnsupportedFormat, "" );
11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IPPI_CALL( border_func( src->data.ptr, src->step, src_size,
11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                dst->data.ptr, dst->step, dst_size, CV_MAT_CN(type) ));
11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buffer && !local_alloc )
11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buffer );
11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvReleasePyramid( CvMat*** _pyramid, int extra_layers )
11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvReleasePyramid" );
11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat** pyramid;
11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !_pyramid )
11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pyramid = *_pyramid;
11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( pyramid )
11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= extra_layers; i++ )
11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvReleaseMat( &pyramid[i] );
11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( _pyramid );
11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvMat**
11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCreatePyramid( const CvArr* srcarr, int extra_layers, double rate,
11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                 const CvSize* layer_sizes, CvArr* bufarr,
11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                 int calc, int filter )
11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat** pyramid = 0;
11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const float eps = 0.1f;
11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvCreatePyramid" );
11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, elem_size, layer_step;
11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *src;
11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size, layer_size;
11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar* ptr = 0;
11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( src = cvGetMat( srcarr, &stub ));
11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( extra_layers < 0 )
11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "The number of extra layers must be non negative" );
11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    elem_size = CV_ELEM_SIZE(src->type);
11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size = cvGetMatSize(src);
11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( bufarr )
11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvMat bstub, *buf;
11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int bufsize = 0;
11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( buf = cvGetMat( bufarr, &bstub ));
11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bufsize = buf->rows*buf->cols*CV_ELEM_SIZE(buf->type);
11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        layer_size = size;
12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 1; i <= extra_layers; i++ )
12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !layer_sizes )
12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                layer_size.width = cvRound(layer_size.width*rate+eps);
12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                layer_size.height = cvRound(layer_size.height*rate+eps);
12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                layer_size = layer_sizes[i-1];
12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            layer_step = layer_size.width*elem_size;
12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            bufsize -= layer_step*layer_size.height;
12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( bufsize < 0 )
12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsOutOfRange, "The buffer is too small to fit the pyramid" );
12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ptr = buf->data.ptr;
12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( pyramid = (CvMat**)cvAlloc( (extra_layers+1)*sizeof(pyramid[0]) ));
12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( pyramid, 0, (extra_layers+1)*sizeof(pyramid[0]) );
12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pyramid[0] = cvCreateMatHeader( size.height, size.width, src->type );
12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvSetData( pyramid[0], src->data.ptr, src->step );
12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    layer_size = size;
12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 1; i <= extra_layers; i++ )
12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !layer_sizes )
12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            layer_size.width = cvRound(layer_size.width*rate + eps);
12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            layer_size.height = cvRound(layer_size.height*rate + eps);
12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            layer_size = layer_sizes[i];
12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( bufarr )
12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pyramid[i] = cvCreateMatHeader( layer_size.height, layer_size.width, src->type );
12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            layer_step = layer_size.width*elem_size;
12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvSetData( pyramid[i], ptr, layer_step );
12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += layer_step*layer_size.height;
12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pyramid[i] = cvCreateMat( layer_size.height, layer_size.width, src->type );
12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( calc )
12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvPyrDown( pyramid[i-1], pyramid[i], filter );
12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            //cvResize( pyramid[i-1], pyramid[i], CV_INTER_LINEAR );
12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cvGetErrStatus() < 0 )
12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleasePyramid( &pyramid, extra_layers );
12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return pyramid;
12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* MSVC .NET 2003 spends a long time building this, thus, as the code
12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   is not performance-critical, we turn off the optimization here */
12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined _MSC_VER && _MSC_VER > 1300 && !defined CV_ICC
12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#pragma optimize("", off)
12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_BORDER_FUNC( 8u, uchar, int, PD_SCALE_INT )
12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_BORDER_FUNC( 16u, ushort, int, PD_SCALE_INT )
12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_BORDER_FUNC( 16s, short, int, PD_SCALE_INT )
12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_BORDER_FUNC( 32f, float, float, PD_SCALE_FLT )
12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_PYR_BORDER_FUNC( 64f, double, double, PD_SCALE_FLT )
12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DEF_INIT_PYR_BORDER_TABLE( FUNCNAME )                   \
12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvInit##FUNCNAME##Table( CvFuncTable* tab )            \
12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                   \
12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_8U] = (void*)icv##FUNCNAME##_8u_CnR;              \
12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_8S] = 0;                                          \
12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_16U] = (void*)icv##FUNCNAME##_16u_CnR;            \
12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_16S] = (void*)icv##FUNCNAME##_16s_CnR;            \
12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_32F] = (void*)icv##FUNCNAME##_32f_CnR;            \
12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab->fn_2d[CV_64F] = (void*)icv##FUNCNAME##_64f_CnR;            \
12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DEF_INIT_PYR_BORDER_TABLE( PyrDownBorder )
12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
1285