/*******************************************************************************
* Copyright 2018-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.
*
* License:
* http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr
* eement/
*******************************************************************************/

#ifndef PIFSOBEL_T_H__
#define PIFSOBEL_T_H__

#include "ippcore.h"
#include "owndefs_tl.h"
#include "ippcore_tl.h"
#include "ipps.h"
#include "ippi.h"
#include "ippdefs.h"
#include "ownisplit_t.h"
#include "owni_tl.h"

#ifdef USE_OMP
#include <omp.h>
#endif

#define ALIGNED_SIZE(p) IPP_ALIGNED_SIZE(p,32)
#define ALIGNED_PTR(p)  IPP_ALIGNED_PTR(p,32)

#define SLICE_MIN_HEIGHT(maskId) (maskId == ippMskSize3x3 ? 3+1 : 5+1)

extern void ownGetSobelSliceSize(IppiSize roiSize, IppiMaskSize maskId, IppiSize* pSliceSize, IppiSize* lastSliceSize,
                                 IppiPoint* splitImage);

typedef struct _ippiFilterSobelHV_T_Str
{
    const Ipp8u *pSrc;
    int srcStep;
    Ipp16s *pDst;
    int dstStep;
    IppiMaskSize maskId;
    IppiBorderType borderType;
    Ipp8u borderValue;
    Ipp8u* pBuffer;
    IppiPoint splitImage;
    IppiSize sliceSize;
    IppiSize lastSliceSize;
    int sliceBufferSize;
} ippiFilterSobelHV_T_Str;

static void filterSobelHVThreadingStructureEncode_8u16s(
    const Ipp8u* pSrc,
    int srcStep,
    Ipp16s* pDst,
    int dstStep,
    IppiMaskSize maskId,
    IppiBorderType borderType,
    Ipp8u borderValue,
    Ipp8u* pBuffer,
    IppiPoint splitImage,
    IppiSize sliceSize,
    IppiSize lastSliceSize,
    int sliceBufferSize,
    ippiFilterSobelHV_T_Str* ts
)
{
    ts->pSrc               = pSrc;
    ts->srcStep            = srcStep;
    ts->pDst               = pDst;
    ts->dstStep            = dstStep;
    ts->maskId             = maskId;
    ts->borderType         = borderType;
    ts->borderValue        = borderValue;
    ts->pBuffer            = pBuffer;
    ts->splitImage         = splitImage;
    ts->sliceSize          = sliceSize;
    ts->lastSliceSize      = lastSliceSize;
    ts->sliceBufferSize    = sliceBufferSize;
}

/* Sobel Filter spec structure */
typedef struct
{
    IppiMaskSize maskId;
    IppNormType  normType;
    IppiSize     roiSize;
    IppiPoint    splitImage;
    IppiSize     sliceSize;
    IppiSize     lastSliceSize;
    IppDataType  srcDataType;
    IppDataType  dstDataType;
    Ipp32u       numChannels;
    int          sliceBufferSize;        /* Calculations buffer size for single slice                  */
    int          intermediateBufferSize; /* Intermediate results storage for functions in the pipeline */
    int lineBufferSize;            /* Intermediate results storage for accurate calculations in the pipeline */
} SobelInfo;

/* Sobel Filter parameters structure for threading routines */
typedef struct _ippiFilterSobel_T_Str
{
    const Ipp8u* pSrc;
    int srcStep;
    Ipp16s* pDst;
    int dstStep;
    IppiSize roiSize;
    IppiMaskSize maskId;
    IppNormType normType;
    IppiBorderType borderType;
    Ipp8u borderValue;
    Ipp8u* pBuffer;
    int sliceBufferSize;        /* Calculations buffer size for single slice                              */
    int intermediateBufferSize; /* Intermediate results storage for functions in the pipeline              */
    int lineBufferSize;            /* Intermediate results storage for accurate calculations in the pipeline */
    int numChannels;
    IppiPoint splitImage;
    IppiSize sliceSize;
    IppiSize lastSliceSize;
} ippiFilterSobel_T_Str;

/* Initialize Sobel Filter threading structure */
static void filterSobelThreadingStructureEncode_8u16s(
    const Ipp8u* pSrc,
    int srcStep,
    Ipp16s* pDst,
    int dstStep,
    IppiSize roiSize,
    IppiMaskSize maskId,
    IppNormType normType,
    IppiBorderType borderType,
    Ipp8u borderValue,
    Ipp8u* pBuffer,
    int sliceBufferSize,
    int intermediateBufferSize,
    int lineBufferSize,
    int numChannels,
    IppiPoint splitImage,
    IppiSize sliceSize,
    IppiSize lastSliceSize,
    ippiFilterSobel_T_Str* ts
)
{
    ts->pSrc                   = pSrc;
    ts->srcStep                = srcStep;
    ts->pDst                   = pDst;
    ts->dstStep                = dstStep;
    ts->roiSize                = roiSize;
    ts->maskId                 = maskId;
    ts->normType               = normType;
    ts->borderType             = borderType;
    ts->borderValue            = borderValue;
    ts->pBuffer                = pBuffer;
    ts->sliceBufferSize        = sliceBufferSize;
    ts->intermediateBufferSize = intermediateBufferSize;
    ts->lineBufferSize         = lineBufferSize;
    ts->numChannels            = numChannels;
    ts->splitImage             = splitImage;
    ts->sliceSize              = sliceSize;
    ts->lastSliceSize          = lastSliceSize;
}

#endif // PIFSOBEL_T_H__
