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

Heap corruption in ippiWarpPerspectiveLinear_8u_C1R

Aleksandr_B_
Beginner
1,107 Views

Hello.

It seems the ipp 2018.3.210 contains a bug in the ippiWarpPerspectiveLinear_8u_C1R function.

The following sequence of code generates exception (Unhandled exception at 0x776DE9A3 (ntdll.dll) in blabla.exe: 0xC0000374: A heap has been corrupted (parameters: 0x77714270).) after last function call (all params are correct and the resulting image is also ok):

 

	int specSize, buffSize;
	ippCheck(ippiWarpQuadGetSize(
		IppiSize(src.size()), srcQuad,
		IppiSize(dst.size()), dstQuad,
		ippWarpPerspective, ipp8u, ippLinear, ippBorderTransp,
		&specSize, &buffSize));

	IppBuff<IppiWarpSpec> spec(specSize);
	ippCheck(ippiWarpQuadLinearInit(
		IppiSize(src.size()), srcQuad,
		IppiSize(dst.size()), dstQuad,
		ippWarpPerspective, ipp8u, 1, ippBorderTransp, 0, 0,
		spec.ptr()));
	
	IppBuff<Ipp8u> buffer(buffSize);
	ippCheck(ippiWarpPerspectiveLinear_8u_C1R(
		src.ptr(), (int)src.step,
		dst.ptr(), (int)dst.step, IppiPoint(), IppiSize(dst.size()),
		spec.ptr(), buffer.ptr()));

 

0 Kudos
9 Replies
Pavel_B_Intel1
Employee
1,107 Views

Hello,

thank for the report, will investigate and report about results.

Pavel

0 Kudos
Aleksandr_B_
Beginner
1,107 Views

update:

I use 32 bit static libraries.

I've checked versions 2017.1.143 and 2017.4.210 - all the same.

ippiWarpAffineLinear_8u_C1R works fine.

OS Windows 7 (x64), Visual Studio 2015.

P.S. IppBuff<> is my wrapper around ippMalloc / ippFree; ippCheck() just checks the function return values.

0 Kudos
Tatyana_B_Intel
Employee
1,107 Views

Hi Alexander,

Could you please provide the simple reproducer with actual parameters values? Or at least image sizes.

Best regards,

Tatyana

0 Kudos
Aleksandr_B_
Beginner
1,107 Views

source image size: 438 x 270

destination image size: 768 x 160

source quadrangle is convex and about  270 x 100 inside source image

destination quadrangle is the whole destination image.

0 Kudos
Aleksandr_B_
Beginner
1,107 Views

ok,

I've added a couple of lines and made up VS2015 solution reproducing the bug (see attachment)

0 Kudos
Tatyana_B_Intel
Employee
1,107 Views
Thanks a lot for the reproducer. I'll check this and will back to you. Best regards, Tatyana
0 Kudos
Tatyana_B_Intel
Employee
1,107 Views

Alexander,

I've checked your reproducer and found that you missed ippiWarpGetBufferSize usage for defining the size of buffer for ippiWarpPerspectiveLinear_8u_C1R. 

Please see an example here: https://software.intel.com/en-us/ipp-dev-reference-warpquadnearestinit-sample 

And the documentation for ippiWarpPerspectiveLinear https://software.intel.com/en-us/ipp-dev-reference-warpperspectivelinear

Also please find the fixed version of your example:

#include <ipp.h>
#include <vector>
#include <iostream>
#include <Windows.h>


class HeapChecker
{
private:
	void check() const {_heapchk();}

public:
	explicit HeapChecker() {check();}
	~HeapChecker() {check();}
};


int main()
{
	const int srcW = 438, srcH = 270, dstW = 768, dstH = 160;
	std::vector<Ipp8u> src(srcW * srcH);
	std::vector<Ipp8u> dst(dstW * dstH);

	double srcQuad[4][2] = {{82., 140.}, {355., 134.}, {352., 221.}, {82., 218.}};
	double dstQuad[4][2] = {{0., 0.}, {767., 0.}, {767., 159.}, {0., 159.}};
	IppStatus sts = ippStsNoErr;

	int specSize, buffSize;
	sts = ippiWarpQuadGetSize(
		IppiSize{srcW, srcH}, srcQuad,
		IppiSize{dstW, dstH}, dstQuad,
		ippWarpPerspective, ipp8u, ippLinear, ippBorderTransp,
		&specSize, &buffSize);

	IppiWarpSpec *spec = (IppiWarpSpec*)ippsMalloc_8u(specSize);
	sts = ippiWarpQuadLinearInit(
		IppiSize{srcW, srcH}, srcQuad,
		IppiSize{dstW, dstH}, dstQuad,
		ippWarpPerspective, ipp8u, 1, ippBorderTransp, 0, 0,
		spec);

	sts = ippiWarpGetBufferSize(spec, IppiSize{ dstW, dstH }, &buffSize);

	Ipp8u *buffer = ippsMalloc_8u(buffSize);
	{
		HeapChecker heap_checker;

		sts = ippiWarpPerspectiveLinear_8u_C1R(
			src.data(), srcW,
			dst.data(), dstW, IppiPoint(), IppiSize{dstW, dstH},
			spec, buffer);
	}

	std::cout << "I'm happy if you see this";

	ippFree(spec);
	ippFree(buffer);
}

Best regards,

Tatyana

0 Kudos
Aleksandr_B_
Beginner
1,107 Views

Thank very much you for your assistance.

Yes, it was my fault.

P.S. In my defence I'd like to say that the functions call logic seems to me rather weird: why do we need to submit &buffSize at the ippiWarpQuadGetSize function call if the real buffer size is calculated by another function - ippiWarpGetBufferSize ?

0 Kudos
Tatyana_B_Intel
Employee
1,107 Views

Alexander,

ippiWarpQuadGetSize calculates buffer size for Init functions. In case of Linear interpolation additional buffer is not required. But in case of Cubic one you can see the last parameter - Init Buffer (https://software.intel.com/en-us/ipp-dev-reference-warpperspectivecubicinit). 

So it was introduced 1 API to cover all possible cases of interpolations.

Best regards,

Tatyana

0 Kudos
Reply