Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

Possible bug of Intel IPP 9.0 for Resize image.

Tam_N_1
Beginner
1,116 Views

Hi staff,

I have worked for a time with the new resize functions in IPP 9.0. and I'm getting some problems which need a help:

I have a input picture size 512x512 and I want to resize it. For simplest, I start with output size 512x512. I used this code which supplied by Valentine in this post :

https://software.intel.com/en-us/forums/intel-integrated-performance-primitives/topic/610642

IppStatus resizeShiftCubic_32f_C1R(Ipp32f* pSrc, IppiSize srcSize, Ipp32s srcStep, Ipp32f* pDst, IppiSize dstSize, Ipp32s dstStep, IppiPoint dstShift)
{
	IppiResizeSpec_32f* pSpec = 0;
	int specSize = 0, initSize = 0, bufSize = 0; Ipp8u* pBuffer = 0;
	Ipp32u numChannels = 1; IppiPoint dstOffset = { 0, 0 }; IppStatus status = ippStsNoErr;
	IppiBorderType border = ippBorderRepl;
	Ipp8u* pInit = NULL;
	IppiRect dstRoi = { dstShift.x, dstShift.y, dstSize.width, dstSize.height };
	IppiSize dstRoiSize = { 0 };
	Ipp32f* pDstRoi = (Ipp32f*)((Ipp8u*)pDst + dstRoi.y * dstStep) + dstRoi.x * numChannels;

	if (dstShift.x < 0)
	{
		dstOffset.x = -dstShift.x;
		dstRoi.width -= dstShift.x;
		dstShift.x = 0;
		pDstRoi = pDstRoi + dstOffset.x * numChannels;
	}

	if (dstShift.y < 0)
	{
		dstOffset.y = -dstShift.y;
		dstRoi.height -= dstShift.y;
		dstShift.y = 0;
		pDstRoi = (Ipp32f*)((Ipp8u*)pDstRoi + dstOffset.y * dstStep);
	}

	if (dstRoi.x + dstRoi.width > dstSize.width)
	{
		dstRoi.width = dstSize.width - dstRoi.x;
	}

	if (dstRoi.y + dstRoi.height > dstSize.height)
	{
		dstRoi.height = dstSize.height - dstRoi.y;
	}

	dstRoiSize.width = dstRoi.width;
	dstRoiSize.height = dstRoi.height;

	/* Spec and init buffer sizes */
	status = ippiResizeGetSize_32f(srcSize, dstSize, ippCubic, 0, &specSize, &initSize);

	/* Memory allocation */
	pSpec = (IppiResizeSpec_32f*)ippsMalloc_8u(specSize);

	pInit = ippsMalloc_8u(initSize);

	/* Filter initialization */
	if (status >= ippStsNoErr) status = ippiResizeCubicInit_32f(srcSize, dstSize, 0.f, 0.0f, pSpec, pInit);

	ippsFree(pInit);

	/* work buffer size */
	if (status >= ippStsNoErr) status = ippiResizeGetBufferSize_32f(pSpec, dstSize, numChannels, &bufSize);

	pBuffer = ippsMalloc_8u(bufSize);

	/* Resize processing */
	if (status >= ippStsNoErr) status = ippiResizeCubic_32f_C1R(pSrc, srcStep, pDstRoi, dstStep, dstOffset, dstRoiSize, border, 0, pSpec, pBuffer);
	//if (status >= ippStsNoErr) status = ippiResizeCubic_32f_C1R(pSrc, srcStep, pDst, dstStep, { 30, 30 }, { 300,500 }, border, 0, pSpec, pBuffer);

	
	ippsFree(pSpec);
	ippsFree(pBuffer);

	return status;

}

 Above code work OK with when dstOffset = {0,0}. dstRoiSize = {512, 512}. It give output image is same as input image.

I changed dstOffset = {0,0}, dstRoiSize = {300,300}. It work ok and give output image have region 300x300 from input image , remain region is blank.

Now i want to change dstOffset = {30,30} and dstRoiSize = {300,300}. Then program is crashed. This is so strange because i think it should give me a image of region {x=30,y=30,w=300,h=300} from input image.

I think this is bug from the library. Or may i misunderstood about dstOffset. Please give me some comment about this.

Regards,

Tam.

0 Kudos
5 Replies
Valentin_K_Intel
Employee
1,116 Views

Hi Tam,

Could you please provide the reproducer for the crash? 

Best regards,
Valentin

0 Kudos
Tam_N_1
Beginner
1,116 Views

Hi,

Above code give me the program crash. 

#include "ippi.h"
#include "ipps.h"

#define SIZE 512
int main()
{
	IppiResizeSpec_32f* pSpec = 0;
	int specSize = 0, initSize = 0, bufSize = 0; Ipp8u* pBuffer = 0;
	Ipp32u numChannels = 1; IppStatus status = ippStsNoErr;
	IppiBorderType border = ippBorderRepl;
	Ipp8u* pInit = 0;

	IppiSize srcSize = { SIZE, SIZE };
	IppiSize dstSize = { SIZE, SIZE };

	IppiPoint dstOffset = { 30,30 };
	IppiSize dstRoiSize = { 300,300 };

	int srcStep;
	int dstStep;
	Ipp32f * pSrc = 0;
	Ipp32f * pDst = 0;

	pSrc = ippiMalloc_32f_C1(srcSize.width, srcSize.height, &srcStep);
	pDst = ippiMalloc_32f_C1(dstSize.width, dstSize.height, &dstStep);

	ippiSet_32f_C1R(1, pSrc, srcStep, srcSize);
	ippiSet_32f_C1R(0, pDst, dstStep, dstSize);

	/* Spec and init buffer sizes */
	status = ippiResizeGetSize_32f(srcSize, dstSize, ippCubic, 0, &specSize, &initSize);

	/* Memory allocation */
	pSpec = (IppiResizeSpec_32f*)ippsMalloc_8u(specSize);

	pInit = ippsMalloc_8u(initSize);

	/* Filter initialization */
	if (status >= ippStsNoErr) status = ippiResizeCubicInit_32f(srcSize, dstSize, 0.0f, 0.0f, pSpec, pInit);

	ippsFree(pInit);

	/* work buffer size */
	if (status >= ippStsNoErr) status = ippiResizeGetBufferSize_32f(pSpec, dstSize, numChannels, &bufSize);

	pBuffer = ippsMalloc_8u(bufSize);

	/* Resize processing */
	if (status >= ippStsNoErr) status = ippiResizeCubic_32f_C1R(pSrc, srcStep, pDst, dstStep, dstOffset, dstRoiSize, border, 0, pSpec, pBuffer);

	ippsFree(pSpec);
	ippsFree(pBuffer);

	ippiFree(pSrc);
	ippiFree(pDst);

	return 0;
}

My environment is Visual Studio 2015 + Parallel Studio XE 2016 on Windows 7 64-bit.

Please help to check this.

Best regards,

Tam.

0 Kudos
Valentin_K_Intel
Employee
1,116 Views

Hi Tam,

Parameters pSrc and pDst must point to the processed source and destination image ROI origins, respectively. The processing functions operates with ROI. It resizes the source image ROI origin to the destination image ROI origin. The offset of the tiled destination image with respect to the destination image origin and the destination image size define the destination image ROI. The source image ROI origin is defined automatically. To obtain the source image ROI, use the ippiResizeGetSrcRoi_32f function. To obtain the source image ROI origin offset, call the ippiResizeGetSrcOffset_32f function.

So, the code should look like this:

#include "ipps.h"
#include "ippi.h"

#define SIZE 512
int main()
{
	IppiResizeSpec_32f* pSpec = 0;
	int specSize = 0, initSize = 0, bufSize = 0; Ipp8u* pBuffer = 0;
	Ipp32u numChannels = 1; IppStatus status = ippStsNoErr;
	IppiBorderType border = ippBorderRepl;
	Ipp8u* pInit = 0;

	IppiSize srcSize = { SIZE, SIZE };
	IppiSize dstSize = { SIZE, SIZE };

	IppiPoint srcOffset = { 0 };
	IppiPoint dstOffset = { 30,30 };
	IppiSize dstRoiSize = { 300,300 };

	int srcStep;
	int dstStep;
	Ipp32f * pSrc  = 0;
	Ipp32f * pDst  = 0;
	Ipp32f * pSrcT = 0;
	Ipp32f * pDstT = 0;

	pSrc = ippiMalloc_32f_C1(srcSize.width, srcSize.height, &srcStep);
	pDst = ippiMalloc_32f_C1(dstSize.width, dstSize.height, &dstStep);

	ippiSet_32f_C1R(1, pSrc, srcStep, srcSize);
	ippiSet_32f_C1R(0, pDst, dstStep, dstSize);

	/* Spec and init buffer sizes */
	status = ippiResizeGetSize_32f(srcSize, dstSize, ippCubic, 0, &specSize, &initSize);

	/* Memory allocation */
	pSpec = (IppiResizeSpec_32f*)ippsMalloc_8u(specSize);

	pInit = ippsMalloc_8u(initSize);

	/* Filter initialization */
	if (status >= ippStsNoErr) status = ippiResizeCubicInit_32f(srcSize, dstSize, 0.0f, 0.0f, pSpec, pInit);

	ippsFree(pInit);

	/* Source ROI offset */
	if (status >= ippStsNoErr) status = ippiResizeGetSrcOffset_32f(pSpec, dstOffset, &srcOffset);

	/* work buffer size */
	if (status >= ippStsNoErr) status = ippiResizeGetBufferSize_32f(pSpec, dstRoiSize, numChannels, &bufSize);

	pBuffer = ippsMalloc_8u(bufSize);

	/* Shifts the pointers */
	pSrcT = (Ipp32f*)((Ipp8u*)pSrc + srcStep * srcOffset.y) + srcOffset.x * numChannels;
	pDstT = (Ipp32f*)((Ipp8u*)pDst + dstStep * dstOffset.y) + dstOffset.x * numChannels;

	/* Resize processing */
	if (status >= ippStsNoErr) status = ippiResizeCubic_32f_C1R(pSrcT, srcStep, pDstT, dstStep, dstOffset, dstRoiSize, border, 0, pSpec, pBuffer);

	ippsFree(pSpec);
	ippsFree(pBuffer);

	ippiFree(pSrc);
	ippiFree(pDst);

	return 0;
}

Best regards,
Valentin

0 Kudos
Tam_N_1
Beginner
1,116 Views

Hi Valentin,

Thank you for your answer. Now I understand.

Honestly, I think the implementation of ippiResize is quite hard to use and not flexible because it required the pDst pointer must be allocated with size dstSize. In my case, I only have the pDst pointer which is allocated with size dstRoiSize.(The old ippiResize_32f_C1R supported this).

Thank you alot.

0 Kudos
Valentin_K_Intel
Employee
1,116 Views

Hi Tam,

It is not required to allocate the memory for the full destination image. It is enough to allocate the memory only for dstRoiSize and to provide the source image ROI with borders is accessible in the memory. However whole image sizes (srcSize, dstSize) must be passed to ResizeGetSize and Resize<Interp>Init functions.

Thanks,
Valentin

0 Kudos
Reply