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

<b>Moving image data in and out of IPP types</b>

Ryan2
Beginner
767 Views
Hi,
I'm using IPP for filtering. I'm having a hard time getting my source image data into IPP types and then back again.
Only the R channel is making it all the way through to Out_Img. I'm not sure if the problem is in the SourceToIpp function or in the IppToSource function. The non-Ipp code is working fine. It's something to do with the Ipp_Img and temp.
I'll most likely multithread these functions once I get them working. For now, I tried to keep them as clean as possible. I'm new to IPP so if there is a more efficient to copy the data inside the nested loops I would appreciate suggestions.
Any thoughts on why only the red channel is making it through? Thanks!!
[cpp]int In_StepBytes;
Ipp32f *Ipp_In;
IppiSize In_Size;

// Get input images
In_Img = (Image *)InImage->GetValue(req);

Ipp_In = ippiMalloc_32f_C3(In_Img->Width, In_Img->Height, &In_StepBytes);

SourceToIpp(In_Img, Ipp_In);
///////
//Do filtering with Ipp_In
///////

// Copy In_Img to Out_Img
Out_Img = In_Img->CopyOfImage();
IppToSource(Out_Img, Ipp_In);
 

void SourceToIpp(Image *S_Img, Ipp32f *Ipp_Img)
{

	int temp_StepBytes;
	Ipp32f *temp;
	IppiSize temp_Size;

	int p_StepBytes;
	Ipp32f *p_Color[3];

	int x = 0;
	int y = 0;

	PixPtr p_Img(S_Img);
	FltPixel p;

	// Allocate memory for temp Ipp image to represent pixel
	temp = ippiMalloc_32f_C3(1, 1, &temp_StepBytes);

	// Allocate memory for p_Color
	p_Color[0] = ippiMalloc_32f_C1(1, 1, &p_StepBytes);
	p_Color[1] = ippiMalloc_32f_C1(1, 1, &p_StepBytes);
	p_Color[2] = ippiMalloc_32f_C1(1, 1, &p_StepBytes);

	// Set temp size
	temp_Size.height = 1;
	temp_Size.width = 1;

	// Loop through image and copy data
	for (y = 0; y < S_Img->Height; y++)
	{
		p_Img.GotoXY(0, y);

		for (x = 0; x < S_Img->Width; x++)
		{
			// Advance through source pixels in current row
			if (x == 0)
				p = p_Img;
			else
				p >>= p_Img;
				
			// Copy source pixel data to Ipp p_Color
			*p_Color[0] = p.R;
			*p_Color[1] = p.G;
			*p_Color[2] = p.B;

			// Set temp IPP image to p_Color
			ippiCopy_32f_P3C3R(p_Color, p_StepBytes, temp, temp_StepBytes, temp_Size);

			// Copy IPP temp value to IPP bg at pointer locatoin offset by x and y
			*(Ipp_Img + (y * S_Img->Width) + x ) = *temp;
		}
	}

	// Free memory allocated for temp
	ippiFree(temp);
	ippiFree(p_Color[0]);
	ippiFree(p_Color[1]);
	ippiFree(p_Color[2]);
}


void IppToSource(Image *S_Img, Ipp32f *Ipp_Img)
{

	int temp_StepBytes;
	Ipp32f *temp;
	IppiSize temp_Size;

	int p_StepBytes;
	Ipp32f *p_Color[3];	

	int x = 0;
	int y = 0;

	PixPtr p_Img(S_Img);
	FltPixel p;

	// Allocate memory for temp Ipp image to represent pixel
	temp = ippiMalloc_32f_C3(1, 1, &temp_StepBytes);

	// Allocate memory for p_Color
	p_Color[0] = ippiMalloc_32f_C1(1, 1, &p_StepBytes);
	p_Color[1] = ippiMalloc_32f_C1(1, 1, &p_StepBytes);
	p_Color[2] = ippiMalloc_32f_C1(1, 1, &p_StepBytes);

	// Set temp size
	temp_Size.height = 1;
	temp_Size.width = 1;

	// Loop through image and copy data
	for (y = 0; y < S_Img->Height; y++)
	{
		p_Img.GotoXY(0, y);

		for (x = 0; x < S_Img->Width; x++)
		{

			// Copy IPP value at pixel pointer position to temp
			*temp = *(Ipp_Img + (y * S_Img->Width) + x);	

			ippiCopy_32f_C3P3R(temp, temp_StepBytes, p_Color, p_StepBytes, temp_Size);

			// Copy Ipp color data to
			p.R = *p_Color[0];
			p.G = *p_Color[1];
			p.B = *p_Color[2];
			p.A = 0;
			
			// Advance through source pixels in current row
			if (x == 0)
				p_Img = p;
			else
				p_Img >>= p;
			
		}
	}

	// Free memory allocated for temp
	ippiFree(temp);
	ippiFree(p_Color[0]);
	ippiFree(p_Color[1]);
	ippiFree(p_Color[2]);
}[/cpp]
0 Kudos
5 Replies
igorastakhov
New Contributor II
767 Views
Hi,

I don't understand your code, especiallythe next construction - p >>= p_Img;

Don't use P3C3 copy for 1 pixel - it's not efficient at all.
The next construction is wrong:
*(Ipp_Img + (y * S_Img->Width) + x ) = *temp;
you are copying here only R value and you should go from row to row by image step, not by its width:

tmpPtr = (Ipp32f*)( (Ipp8u*)Ipp_Img + y * in_StepBytes + 3 * SizeOf( Ipp32f ) * x );
tmpPtr[0] = p.R;
tmpPtr[1] = p.G;
tmpPtr[2] = p.B;

as C3 IPP image is represented as packed RGB values + align bytes for each row:
RGBRGBRGBRGB....RGBxxxxx
where xxxxx means a number of bytes (depends on image width) to align the beginning of the next row to 16-byte boundary

Regards,
Igor

0 Kudos
Ryan2
Beginner
767 Views
Hi Igor,

Thank you for the reply.

p is a variable holding one pixel using a type defined outside of IPP. p>>=p_Img copys the data in p into P_Img which is a pointer to a pixel in the non-IPP image type. As well as copying the data, >>= also advanves p_Img to the next pixel. Moreover, p>>=p_Img simply sets the pixel at at x,y equal p and advances to the next pixel in the row. p_Img.Goto(0,y) is used to set the start of each row.

I'll use the bytestep from now on instead of width. Thanks.

tmpPtr = (Ipp32f*) ( (Ipp8u*)Ipp_Img + y*in_StepBytes + 3 * SizeOf(Ipp32f)*x );

What is the purpose of (Ipp8u*)?

Is the above expression valid when tmpPtr is a 3-plane Ipp32f_C1 and Ipp_Img is a pixel-ordered Ipp32f_C3?

Best,
Ryan
0 Kudos
Ying_H_Intel
Employee
767 Views
Hi Ryan,

Could you please tell how you store yoursource image data?Are they are in continous array or discretedpoint in large array?

As you see, ipp image processing funtion(include ippiFilter_* function) use continous array.
They can be any continous array
frompSrc[512][512]
orpsr =malloc(width*height*sizeof(float)*channel).
or used aligned memory: Ipp_In=ippiMalloc_32f_C3(In_Img->Width,In_Img->Height,&In_StepBytes);
or fromyourImage class, where image data are stored in continous array.
(there is nospecial IPP image type needed).

So if your source image data are stored continously, then you may use them directly to ippiFilter function. like the C++ sample in IPP code sample or do search the sample code in the forum

ippiFilterGauss_8u_C1R( (Ipp8u*)pSrc->DataPtr(), pSrc->Step(),
(Ipp8u*)pDst->DataPtr(), pDst->Step(), pSrc->Size(),
,ippMskSize3x3)
It is not need to do the moving in or out.

If your souce image data are stored in discreted points, you may copy them to an array pSrc[width][height].
thus there is not needed to call ipp function like ippiCopy to copy only one pixel also. (it is inefficient).

but you have to use IPP function call, it may need to understand the bytestep,please see the article
http://software.intel.com/en-us/articles/intel-integrated-performance-primitives-intel-ipp-processing-an-image-from-edge-to-edge/

stepBytes.It is the distance in bytes of imagerow.It depends on your array memory layout and datatype.

AsstepBytesare in bytes, sothestart pointer IPP_img should be byte type. (either ipp 8u*, actually unsignedchar *)
Such the Ipp_Img + y*in_StepBytespoint tothe firstaddress of y row. then convert it to (IPP 32f*,actually float *) to get float pixel (whateveryRRRRRR, or RGBRGB store) .

Best Regards,
Ying

  • IppiSizeroiSize={1022,1022};
  • IppiSizeimgSize={1024,1024};
  • size_tsize=imgSize.width*imgSize.height*sizeof(Ipp8u);
  • intsrcStep=imgSize.width*sizeof(Ipp8u);
  • Ipp8u*data=(Ipp8u*)malloc(size);
  • Ipp8u*pStartPoint;
  • pStartPoint=data;
  • ippiImageJaehne_8u_C1R(pStartPoint,srcStep,imgSize);
  • intdstStep=roiSize.width*sizeof(Ipp8u);
  • size_tdstSize=roiSize.width*roiSize.height;
  • Ipp8u*dst=(Ipp8u*)malloc(dstSize);
  • ippiFilterGauss_8u_C1R(data+srcStep/sizeof(Ipp8u)+1,srcStep,dst,dstStep,roiSize,ippMskSize3x3
  • 0 Kudos
    SergeyKostrov
    Valued Contributor II
    767 Views
    It looks like some ATL'sCOM objects are used:

    >>...
    >>PixPtrp_Img( S_Img );
    >>FltPixel p;
    >>...

    and PixPtr is an MIDL's generatedCOM-class-wrapper.

    >>...
    >>p >>= p_Img;
    >>...

    and '>>=' is a C++ operator that moves some data to 'p_Img'...

    Best regards,
    Sergey
    0 Kudos
    Ryan2
    Beginner
    767 Views
    Thanks Guys. I was able to get it working using this code:
    [cpp]			p.R = *(Ipp32f*)((Ipp8u*)Ipp_Img + (y * Ipp_StepBytes) + 3*sizeof(Ipp32f)*x );
    			p.G = *(Ipp32f*)((Ipp8u*)Ipp_Img + (y * Ipp_StepBytes) + 3*sizeof(Ipp32f)*x + sizeof(Ipp32f) );
    			p.B = *(Ipp32f*)((Ipp8u*)Ipp_Img + (y * Ipp_StepBytes) + 3*sizeof(Ipp32f)*x + 2*sizeof(Ipp32f) );[/cpp]
    0 Kudos
    Reply