Image resize has been upgraded in Intel® IPP 7.1. There are several differences between the new resize, ippiResizeSqrPixel (Intel® IPP 7.0), and ippiResize (previous versions).
Benefits of the new resize approach include:
- Smaller footprint: ippiResizeSqrPixel can add several MB to executable size when linked statically. This is because all interpolation mode pathways are in the same function. Interpolation mode for ippiResizeSqrPixel is chosen with a variable (which could change at runtime, though in practice this rarely happens) so at compile time all interpolation modes must be included. The new resize uses different functions for each interpolation method, and each function is significantly smaller.
- Multiple use optimizations: the ippiResize* functions use a IppiResizeSpec buffer to hold coefficients that can be pre-calculated. So, for cases where the same input and output resolutions will be used multiple times this avoids the overhead of recalculating for each iteration.
- Better support for tiling and threading. While ippiResizeSqrPixel can be used in tiling scenarios the use model was not as easy as it could be. The new resize functions are designed to make this easier.
The new resize functions continue the trend of externalizing memory allocations and control seen in Intel® IPP 7.0 and earlier to give you the best performance possible. The old ippiResize interface was self contained, in that it could be called with only the source and destination buffers. For ippiResizeSqrPixel a single external buffer is required. The new resize functions in Intel® IPP 7.1 use two external buffers.
To illustrate (please note: this resize method has been removed in Intel® IPP 7.1) here is the old resize:
ippiResize_8u_C1R(pSrc, srcsize, stridesrc_8u, srcRoi, pDst, stridedst_8u, dstsize, wratio, hratio, IPPI_INTER_LANCZOS);
The ippiResizeSqrPixel interface added external management of a working buffer:
ippiResizeGetBufSize(srcRoi, dstRoi, nChannel, IPPI_INTER_LANCZOS, &bufSize2 ); pBuffer= ippsMalloc_8u(bufSize2 ); ippiResizeSqrPixel_8u_C1R(pSrc, srcsize, stridesrc_8u, srcRoi, pDst, stridedst_8u, dstRoi, wratio, hratio, 0.0, 0.0, IPPI_INTER_LANCZOS, pBuffer); ippsFree(pBuffer);
In the new resize an additional IppiResizeSpec_32f buffer is added. This allows coefficients to be pre-calculated, which offers performance benefits in two ways. First, re-calculating them can be avoided if the same combination of input and output resolution will be reused. A common scenario is video frame processing, where the same combination of resolutions may be used thousands of times. Second, this is part of improved threading support. Coefficients may be pre-calculated instead of repeating these operations in each thread.
// get working buffer sizes ippiResizeGetSize_8u(srcsize,dstsize,ippLanczos, 0, &specSize, &initSize); // allocate working buffers Ipp8u *pInitBuf=ippsMalloc_8u(initSize); IppiResizeSpec_32f* pSpec=(IppiResizeSpec_32f*)ippsMalloc_8u(specSize); ippiResizeLanczosInit_8u(srcsize, dstsize, numLobes, pSpec, pInitBuf); ippiResizeGetBufferSize_8u(pSpec,dstsize,nChannel,&bufSize); Ipp8u* pBuffer=ippsMalloc_8u(bufSize); ippiResizeLanczos_8u_C1R(pSrc, stridesrc_8u, pDst, stridedst_8u, dstOffset, dstsize, ippBorderRepl, 0, pSpec, pBuffer); ippsFree(pInitBuf); ippsFree(pSpec); ippsFree(pBuffer);