Link Copied
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.
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.
[cpp]status = GaussBmp((Ipp8u*)growData.Scan0, growSize, nChannel, ippMskSize5x5); [/cpp]
Hello noemata,
I try your code. You may have noticed that there is different valuebetween
pad=ippiMalloc_8u_C1
and
step = padSize.width * nChannels
for example, in your case, for image pad, width=8+2*3=14,
the step returned by ippiMalloc is32
step= padSize.width*nChannnels is 14.
Then you havethecode
step = padSize.width * nChannels;
if (nChannels == 1)
{
status = ippiCopyReplicateBorder_8u_C1R(pSrc, srcSize.width * nChannels, srcSize, pad, step, padSize, nPad, nPad);
Itseems to work, but actually the copy result is not expected. (It will cause more potiential error, e.g your mentioned 24 bit doesn't work).
in detial, if you use ippiMalloc toallocate memory to pad, then the copy resultin padshould be
i.e the first twoline
003 003 003 003 003 003 003 003 008 008 008 008 008 008 then 000 000 000 000 000 000 000 000 ...
003 003 003 003 003 003 003 003 008 008 008 008 008 008 then 000 000 000 000 000 000 000 000
(As Vladmirmentioned,pad is 32-byte aligned, where every line is 32 bytes. The first 18 byte has copy value, the 18~32 should be padded with zeros. )
But if you change the step=14, thenthe real result in pad (first64 bytes)is
003 003 003 003 003 003 003 003 008 008 008 008 008 008 003 003 003 003 003 003 003 003 008 008 008 008 008 008 003 003 003 003 ....
become consecutive value.
So when you use ippiMalloc,you can use stepBytes directly instead to compute the step by width*channel.But Of cause,if you perfer tosee the concecutive value inmemory, you caluse malloc() directly.
for example
Ipp8u*pad = (Ipp8u*)malloc(padSize.width * nChannels*padSize.height);
Then the step should be padSize.width * nChannels.
Considering the step, thereis another thing you may take care.
stepBytes, almost each ipp image processcing function requires the parameter.
It is the distance in bytes between lines.
As you know, image data is often 4-bytes aligned (i.e, bmp format file). So the distance between lines for such kind of image data is multiples of4, thus the stepBytesare not equal to width*sizeof(type)*channel in some case either.
So when you read 24bit bitmap image from file, it is better to use pSrc->Step() (show in ipp sample codeat <http://software.intel.com/en-us/articles/intel-integrated-performance-primitives-code-samples/>
instead of calculateimage_WIDTH*channel.
Best Regards,
Ying
Hello noemata,
I try your code. You may have noticed that there is different valuebetween
pad=ippiMalloc_8u_C1
and
step = padSize.width * nChannels
for example, in your case, for image pad, width=8+2*3=14,
the step returned by ippiMalloc is32
step= padSize.width*nChannnels is 14.
Then you havethecode
step = padSize.width * nChannels;
if (nChannels == 1)
{
status = ippiCopyReplicateBorder_8u_C1R(pSrc, srcSize.width * nChannels, srcSize, pad, step, padSize, nPad, nPad);
Itseems to work, but actually the copy result is not expected. (It will cause more potiential error, e.g your mentioned 24 bit doesn't work).
in detial, if you use ippiMalloc toallocate memory to pad, then the copy resultin padshould be
i.e the first twoline
003 003 003 003 003 003 003 003 008 008 008 008 008 008 then 000 000 000 000 000 000 000 000 ...
003 003 003 003 003 003 003 003 008 008 008 008 008 008 then 000 000 000 000 000 000 000 000
(As Vladmirmentioned,pad is 32-byte aligned, where every line is 32 bytes. The first 18 byte has copy value, the 18~32 should be padded with zeros. )
But if you change the step=14, thenthe real result in pad (first64 bytes)is
003 003 003 003 003 003 003 003 008 008 008 008 008 008 003 003 003 003 003 003 003 003 008 008 008 008 008 008 003 003 003 003 ....
become consecutive value.
So when you use ippiMalloc,you can use stepBytes directly instead to compute the step by width*channel.But Of cause,if you perfer tosee the concecutive value inmemory, you caluse malloc() directly.
for example
Ipp8u*pad = (Ipp8u*)malloc(padSize.width * nChannels*padSize.height);
Then the step should be padSize.width * nChannels.
Considering the step, thereis another thing you may take care.
stepBytes, almost each ipp image processcing function requires the parameter.
It is the distance in bytes between lines.
As you know, image data is often 4-bytes aligned (i.e, bmp format file). So the distance between lines for such kind of image data is multiples of4, thus the stepBytesare not equal to width*sizeof(type)*channel in some case either.
So when you read 24bit bitmap image from file, it is better to use pSrc->Step() (show in ipp sample codeat <http://software.intel.com/en-us/articles/intel-integrated-performance-primitives-code-samples/>
instead of calculateimage_WIDTH*channel.
Best Regards,
Ying
Makes perfect sense. The step/stride value was something I was looking for further guidance on. It would have been very helpful to have examples that used either OpengGL textures, DirectX textures or GDI+ bitmaps.
The examples in the docs often make reference to hand coded bitmap buffers that do not incorporate padding per scan line which confused the issue for me when I was trying tofit some of the documentation sample elements into test cases I was building for myself.
Initially I didn't have a failure check for this api: ippiResizeSqrPixelGetBufSize(...)
Which furtherconfused things because Iended up using the previouscalls buffer size as a result. It was a surprise to see this call fail for what should have been a valid interpolation mode.
That's the problem withsample codethatisn't production grade.Thoughit may make the example simpler understand, it can hide potentially critical considerations.I think it would be prudent to include a couple production grade examples in the IPP docs that usecomplimentary technologies such as OpenGL, DirectX and GDI+ (and perhaps Mac and Linux related tech).
The ippiDemo code sample is so layered that youcan't really see how you would need to be usea set of APIsin sequence. Nor does it directly demonstrate how border pixels need to be initialized for a target bitmap size. Yet it was the best example I could find.
My two cents worth.
I did read this section. The hand coded bitmaps lackingalignment considerationsdidn't help getting tothe followingline of code:
// Filter operation must start at upper left corner of first image pixel which is justpast the upperleft corner of the replicated border. Row addressing must acount for pixel row word/dword alignment. The row address must also account for individual pixel size (1C, 3C, A4C)when formulating the pixel row address value.
&pixelbuffer[nPaddingPixels *rowStepsize + (nPaddingPixels * nChannels)];
I did read this section. The hand coded bitmaps lackingalignment considerationsdidn't help getting tothe followingline of code:
// Filter operation must start at upper left corner of first image pixel which is justpast the upperleft corner of the replicated border. Row addressing must acount for pixel row word/dword alignment. The row address must also account for individual pixel size (1C, 3C, A4C)when formulating the pixel row address value.
&pixelbuffer[nPaddingPixels *rowStepsize + (nPaddingPixels * nChannels)];
For more complete information about compiler optimizations, see our Optimization Notice.