/******************************************************************************* * Copyright 2015-2018 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. *******************************************************************************/ // An example of performing The code example shows how these functions can be used to organize the separable convolution as a step of // image processing pipeline.implemented with Intel(R) Integrated Primitives (Intel(R) IPP) functions : // ippiFilterRowBorderPipelineGetBufferSize_Low_16s_C1R // ippiFilterColumnPipeline_Low_16s_C1R // ippiFilterColumnPipelineGetBufferSize_Low_16s_C1R // ippiFilterRowBorderPipeline_Low_16s_C1R #include #include "ipp.h" #define WIDTH 32 /* image width */ #define HEIGHT 16 /* image height */ #define kernelSize 5 /* Next two defines are created to simplify code reading and understanding */ #define EXIT_MAIN exitLine: /* Label for Exit */ #define check_sts(st) if((st) != ippStsNoErr) goto exitLine; /* Go to Exit if Intel(R) IPP function returned status different from ippStsNoErr */ /* Results of ippMalloc() are not validated because Intel(R) IPP functions perform bad arguments check and will return an appropriate status */ int main(void) { IppStatus status = ippStsNoErr; const Ipp16s **pGet = NULL; Ipp16s* src = NULL, *dst = NULL; int xAnchor = kernelSize >> 1; /* The anchor value, (0 <= xAnchor < kernelSize) */ Ipp16s pKerX[kernelSize] = { 1, 2, 3, 2, 1 }; Ipp16s pKerY[kernelSize] = { 1, 2, 0, 2, 1 }; /* The pointer to the kernels */ Ipp16s* pSrc = NULL, *pDst = NULL; /* Pointers to source/destination images */ int srcStep = 0, dstStep = 0; /* Steps, in bytes, through the source/destination images */ IppiSize roiSize = { WIDTH, HEIGHT }; /* Size of source/destination ROI in pixels */ IppiSize roi = { WIDTH, 1 }; /* Size of destination ROI in pixels */ int divisor = 1; /* The value to divide output pixels by */ Ipp8u borderValue = 0; Ipp8u *pBufRow = NULL, *pBufCol = NULL;/* Pointer to the work buffer */ int sizeRow = 0, sizeCol = 0; /* Common work buffer size */ int todo = roiSize.height, bufLen; int mStep = (roiSize.width + 7)&(~7); int sStep = 0, dStep = 0; int i, j, n; Ipp16s* pCycleBuf; pGet = (const Ipp16s**)ippsMalloc_8u(kernelSize*sizeof(Ipp16s*)); pCycleBuf = (const Ipp16s**)ippsMalloc_8u(mStep * kernelSize *sizeof(Ipp16s)); pSrc = ippiMalloc_16s_C1(roiSize.width, roiSize.height, &srcStep); pDst = ippiMalloc_16s_C1(roiSize.width, roiSize.height, &dstStep); dst = pDst; src = pSrc; sStep = srcStep >> 1, dStep = dstStep >> 1; for (n = 0; n < kernelSize; n++) { pGet[n] = (Ipp16s*)pCycleBuf + n * mStep; } for (i = 0; i < roiSize.height; i++) { for (j = 0; j < roiSize.width; j++) { *(pSrc + i*sStep + j) = i; } } check_sts( status = ippiFilterRowBorderPipelineGetBufferSize_Low_16s_C1R(roiSize, 3, &sizeRow) ) check_sts( status = ippiFilterColumnPipelineGetBufferSize_Low_16s_C1R(roiSize, 3, &sizeCol) ) pBufRow = ippsMalloc_8u(sizeRow); pBufCol = ippsMalloc_8u(sizeCol); src = pSrc; for (j = 0; j < kernelSize - 1; j++){ check_sts(status = ippiFilterRowBorderPipeline_Low_16s_C1R(src, srcStep, &pGet[j], roi, pKerX, kernelSize, xAnchor, ippBorderRepl, borderValue, divisor, pBufRow)) src += sStep; } for (j = 0; j < roiSize.height; j++){ check_sts( status = ippiFilterRowBorderPipeline_Low_16s_C1R(src, srcStep, &pGet[kernelSize-1], roi, pKerX, kernelSize, xAnchor, ippBorderRepl, borderValue, divisor, pBufRow) ) check_sts( status = ippiFilterColumnPipeline_Low_16s_C1R(pGet, dst, dstStep, roi, pKerY, kernelSize, divisor, pBufCol) ) src += sStep; dst += dStep; { Ipp16s* tGet= pGet[0]; for (n = 0; n < kernelSize - 1; n++){ pGet[n] = pGet[n + 1]; } pGet[kernelSize - 1] = tGet; } } EXIT_MAIN ippsFree(pGet); ippsFree(pCycleBuf); ippiFree(pSrc); ippsFree(pBufRow); ippsFree(pBufCol); ippiFree(pDst); printf("Exit status %d (%s)\n", (int)status, ippGetStatusString(status)); return (int)status; }