/*******************************************************************************
* Copyright 2015-2020 Intel Corporation.
*
* This software and the related documents are Intel copyrighted  materials,  and
* your use of  them is  governed by the  express license  under which  they were
* provided to you (License).  Unless the License provides otherwise, you may not
* use, modify, copy, publish, distribute,  disclose or transmit this software or
* the related documents without Intel's prior written permission.
*
* This software and the related documents  are provided as  is,  with no express
* or implied  warranties,  other  than those  that are  expressly stated  in the
* License.
*******************************************************************************/

/*
//   Description:
//       Intel(R) IPP RESIZE Transform Functions with Antialiasing
//
//   Content:
//       ippiResizeAntialiasingLinearInit_LT
//       ippiResizeAntialiasingCubicInit_LT
//       ippiResizeAntialiasingLanczosInit_LT
//       ippiResizeAntialiasing_8u_C1R_LT
//       ippiResizeAntialiasing_8u_C3R_LT
//       ippiResizeAntialiasing_8u_C4R_LT
//       ippiResizeAntialiasing_16u_C1R_LT
//       ippiResizeAntialiasing_16u_C3R_LT
//       ippiResizeAntialiasing_16u_C4R_LT
//       ippiResizeAntialiasing_16s_C1R_LT
//       ippiResizeAntialiasing_16s_C3R_LT
//       ippiResizeAntialiasing_16s_C4R_LT
//       ippiResizeAntialiasing_32f_C1R_LT
//       ippiResizeAntialiasing_32f_C3R_LT
//       ippiResizeAntialiasing_32f_C4R_LT
//
*/

#include "piresizenaa_tl.h"

static const IppiSizeL RESIZE_LINEAR_MIN_TILE_SIZE  = {8,8};
static const IppiSizeL RESIZE_CUBIC_MIN_TILE_SIZE   = {16,16};
static const IppiSizeL RESIZE_LANCZOS_MIN_TILE_SIZE = {24,24};

/* /////////////////////////////////////////////////////////////////////////////
//  Name:               ippiResizeNearestAntialiasingInit_LT
//                      ippiResizeLinearAntialiasingInit_LT
//                      ippiResizeCubicAntialiasingInit_LT
//
//  Purpose:            Initializes the Spec structure for the Resize transform
//                      with antialiasing by different interpolation methods
//
//  Parameters:
//    srcSize           Size of the input image (in pixels)
//    dstSize           Size of the output image (in pixels)
//    valueB            The first parameter (B) for specifying Cubic filters
//    valueC            The second parameter (C) for specifying Cubic filters
//    numLobes          The parameter for specifying Lanczos (2 or 3) or Hahn (3 or 4) filters
//    pInitBuf          Pointer to the temporal buffer for several filter initialization
//    pSpec             Pointer to the Spec structure for resize filter
//
//  Return Values:
//    ippStsNoErr               Indicates no error
//    ippStsNullPtrErr          Indicates an error if one of the specified pointers is NULL
//    ippStsNoOperation         Indicates a warning if width or height of any image is zero
//    ippStsSizeErr             Indicates an error if width or height of the source image is negative
//    ippStsExceededSizeErr     Indicates an error if one of width or height of the destination image or
//                              the source image with borders exceeds 536870911 (0x1FFFFFFF)
//    ippStsDataTypeErr         Indicates an error when dataType has an illegal value.
//    ippStsNumChannelsErr      Indicates an error if numChannels has illegal value
//    ippStsNotSupportedModeErr Indicates an error if the requested mode is not supported.
//
//  Notes/References:
//    1. The equation shows the family of cubic filters:
//           ((12-9B-6C)*|x|^3 + (-18+12B+6C)*|x|^2                  + (6-2B)  ) / 6   for |x| < 1
//    K(x) = ((   -B-6C)*|x|^3 + (    6B+30C)*|x|^2 + (-12B-48C)*|x| + (8B+24C)) / 6   for 1 <= |x| < 2
//           0   elsewhere
//    Some values of (B,C) correspond to known cubic splines: Catmull-Rom (B=0,C=0.5), B-Spline (B=1,C=0) and other.
//      Mitchell, Don P.; Netravali, Arun N. (Aug. 1988). "Reconstruction filters in computer graphics"
//      http://www.mentallandscape.com/Papers_siggraph88.pdf
//
//    2. Hahn filter does not supported now.
*/

IPPFUN (IppStatus, ippiResizeAntialiasingLinearInit_LT, (IppiSizeL srcSize, IppiSizeL dstSize, IppDataType dataType, Ipp32u numChannels, IppiResizeSpec_LT* pSpec, Ipp8u* pInitBuf))
{
    IppStatus status = ippStsNoErr;
    ResizeInfo *pResizeInfo = 0;

    if (pSpec == 0 || pInitBuf == 0) return ippStsNullPtrErr;
    if (numChannels != 1 && numChannels != 3 && numChannels != 4) return ippStsNumChannelsErr;

    pResizeInfo = (ResizeInfo*)pSpec;
    pSpec = (IppiResizeSpec_LT*)((Ipp8u*)pSpec + sizeof(ResizeInfo));

    status = ippiResizeAntialiasingLinearInit_L(srcSize, dstSize, dataType, (IppiResizeSpec*)pSpec, pInitBuf);

    if (status >= 0 && status != ippStsNoOperation)
    {
        IppiSizeL tileSize;
        IppSizeL srcPixNumber = srcSize.width * srcSize.height;
        IppSizeL dstPixNumber = dstSize.width * dstSize.height;
        tileSize.width  = dstSize.width;
        tileSize.height = dstSize.height;
        if ( srcPixNumber >= RESIZE_TILE_THRESHOLD || dstPixNumber >= RESIZE_TILE_THRESHOLD )
        {
            owniGetTileSizeSimple_LT(dstSize, RESIZE_LINEAR_MIN_PIX_NUMBER / numChannels, RESIZE_LINEAR_MIN_TILE_SIZE, &tileSize);
        }

        ippiSplitToTiles_LT( dstSize, tileSize, &pResizeInfo->split, &pResizeInfo->tileSize, &pResizeInfo->lastTile );

        pResizeInfo->dataType    = dataType;
        pResizeInfo->srcSize     = srcSize;
        pResizeInfo->dstSize     = dstSize;
        pResizeInfo->numChannels = numChannels;
        pResizeInfo->interp      = ippLinear;

        status = ippiResizeGetBorderSize_L((IppiResizeSpec*)pSpec, &pResizeInfo->borderSize);
    }

    return status;
}

IPPFUN (IppStatus, ippiResizeAntialiasingCubicInit_LT, (IppiSizeL srcSize, IppiSizeL dstSize, IppDataType dataType, Ipp32u numChannels, Ipp32f valueB, Ipp32f valueC, IppiResizeSpec_LT* pSpec, Ipp8u* pInitBuf))
{
    IppStatus status = ippStsNoErr;
    ResizeInfo *pResizeInfo = 0;

    if (pSpec == 0 || pInitBuf == 0) return ippStsNullPtrErr;
    if (numChannels != 1 && numChannels != 3 && numChannels != 4) return ippStsNumChannelsErr;

    pResizeInfo = (ResizeInfo*)pSpec;
    pSpec = (IppiResizeSpec_LT*)((Ipp8u*)pSpec + sizeof(ResizeInfo));

    status = ippiResizeAntialiasingCubicInit_L(srcSize, dstSize, dataType, valueB, valueC, (IppiResizeSpec*)pSpec, pInitBuf);

    if (status >= 0 && status != ippStsNoOperation)
    {
        IppiSizeL tileSize;
        IppSizeL srcPixNumber = srcSize.width * srcSize.height;
        IppSizeL dstPixNumber = dstSize.width * dstSize.height;
        tileSize.width  = dstSize.width;
        tileSize.height = dstSize.height;
        if ( srcPixNumber >= RESIZE_TILE_THRESHOLD || dstPixNumber >= RESIZE_TILE_THRESHOLD )
        {
            owniGetTileSizeSimple_LT(dstSize, RESIZE_CUBIC_MIN_PIX_NUMBER / numChannels, RESIZE_CUBIC_MIN_TILE_SIZE, &tileSize);
        }

        ippiSplitToTiles_LT( dstSize, tileSize, &pResizeInfo->split, &pResizeInfo->tileSize, &pResizeInfo->lastTile );

        pResizeInfo->dataType    = dataType;
        pResizeInfo->srcSize     = srcSize;
        pResizeInfo->dstSize     = dstSize;
        pResizeInfo->numChannels = numChannels;
        pResizeInfo->interp      = ippCubic;

        status = ippiResizeGetBorderSize_L((IppiResizeSpec*)pSpec, &pResizeInfo->borderSize);
    }

    return status;
}

IPPFUN (IppStatus, ippiResizeAntialiasingLanczosInit_LT, (IppiSizeL srcSize, IppiSizeL dstSize, IppDataType dataType, Ipp32u numChannels, Ipp32u numLobes, IppiResizeSpec_LT* pSpec, Ipp8u* pInitBuf))
{
    IppStatus status = ippStsNoErr;
    ResizeInfo *pResizeInfo = 0;

    if (pSpec == 0 || pInitBuf == 0) return ippStsNullPtrErr;
    if (numChannels != 1 && numChannels != 3 && numChannels != 4) return ippStsNumChannelsErr;

    pResizeInfo = (ResizeInfo*)pSpec;
    pSpec = (IppiResizeSpec_LT*)((Ipp8u*)pSpec + sizeof(ResizeInfo));

    status = ippiResizeAntialiasingLanczosInit_L(srcSize, dstSize, dataType, numLobes, (IppiResizeSpec*)pSpec, pInitBuf);

    if (status >= 0 && status != ippStsNoOperation)
    {
        IppiSizeL tileSize;
        IppSizeL srcPixNumber = srcSize.width * srcSize.height;
        IppSizeL dstPixNumber = dstSize.width * dstSize.height;
        tileSize.width  = dstSize.width;
        tileSize.height = dstSize.height;
        if ( srcPixNumber >= RESIZE_TILE_THRESHOLD || dstPixNumber >= RESIZE_TILE_THRESHOLD )
        {
            owniGetTileSizeSimple_LT(dstSize, RESIZE_LANCZOS_MIN_PIX_NUMBER / numChannels, RESIZE_LANCZOS_MIN_TILE_SIZE, &tileSize);
        }

        ippiSplitToTiles_LT( dstSize, tileSize, &pResizeInfo->split, &pResizeInfo->tileSize, &pResizeInfo->lastTile );

        pResizeInfo->dataType    = dataType;
        pResizeInfo->srcSize     = srcSize;
        pResizeInfo->dstSize     = dstSize;
        pResizeInfo->numChannels = numChannels;
        pResizeInfo->interp      = ippLanczos;

        status = ippiResizeGetBorderSize_L((IppiResizeSpec*)pSpec, &pResizeInfo->borderSize);
    }

    return status;
}

/* /////////////////////////////////////////////////////////////////////////////
//  Name:               ippiResizeAntialiasing
//
//  Purpose:            Changes an image size by different interpolation methods with antialiasing technique
//
//  Parameters:
//    pSrc              Pointer to the source image
//    srcStep           Distance (in bytes) between of consecutive lines in the source image
//    pDst              Pointer to the destination image
//    dstStep           Distance (in bytes) between of consecutive lines in the destination image
//    border            Type of the border
//    borderValue       Pointer to the constant value(s) if border type equals ippBorderConstant
//    pSpec             Pointer to the Spec structure for resize filter
//    pBuffer           Pointer to the work buffer
//
//  Return Values:
//    ippStsNoErr               Indicates no error
//    ippStsNullPtrErr          Indicates an error if one of the specified pointers is NULL
//    ippStsBorderErr           Indicates an error if border type has an illegal value
//    ippStsContextMatchErr     Indicates an error if pointer to an invalid pSpec structure is passed
//    ippStsNotSupportedModeErr Indicates an error if requested mode is currently not supported
//    ippStsStepErr             Indicates an error if the step value is not data type multiple
//
//  Notes:
//    1. Supported border types are ippBorderInMem and ippBorderRepl.
//    2. Hahn filter does not supported now.
*/

/* 8u Antialiasing Resize functions */

IppStatus ippiResizeAntialiasing_8u_C1R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_8u_LT_Str * ts = (ippiResize_8u_LT_Str *)arg;
    const Ipp8u* pSrc = (const Ipp8u*)ts->pSrc; 
    IppSizeL srcStep = ts->srcStep; 
    Ipp8u* pDst = (Ipp8u*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp8u* pBorderValue = (const Ipp8u *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp8u *pSrcRoi = 0;
    Ipp8u       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_8u(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_8u(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_8u_C1R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_8u_C1R_LT, (const Ipp8u* pSrc, IppSizeL srcStep, Ipp8u* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp8u* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 1;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_8u_C1R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                               pBorderValue, pResizeSpec, pBuffer);
    }

    {
        ippiResize_8u_LT_Str ts;
        resizeThreadingStructureEncode_8u((Ipp8u*)pSrc, (IppSizeL)srcStep, (Ipp8u*)pDst, (IppSizeL)dstStep, border, (Ipp8u *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_8u_C1R_LT_Fun);
    }

    return status;
}

IppStatus ippiResizeAntialiasing_8u_C3R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_8u_LT_Str * ts = (ippiResize_8u_LT_Str *)arg;
    const Ipp8u* pSrc = (const Ipp8u*)ts->pSrc; 
    IppSizeL srcStep = ts->srcStep; 
    Ipp8u* pDst = (Ipp8u*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp8u* pBorderValue = (const Ipp8u *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp8u *pSrcRoi = 0;
    Ipp8u       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_8u(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_8u(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_8u_C3R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_8u_C3R_LT, (const Ipp8u* pSrc, IppSizeL srcStep, Ipp8u* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp8u* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 3;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_8u_C3R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                             pBorderValue, pResizeSpec, pBuffer);
    }

    {
        ippiResize_8u_LT_Str ts;
        resizeThreadingStructureEncode_8u((Ipp8u*)pSrc, (IppSizeL)srcStep, (Ipp8u*)pDst, (IppSizeL)dstStep, border, (Ipp8u *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_8u_C3R_LT_Fun);
    }

    return status;
}

IppStatus ippiResizeAntialiasing_8u_C4R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_8u_LT_Str * ts = (ippiResize_8u_LT_Str *)arg;
    const Ipp8u* pSrc = (const Ipp8u*)ts->pSrc; 
    IppSizeL srcStep = ts->srcStep; 
    Ipp8u* pDst = (Ipp8u*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp8u* pBorderValue = (const Ipp8u *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp8u *pSrcRoi = 0;
    Ipp8u       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_8u(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_8u(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_8u_C4R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_8u_C4R_LT, (const Ipp8u* pSrc, IppSizeL srcStep, Ipp8u* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp8u* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 4;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_8u_C4R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                             pBorderValue, pResizeSpec, pBuffer);
    }
    
    {
        ippiResize_8u_LT_Str ts;
        resizeThreadingStructureEncode_8u((Ipp8u*)pSrc, (IppSizeL)srcStep, (Ipp8u*)pDst, (IppSizeL)dstStep, border, (Ipp8u *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_8u_C4R_LT_Fun);
    }

    return status;
}

/* 16u Antialiasing Resize functions */

IppStatus ippiResizeAntialiasing_16u_C1R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_16u_LT_Str * ts = (ippiResize_16u_LT_Str *)arg;
    const Ipp16u* pSrc = (const Ipp16u*)ts->pSrc; 
    IppSizeL srcStep = ts->srcStep; 
    Ipp16u* pDst = (Ipp16u*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp16u* pBorderValue = (const Ipp16u *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp16u *pSrcRoi = 0;
    Ipp16u       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_16u(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_16u(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_16u_C1R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_16u_C1R_LT, (const Ipp16u* pSrc, IppSizeL srcStep, Ipp16u* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp16u* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 1;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_16u_C1R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                             pBorderValue, pResizeSpec, pBuffer);
    }
    
    {
        ippiResize_16u_LT_Str ts;
        resizeThreadingStructureEncode_16u((Ipp16u*)pSrc, (IppSizeL)srcStep, (Ipp16u*)pDst, (IppSizeL)dstStep, border, (Ipp16u *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_16u_C1R_LT_Fun);
    }

    return status;
}

IppStatus ippiResizeAntialiasing_16u_C3R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_16u_LT_Str * ts = (ippiResize_16u_LT_Str *)arg;
    const Ipp16u* pSrc = (const Ipp16u*)ts->pSrc; 
    IppSizeL srcStep = ts->srcStep; 
    Ipp16u* pDst = (Ipp16u*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp16u* pBorderValue = (const Ipp16u *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp16u *pSrcRoi = 0;
    Ipp16u       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_16u(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_16u(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_16u_C3R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_16u_C3R_LT, (const Ipp16u* pSrc, IppSizeL srcStep, Ipp16u* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp16u* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 3;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_16u_C3R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                             pBorderValue, pResizeSpec, pBuffer);
    }
    
    {
        ippiResize_16u_LT_Str ts;
        resizeThreadingStructureEncode_16u((Ipp16u*)pSrc, (IppSizeL)srcStep, (Ipp16u*)pDst, (IppSizeL)dstStep, border, (Ipp16u *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_16u_C3R_LT_Fun);
    }

    return status;
}

IppStatus ippiResizeAntialiasing_16u_C4R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_16u_LT_Str * ts = (ippiResize_16u_LT_Str *)arg;
    const Ipp16u* pSrc = (const Ipp16u*)ts->pSrc; 
    IppSizeL srcStep = ts->srcStep; 
    Ipp16u* pDst = (Ipp16u*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp16u* pBorderValue = (const Ipp16u *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp16u *pSrcRoi = 0;
    Ipp16u       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_16u(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_16u(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_16u_C4R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_16u_C4R_LT, (const Ipp16u* pSrc, IppSizeL srcStep, Ipp16u* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp16u* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 4;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_16u_C4R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                             pBorderValue, pResizeSpec, pBuffer);
    }
    
    {
        ippiResize_16u_LT_Str ts;
        resizeThreadingStructureEncode_16u((Ipp16u*)pSrc, (IppSizeL)srcStep, (Ipp16u*)pDst, (IppSizeL)dstStep, border, (Ipp16u *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_16u_C4R_LT_Fun);
    }

    return status;
}

/* 16s Antialiasing Resize functions */

IppStatus ippiResizeAntialiasing_16s_C1R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_16s_LT_Str * ts = (ippiResize_16s_LT_Str *)arg;
    const Ipp16s* pSrc = (const Ipp16s*)ts->pSrc; 
    IppSizeL srcStep = ts->srcStep; 
    Ipp16s* pDst = (Ipp16s*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp16s* pBorderValue = (const Ipp16s *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp16s *pSrcRoi = 0;
    Ipp16s       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_16s(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_16s(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_16s_C1R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_16s_C1R_LT, (const Ipp16s* pSrc, IppSizeL srcStep, Ipp16s* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp16s* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 1;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_16s_C1R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                             pBorderValue, pResizeSpec, pBuffer);
    }

    {
        ippiResize_16s_LT_Str ts;
        resizeThreadingStructureEncode_16s((Ipp16s*)pSrc, (IppSizeL)srcStep, (Ipp16s*)pDst, (IppSizeL)dstStep, border, (Ipp16s *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_16s_C1R_LT_Fun);
    }

    return status;
}

IppStatus ippiResizeAntialiasing_16s_C3R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_16s_LT_Str * ts = (ippiResize_16s_LT_Str *)arg;
    const Ipp16s* pSrc = (const Ipp16s*)ts->pSrc; 
    IppSizeL srcStep = ts->srcStep; 
    Ipp16s* pDst = (Ipp16s*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp16s* pBorderValue = (const Ipp16s *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp16s *pSrcRoi = 0;
    Ipp16s       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_16s(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_16s(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_16s_C3R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_16s_C3R_LT, (const Ipp16s* pSrc, IppSizeL srcStep, Ipp16s* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp16s* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 3;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_16s_C3R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                             pBorderValue, pResizeSpec, pBuffer);
    }
    
    {
        ippiResize_16s_LT_Str ts;
        resizeThreadingStructureEncode_16s((Ipp16s*)pSrc, (IppSizeL)srcStep, (Ipp16s*)pDst, (IppSizeL)dstStep, border, (Ipp16s *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_16s_C3R_LT_Fun);
    }

    return status;
}

IppStatus ippiResizeAntialiasing_16s_C4R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_16s_LT_Str * ts = (ippiResize_16s_LT_Str *)arg;
    const Ipp16s* pSrc = (const Ipp16s*)ts->pSrc; 
    IppSizeL srcStep = ts->srcStep; 
    Ipp16s* pDst = (Ipp16s*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp16s* pBorderValue = (const Ipp16s *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp16s *pSrcRoi = 0;
    Ipp16s       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_16s(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_16s(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_16s_C4R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_16s_C4R_LT, (const Ipp16s* pSrc, IppSizeL srcStep, Ipp16s* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp16s* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 4;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_16s_C4R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                             pBorderValue, pResizeSpec, pBuffer);
    }

    {
        ippiResize_16s_LT_Str ts;
        resizeThreadingStructureEncode_16s((Ipp16s*)pSrc, (IppSizeL)srcStep, (Ipp16s*)pDst, (IppSizeL)dstStep, border, (Ipp16s *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_16s_C4R_LT_Fun);
    }

    return status;
}

/* 32f Antialiasing Resize functions */

IppStatus ippiResizeAntialiasing_32f_C1R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_32f_LT_Str * ts = (ippiResize_32f_LT_Str *)arg;
    const Ipp32f* pSrc = (const Ipp32f*)ts->pSrc; 
    IppSizeL srcStep = ts->srcStep; 
    Ipp32f* pDst = (Ipp32f*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp32f* pBorderValue = (const Ipp32f *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp32f *pSrcRoi = 0;
    Ipp32f       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_32f(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_32f(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_32f_C1R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_32f_C1R_LT, (const Ipp32f* pSrc, IppSizeL srcStep, Ipp32f* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp32f* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 1;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_32f_C1R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                             pBorderValue, pResizeSpec, pBuffer);
    }

    {
        ippiResize_32f_LT_Str ts;
        resizeThreadingStructureEncode_32f((Ipp32f*)pSrc, (IppSizeL)srcStep, (Ipp32f*)pDst, (IppSizeL)dstStep, border, (Ipp32f *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_32f_C1R_LT_Fun);
    }

    return status;
}

IppStatus ippiResizeAntialiasing_32f_C3R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_32f_LT_Str * ts = (ippiResize_32f_LT_Str *)arg;
    const Ipp32f* pSrc = (const Ipp32f*)ts->pSrc;
    IppSizeL srcStep = ts->srcStep; 
    Ipp32f* pDst = (Ipp32f*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp32f* pBorderValue = (const Ipp32f *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp32f *pSrcRoi = 0;
    Ipp32f       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_32f(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_32f(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_32f_C3R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_32f_C3R_LT, (const Ipp32f* pSrc, IppSizeL srcStep, Ipp32f* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp32f* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 3;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_32f_C3R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                             pBorderValue, pResizeSpec, pBuffer);
    }

    {
        ippiResize_32f_LT_Str ts;
        resizeThreadingStructureEncode_32f((Ipp32f*)pSrc, (IppSizeL)srcStep, (Ipp32f*)pDst, (IppSizeL)dstStep, border, (Ipp32f *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_32f_C3R_LT_Fun);
    }

    return status;
}

IppStatus ippiResizeAntialiasing_32f_C4R_LT_Fun (IppSizeL i, void * arg)
{
    ippiResize_32f_LT_Str * ts = (ippiResize_32f_LT_Str *)arg;
    const Ipp32f* pSrc = (const Ipp32f*)ts->pSrc;
    IppSizeL srcStep = ts->srcStep; 
    Ipp32f* pDst = (Ipp32f*)ts->pDst;
    IppSizeL dstStep = ts->dstStep;
    IppiBorderType border = ts->border;
    const Ipp32f* pBorderValue = (const Ipp32f *)ts->pBorderValue;
    Ipp8u* pBuffer = ts->pBuffer; 
    Ipp32u numChannels = ts->numChannels; 
    IppSizeL tileBufferSize = ts->tileBufferSize; 
    IppiResizeSpec *pResizeSpec = ts->pResizeSpec; 
    ResizeInfo *pResizeInfo = ts->pResizeInfo;
    int threadIdx = 0;

    IppStatus threadStatus;

    /* Pointers to the source and destination tiles */
    const Ipp32f *pSrcRoi = 0;
    Ipp32f       *pDstRoi = 0;
    /* Source and destination tile ROI parameters */
    IppiPointL   roiOffset  = {0}, srcRoiOffset = {0};
    IppiSizeL      roiSize    = {0};

    owniResizeGetTileByIndex((int)i, pResizeInfo->split, pResizeInfo->tileSize, pResizeInfo->lastTile, &roiOffset, &roiSize);
    threadStatus = ippiResizeGetSrcOffset_L(pResizeSpec, roiOffset, &srcRoiOffset);

    /* Compute pointers to ROIs */
    pSrcRoi = owniGetImagePointer_32f(pSrc, srcStep, srcRoiOffset.x, srcRoiOffset.y, numChannels);
    pDstRoi = owniGetImagePointer_32f(pDst, dstStep, roiOffset.x,    roiOffset.y,    numChannels);

    if (threadStatus >= 0)
    {
        /* Pointer to tile work buffer */
        ippGetThreadIdx_LT(&threadIdx);
        Ipp8u *pTileBuffer = pBuffer + tileBufferSize * threadIdx;

        /* Intel(R) IPP function call */
        threadStatus = ippiResizeAntialiasing_32f_C4R_L(pSrcRoi, srcStep, pDstRoi, dstStep, roiOffset, roiSize, border, pBorderValue, pResizeSpec, pTileBuffer);
    }
    return threadStatus;
}

IPPFUN (IppStatus, ippiResizeAntialiasing_32f_C4R_LT, (const Ipp32f* pSrc, IppSizeL srcStep, Ipp32f* pDst, IppSizeL dstStep, IppiBorderType border, const Ipp32f* pBorderValue, const IppiResizeSpec_LT* pSpec, Ipp8u* pBuffer))
{
    Ipp32u numChannels = 4;
    IppStatus status = ippStsNoErr;
    IppSizeL numTiles = 0;
    IppSizeL tileBufferSize = 0;
    IppiResizeSpec *pResizeSpec = (IppiResizeSpec*)((Ipp8u*)pSpec + sizeof(ResizeInfo)); /* Resize Spec structure for Intel(R) IPP function call */
    ResizeInfo *pResizeInfo = (ResizeInfo*)pSpec;                 /* Resize Info structure */

    /* Bad argument checking */
    if (pSrc == 0 || pDst == 0 || pSpec == 0 || pBuffer == 0) return ippStsNullPtrErr;
    if (pResizeInfo->numChannels < numChannels)              return ippStsContextMatchErr;

    numTiles = pResizeInfo->split.x * pResizeInfo->split.y;

    /* Compute work buffer for one thread */
    status = owniResizeGetTileBufferSize(pSpec, numChannels, &tileBufferSize);
    if (status < 0) return status;

    if (numTiles == 1)
    {
        /* Source and destination ROI parameters */
        IppiPointL roiOffset  = {0};
        /* Intel(R) IPP function call */
        return ippiResizeAntialiasing_32f_C4R_L(pSrc, srcStep, pDst, dstStep, roiOffset, pResizeInfo->tileSize, border,
                                             pBorderValue, pResizeSpec, pBuffer);
    }

    {
        ippiResize_32f_LT_Str ts;
        resizeThreadingStructureEncode_32f((Ipp32f*)pSrc, (IppSizeL)srcStep, (Ipp32f*)pDst, (IppSizeL)dstStep, border, (Ipp32f *)pBorderValue, pBuffer, numChannels, tileBufferSize, pResizeSpec, pResizeInfo, &ts);
        status = ippParallelFor_LT(numTiles, (void*)&ts, ippiResizeAntialiasing_32f_C4R_LT_Fun);
    }

    return status;
}
