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

ippiResize Usage

sohrab_ali
Beginner
828 Views
Hi
I am very much new Intel IPP libraray.
I am trying to resize my input image (RGB24 , 720 x 576) into (RGB24 360 x 288)
1) Is it necessary that buffer size ofdstimage(720x576x3) should be same as of input image
I am trying that my dstimage buffersize should be of size 360 x 288 x 3
If you can help with my this code
const Ipp8u* pSrc=pData; // 720 x 576 x 3
int srcStep=720 * 3;
IppiSize srcSize;
srcSize.width=720;
srcSize.height=576;
IppiRect srcRec;
srcRec.x=0;
srcRec.y=0;
srcRec.width=720;
srcRec.height=576;

Ipp8u* pDst=NULL;
pDst=ippiMalloc_8u_C3(360,288,&frame);
int dstStep=360 * 3;
IppiSize dstroi;
dstroi.width=360;
dstroi.height=288;
double x=0.5;
double y=0.5;

status=ippiResize_8u_C3R(pSrc,srcSize,srcStep,srcRec,pDst,dstStep,dstroi,x,y,IPPI_INTER_NN);
0 Kudos
11 Replies
Vladimir_Dudnik
Employee
828 Views
Hi,
first of all, I see you did not used image step parameter for your destination image:
pDst=ippiMalloc_8u_C3(360,288,&frame);
but
status=ippiResize_8u_C3R(pSrc,srcSize,srcStep,srcRec,pDst,dstStep,dstroi,x,y,IPPI_INTER_NN);
I remember ippiResize function was discussed several times on this forum, so you can find it useful to look on these threads:
And of course, IPP Manual is very good source of information. I recommend you to read IPP Reference Manual, volume 2: Image and Video Processing, Chapter 12 - Image Geometric Transform, article Resize which contains function description and example of using
Regards,
Vladimir

Message Edited by vdudnik on 04-29-2005 08:25 AM

0 Kudos
tposhea
Beginner
828 Views

Please ignore.

0 Kudos
matthieu_darbois
New Contributor III
828 Views
Hi,

Could you please give more detail as to what is happening with the code you posted.
From what I can see, I'd say this should work.

As for dstStep, you can use 360*3 instead of the value returned in frame. Using the step returned by ippiMalloc is useful to speed up processing (All lines aligned on a 32 bytes boundary) but it is not necessary to use that step. You can use a lower step value. In this case, the smallest value acceptable being 360*3.

Regards,
Matthieu
0 Kudos
Vladimir_Dudnik
Employee
828 Views
Matthieu,

I have to correct your statement about step returned by ippiMalloc function. When you allocate image with ippiMalloc call you have to use step returned by this function.

Please refer to IPP documentation on ippiMalloc for more details:

Description

The function ippiMalloc is declared in the ippi.h file. This function allocates a memory block aligned to a 32-byte boundary for elements of different data types. Every line of the image is aligned by padding with zeros in accordance with the pStepBytes parameter, which is calculated by the ippiMalloc function and returned for further use.


Regards,
Vladimir
0 Kudos
matthieu_darbois
New Contributor III
828 Views
Hi Vladimir,

I'm sure of what I'm saying here. Not using the returned step just means you've allocated memory that won't be used : (mallocStep - usedStep) * Height bytes.
When you choose to use your own step value, you have to stick with it for every function call. You can't use a step value larger than the one returned by ippiMalloc but you can use one that's smaller and with which the image can fit in (that is a limit of width*datasize). The only constraint on step is that it should be a multiple of datasize.
This is a very useful parameter which allows to work on ROI, to process only partial data (step x 2 means you process one row out of 2 for example)... If this parameter was locked to the value returned by ippiMalloc then it wouldn't be very useful.
But, as I said in my previous post, the step returned by ippiMalloc is the one that provide the best performances when processing an image.

Regards,
Matthieu

0 Kudos
Vladimir_Dudnik
Employee
828 Views
Matthieu,

I'm not sure I get your point. Let's consider you allocated 3x3 Ipp8u single channel image with ippiMalloc function. Then memory layout will look like

x x x 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
x x x 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
x x x 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

and ippiMalloc will return you step 32. If you will use other step, say 16, you will not be able to correctly address the second and third rows of your image

Let's put address of the first image pixel is 100, then you'll get incorrect address of the first image pixel in second row, which in your case is 100 + 16 = 116, while in the reality it is 100 + 32 = 132

To process ROI you need to calculate address of the first pixel in your ROI and then using correct value of step (which should reflect real layout of image data in memory) you can easyly address any row or pixel in your ROI.

Based on example above, let's consider ROI with size 2x2 and left top corner coordinates x = 1, y = 1
x x x 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
xRR 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
xRR 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

To apply ippiSet_8u_C1R function forthis ROI you will need to calculate ROI base address, which will be 100 + 32 + 1 = 133 and call function in this way

IppiSize roi = { 2, 2};

roiPtr = pSrc + roiY*step + roiX;

ippiSet(value, roiPtr, step, pDst, dstStep, roi);

Regards,
Vladimir
0 Kudos
matthieu_darbois
New Contributor III
828 Views
Vladimir,

When you allocate an image, it is not initialized (even if ippiMalloc sets padding 0s). So it's the step you use for initialization of the image that's relevant for correct step usage in the following function calls.
I think that IPP functions doesn't rely on the fact that there is 0 padding at the end of each line. The only doubt I have is when calling functions not using ROI where it might rely on padding bytes being all 0. But for the vast majority of functions (using ROIs) there is no problem at all.
The memory layout is just one big block of memory. From a memory point of view there is no "lines". Only after initialization of the image we can view the block of memory as lines and columns.

Regards,
Matthieu

Edit :
According to IPP documentation regarding ROI, when a function does not operate on ROI, step must be equal to width * bytesperpixel. I quote :
"If ROI is present,
source and destination images can have different sizes
lines may have padding at the end for aligning the line sizes
application must correctly define the pSrc, pDst, and roiSize parameters."

This implies that when not using ROI, lines can't have padding.
0 Kudos
Vladimir_Dudnik
Employee
829 Views

I know that ippiMalloc does not initialize image pixels and I have used symbol 'x'in examples to refers to not initialized values.

That is true that memory is just a contiguous array of bytes. But how do you logically treat these bytes does matter.

The only valid casefor step which is equal to width * BytesPerPixel is whenimage memory allocated without padding at the end of image rows. It does not depend on whetherROI is usedor not! If examples from my previous post are not clear on that let me construct another example to address that particular case. Let's consider situation where memory allocated without padding for the same single channel, Ipp8u image with size 3x3:

Ipp8u* pSrc= (Ipp8u*)malloc(3*3);

Althoughreal memory block will look like just array of bytes x x x x x x x x x, logically it might be treated as 2D array

x x x
x x x
x x x

So,toget pointer tothesecond pixel in the second row (in assumtion that base address still the same 100) you will need do something like this Ipp8uroiPtr = 100 + 3 + 1. It is obvious that in case of padding this calculation will provide wrong result, isn't it?

Could you please refer to a certain example in IPP documentation which really says: "when a function does not operate on ROI, step must be equal to width * bytesperpixel"? I'm asking that because it is wrong in general case and so should be fixed in documenation.

Vladimir

0 Kudos
matthieu_darbois
New Contributor III
829 Views
Vladimir,

The quotation I used in my previous post is from ippiman.pdf page 68 (6.1.1.035 ia32 windows version). It does not say explicitly that "when a function does not operate on ROI, step must be equal to width * bytesperpixel" but says instead that when & function uses ROI, "lines may have padding at the end for aligning the line sizes".

I think we misunderstand each other with the step parameter. Let me illustrate this :
Consider a source image 3x3 (pSrc, step 3) :
s00 s01 s02
s10 s11 s12
s20 s21 s22

Now, let's allocate a destination image of size 3x3:

pDst = ippiMalloc_8u_C1(3, 3, &dstStep);
This gives a memory block of 96 bytes with dstStep = 32

if I use the returned dstStep then :
ippiAddC_8u_C1RSfs(pSrc, 3, 1, pDst, dstStep, 3x3, 0);

This gives as a result :
s00+1 s01+1 s02+1 x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
s10+1 s11+1 s12+1 x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
s20+1 s21+1 s22+1 x x x x x x x x x x x x x x x x x x x x x x x x x x x x x

if, instead of using dstStep, I use 4, then it would give :
ippiAddC_8u_C1RSfs(pSrc, 3, 1, pDst, 4, 3x3, 0);
s00+1 s01+1 s02+1 x
s10+1 s11+1 s12+1 x
s20+1 s21+1 s22+1 x
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x

Which is the correct result if I consider a step of 4 for the destination image. I do have 84 bytes not used after the actual image data+padding.
If I use that image in other functions and use a step of 4, it will work flawlessly.

The maximum and recommended step to use for an image is the one returned by ippiMalloc but ultimately, the final decision is up to developer.

Regards,
Matthieu

PS : I found an error in the documentation while writing this. ippiAddC is missing the "value" argument page 143.
0 Kudos
Vladimir_Dudnik
Employee
829 Views
Agree, from this point of view step returned by ippiMalloc is not mandatory for use, although it should be noted that such use might be really confusing for beginners. That's why my recommendation will be to use functions in way they were designed for. Otherwise it might be misleading to call ippiMalloc and do not use features it provides. Will not it be simplier to call just system malloc in that case?

Vladimir
0 Kudos
matthieu_darbois
New Contributor III
829 Views
Hi,
I totally agree that when not using the step as provided by IPP, it would be better and not misleading to use the system malloc. I was just saying that it was possible and thus, not the error in the specific code at the beginning of the thread.

Regards,
Matthieu
0 Kudos
Reply