Fixed IPP crash problems. If only Intel provided something like this as an example. This covers many use cases (resize, filter, etc.). Would have saved me half a day of trial and error.

Fixed IPP crash problems. If only Intel provided something like this as an example. This covers many use cases (resize, filter, etc.). Would have saved me half a day of trial and error.

// Authored by: Mario Pintaric

// ippTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include
#include
#include

#pragma comment(lib, "gdiplus")

#include "ipp.h"

#pragma comment(lib, "ippcore.lib")
#pragma comment(lib, "ippi.lib")

using namespace Gdiplus;

class GdiplusInit
{
public:
GdiplusInit()
{
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
}
~GdiplusInit()
{
GdiplusShutdown(gdiplusToken);
}
protected:
private:
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
};

GdiplusInit InitGDIPlus;

int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array
// in bytes
Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;

Gdiplus::GetImageEncodersSize(&num, &size);
if(size == 0)
return -1;

pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1;

GetImageEncoders(num, size, pImageCodecInfo);

for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}

free(pImageCodecInfo);
return -1;
}

IppStatus GaussBmp(Ipp8u *pSrc, IppiSize srcSize, int nChannels, IppiMaskSize op)
{
Ipp8u *pad;
int nPad, step;
IppiSize padSize;
Ipp8u *pBorderOffset;
IppStatus status = ippStsNoMemErr;

// Set mask operation. Intel IPP docs do not provide an adequate explanation of border value condition handling.
// Overall, the docs are riddled with mistakes, poor grammar and incomplete explanations.
if ( op == ippMskSize3x3 )
{
nPad = 3;
}
else if ( op == ippMskSize5x5 )
{
nPad = 5; // Crashes when set to 5. Why???
}
else
return ippStsNotSupportedModeErr;

// Calculate padded and filtered bitmap sizes.
padSize.width = srcSize.width + (2 * nPad);
padSize.height = srcSize.height + (2 * nPad);

// Allocate padded bitmap that will contain replicated border of source bitmap and corresponding filter target bitmap.
if (nChannels == 1)
{
pad = ippiMalloc_8u_C1(padSize.width, padSize.height, &step);
}
else if (nChannels == 3)
{
pad = ippiMalloc_8u_C3(padSize.width, padSize.height, &step);
}
else if (nChannels == 4)
{
pad = ippiMalloc_8u_AC4(padSize.width, padSize.height, &step);
}
else
return ippStsNotSupportedModeErr;

if ( !pad )
goto Fault;

// Note: Intel IPP seems to incorrectly caclulate the step value!!! Why??? Especially bad for small bitmap sizes (< 10 bytes wide)
step = padSize.width * nChannels;

if (nChannels == 1)
{
status = ippiCopyReplicateBorder_8u_C1R(pSrc, srcSize.width * nChannels, srcSize, pad, step, padSize, nPad, nPad);
}
else if (nChannels == 3)
{
status = ippiCopyReplicateBorder_8u_C3R(pSrc, srcSize.width * nChannels, srcSize, pad, step, padSize, nPad, nPad);
}
else if (nChannels == 4)
{
status = ippiCopyReplicateBorder_8u_AC4R(pSrc, srcSize.width * nChannels, srcSize, pad, step, padSize, nPad, nPad);
}

if ( status )
goto Fault;

// The docs do not provide any clarity on the need to do this. None of the samples I've seen suggest this is required.
// Half a day blown because of poor documentation!
pBorderOffset = &pad[(padSize.width * nPad * nChannels) + (nPad * nChannels)];

if (nChannels == 1)
{
status = ippiFilterGauss_8u_C1R(pBorderOffset, step, pSrc, srcSize.width * nChannels, srcSize, op);
}
else if (nChannels == 3)
{
status = ippiFilterGauss_8u_C3R(pBorderOffset, step, pSrc, srcSize.width * nChannels, srcSize, op);
}
else if (nChannels == 4)
{
status = ippiFilterGauss_8u_AC4R(pBorderOffset, step, pSrc, srcSize.width * nChannels, srcSize, op);
}

if ( status )
goto Fault;

Fault:
if ( pad )
ippiFree(pad);

return status;
}

int _tmain(int argc, _TCHAR* argv[])
{
const IppLibraryVersion* ippVersion = ippiGetLibVersion();

printf("IPP: [ %s %s ]\n", ippVersion->Name, ippVersion->Version);

Bitmap inBmp(L"bg.bmp");

if ( inBmp.GetLastStatus() == Ok )
{
PixelFormat fmt = inBmp.GetPixelFormat();

if ( PixelFormat24bppRGB == fmt )
{
BitmapData InData, growData, shrinkData;

int growwidth = inBmp.GetWidth() * 4;
int growheight = inBmp.GetHeight() * 4;

int shrinkwidth = growwidth / 8;
int shrinkheight = growheight / 8;

Bitmap growBmp(growwidth, growheight, PixelFormat24bppRGB);
Bitmap shrinkBmp(shrinkwidth, shrinkheight, PixelFormat24bppRGB);

inBmp.LockBits(0, ImageLockModeRead, PixelFormat24bppRGB, &InData);
growBmp.LockBits(0, ImageLockModeWrite, PixelFormat24bppRGB, &growData);
shrinkBmp.LockBits(0, ImageLockModeWrite, PixelFormat24bppRGB, &shrinkData);

IppStatus status;
IppiSize inSize = { inBmp.GetWidth(), inBmp.GetHeight() };
IppiRect inRect = { 0, 0, inBmp.GetWidth(), inBmp.GetHeight() };
IppiSize shrinkSize = { shrinkwidth, shrinkheight };
IppiRect shrinkRect = { 0, 0, shrinkwidth, shrinkheight };
IppiSize growSize = { growwidth, growheight };
IppiRect growRect = { 0, 0, growwidth, growheight };

double xgrowFactor = growwidth / (double)inBmp.GetWidth();
double ygrowFactor = growheight / (double)inBmp.GetHeight();
double xshrinkFactor = shrinkwidth / (double)growwidth;
double yshrinkFactor = shrinkheight / (double)growheight;
double xShift = 0.0;
double yShift = 0.0;
int nChannel = 3;

int bufferSize = 0;
Ipp8u *pshrinkBuffer = NULL, *pgrowBuffer = NULL;

// IPPI_INTER_NN
// IPPI_INTER_LINEAR
// IPPI_INTER_CUBIC
// IPPI_INTER_CUBIC2P_BSPLINE
// IPPI_INTER_CUBIC2P_CATMULLROM
// IPPI_INTER_CUBIC2P_B05C03
// IPPI_INTER_SUPER
// IPPI_INTER_LANCZOS
int interpolation = IPPI_INTER_LANCZOS; // Is this the best IPP has to offer when downsampling?

// Note: docs imply IPPI_INTER_SUPER is supported by ippiResizeSqrPixel, but it is not???
status = ippiResizeSqrPixelGetBufSize(shrinkSize, nChannel, interpolation, &bufferSize);

if ( status )
goto Fault;

pshrinkBuffer = (Ipp8u *)ippMalloc(bufferSize);

if ( !pshrinkBuffer )
goto Fault;

status = ippiResizeSqrPixelGetBufSize(growSize, nChannel, interpolation, &bufferSize);

if ( status )
goto Fault;

pgrowBuffer = (Ipp8u *)ippMalloc(bufferSize);

if ( !pgrowBuffer )
goto Fault;

status = ippiResizeSqrPixel_8u_C3R((Ipp8u*)InData.Scan0, inSize, inBmp.GetWidth() * nChannel, inRect, (Ipp8u*)growData.Scan0, growwidth * nChannel, growRect, xgrowFactor, ygrowFactor, 0, 0, interpolation, pgrowBuffer);

if ( status )
goto Fault;

// Blur upscaled bitmap so that we downscale more smoothly.
status = GaussBmp((Ipp8u*)growData.Scan0, growSize, nChannel, ippMskSize5x5);

if ( status )
goto Fault;

// Blur some more ...
status = GaussBmp((Ipp8u*)growData.Scan0, growSize, nChannel, ippMskSize5x5);

if ( status )
goto Fault;

// Sadly, Photoshop does a way better job. To my eyes, it's at least twice as good.
// To equal its quality we need to pull a couple more tricks before getting to here.
status = ippiResizeSqrPixel_8u_C3R((Ipp8u*)growData.Scan0, growSize, growBmp.GetWidth() * nChannel, growRect, (Ipp8u*)shrinkData.Scan0, shrinkwidth * nChannel, shrinkRect, xshrinkFactor, yshrinkFactor, 0, 0, interpolation, pshrinkBuffer);

Fault:
if ( status == ippStsInterpolationErr )
printf("Invalid interpolation mode!\n");

if ( pshrinkBuffer )
ippFree(pshrinkBuffer);

if ( pgrowBuffer )
ippFree(pgrowBuffer);

inBmp.UnlockBits(&InData);
growBmp.UnlockBits(&growData);
shrinkBmp.UnlockBits(&shrinkData);

if ( status == ippStsNoErr )
{
CLSID clsidBMP;

GetEncoderClsid(L"image/bmp", &clsidBMP);

growBmp.Save(L"grow.bmp", &clsidBMP);
shrinkBmp.Save(L"shrink.bmp", &clsidBMP);
}
}
}

return 0;
}

24 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

That's good! BTW, sometime looking through function description before use may help to save time for trial and errors.

Anyway I'm glad you solve the issue

Regards,
Vladimir

Quoting - Vladimir Dudnik (Intel)
That's good! BTW, sometime looking through function description before use may help to save time for trial and errors.

Anyway I'm glad you solve the issue

Regards,
Vladimir

There are a number of issues highlighted by this code. IPP step size is incorrectly caclulated for small bitmap sizes. I'm not entirely sure why theincorrectly cacluated IPPvalue works for larger bitmaps, though the fix shown here seems to work in all cases.

The docs do not adequately explain border handling considerations.

Why is IPPI_INTER_SUPER not supported by the ippiResizeSqrPixelGetBufSize() function? You made reference to it in other posts as being one of the valid options.

Lastly, the provided Intel documentation needs an overhaul. I hate to say it Vladimir ... but the English languageis a second class citizen here. Since English is the language of discourse, I would expect nothing less than first caliber diction from those supporting this forum and writing the IPP documentation.

Well let's try to improve the things together. If you canrefer me to the specific examples of bad written phrases in documentation I will submit this as a bug report to product bug tracker. Of course you also may do thisthrough Intel Premier Support channel.

It is also not clear for me how do you conclude IPPI_INTER_SUPER does not work? Did you notice a code example in ippiman.pdf file on page 937 (I am referring to the documents available in Inel Compiler 11.1 beta).

While English is not my native language I hope engineers may understand each other in the most of cases. Although there are native english speaking persons who provide support on this forum.

Regarding step calculation I just provided comment in your another post. If you took attention to ippiMalloc description you may notice that this fuction do align memory buffer it allocates and so it returns step for this 2D memory buffer. Soyou have to use this instead of replacing it with your own value whichdoes not take into account actual aligment done at allocation.

What exactly document do you mean saying it does not adequately explain borders? I am still hoping chapter 2 "Inte IPP Concepts" of Image processing Manual (ippiman.pdf) is quite well in explanation of these basic things.

Vladimir

Quoting - Vladimir Dudnik (Intel)

Well let's try to improve the things together. If you canrefer me to the specific examples of bad written phrases in documentation I will submit this as a bug report to product bug tracker. Of course you also may do thisthrough Intel Premier Support channel.

It is also not clear for me how do you conclude IPPI_INTER_SUPER does not work? Did you notice a code example in ippiman.pdf file on page 937 (I am referring to the documents available in Inel Compiler 11.1 beta).

While English is not my native language I hope engineers may understand each other in the most of cases. Although there are native english speaking persons who provide support on this forum.

Regarding step calculation I just provided comment in your another post. If you took attention to ippiMalloc description you may notice that this fuction do align memory buffer it allocates and so it returns step for this 2D memory buffer. Soyou have to use this instead of replacing it with your own value whichdoes not take into account actual aligment done at allocation.

What exactly document do you mean saying it does not adequately explain borders? I am still hoping chapter 2 "Inte IPP Concepts" of Image processing Manual (ippiman.pdf) is quite well in explanation of these basic things.

Vladimir

I am making the assumption that your released product is complete in terms of the way it is documented; "beta" documentation references are out of scope for us given we are trying to produce a production grade solution based on your products.

The IPP generated step calculation, when fed back to IPP API's produces incorrect results for small bitmaps. It would also be helpful to have some guidance on mixingIPP data buffers with other libraries such as GDI+ and OpenGL textures.

I appreciate the intent Vladimir. It's all good. Just be thankful you don't have to read my French.

Well, I just made an assumption you use IPP 6.1 beta from Intel Parallel Composer beta.You may accessIPP 6.0producton the IPP Home page.

IPP generated step itself can't cause incorrect results regardless of image size. I'm sure the reason is some other mistake in IPP function use.

Did you take a look at IPP samples? We provide plenty of different applications in source code to demonstrate how to use IPP functions or how to build different media codecs based on IPP functions.

Regards,
Vladimir

Quoting - Vladimir Dudnik (Intel)

Well, I just made an assumption you use IPP 6.1 beta from Intel Parallel Composer beta.You may accessIPP 6.0producton the IPP Home page.

IPP generated step itself can't cause incorrect results regardless of image size. I'm sure the reason is some other mistake in IPP function use.

Did you take a look at IPP samples? We provide plenty of different applications in source code to demonstrate how to use IPP functions or how to build different media codecs based on IPP functions.

Regards,
Vladimir

Nope, Vladimir, this is definitely a bug in the IPP. It's really bad in v 6.0 (causing extremely strange bitmaps to be produced), but the strange thing is, it's not as bad in v 5.3 update 3. I've had to backtrack to the v 5.3 version of the ipp because of this bug.

I'm using sampling code that's coming from the ipp documentation; for instance:

bool CGenerate2xSubsample::Reduce_2D_Intel(eReductionType inWhichReduction,
Ipp32f *In, int NxIn, int NyIn,
Ipp32f *Out, int NxOut, int NyOut)
{
WriteMammoLogFileString("tttReduce 2d startedn");
IppiSize size = {NxIn,NyIn};
IppiRect srect = {0,0,NxIn,NyIn};
IppiRect drect = {0,0,NxOut,NyOut};
int bufsize;
Ipp8u* buf;
IppStatus status = ippStsNoErr;
/* calculation of work buffer size */
int theType = IPPI_INTER_NN;
switch (inWhichReduction){
case EReduceNearest:
theType = IPPI_INTER_NN;
break;
case EReduceLinear:
theType = IPPI_INTER_LINEAR;
break;
case EReduceCubic:
theType = IPPI_INTER_CUBIC;
break;
case EReduceLanczos:
theType = IPPI_INTER_LANCZOS;
break;
case EReduceCubicBSpline:
theType = IPPI_INTER_CUBIC2P_BSPLINE;
break;
case EReduceCubicCatMullrom:
theType = IPPI_INTER_CUBIC2P_CATMULLROM;
break;
case EReduceSuper:
theType = IPPI_INTER_SUPER;
break;
}
ippiResizeGetBufSize( srect, drect, 1, theType, &bufsize );
/* memory allocate */
buf = ippsMalloc_8u( bufsize );
if( NULL != buf )
status = ippiResizeSqrPixel_32f_C1R(
In, size, NxIn*sizeof(Ipp32f), srect,
Out, NxOut*sizeof(Ipp32f), drect,
((float)NxOut)/((float)NxIn), ((float)NyOut)/((float)NyIn),
0, 0, theType, buf );

/* memory free */
if( NULL != buf ) ippsFree( buf );
WriteMammoLogFileString("tttReduce 2d donen");

if (status == ippStsNoErr)
return true;
else return false;
}

That code, and the upsampling variation, fails catastrophically when the bitmap size gets to about 3 or lower on either side for a bitmap. In v 5.3, the resulting bitmap is definitely wrong, but it's not catastrophically wrong-- in v 6.0, the produced bitmap contains values that are in the negative 8 million range from a range of 0-65535. In fact, the exact same code in v 5.3 is relatively well behaved, but the code in v 6 causes serious machine-dependent stability problems as well.

I don't know if it's a problem in the documentation or not, but it seems that there's a general haziness about whether to use ippiMalloc_32f_C1 or ippsMalloc_32f for single channel data. For instance, if I use ippsMalloc_32f, then I just use the ippi functions by specifying the step size to be the number of columns * sizeof(type). I'm guessing that that assumption fails here?

Quoting - Mark Roden

Nope, Vladimir, this is definitely a bug in the IPP. It's really bad in v 6.0 (causing extremely strange bitmaps to be produced), but the strange thing is, it's not as bad in v 5.3 update 3. I've had to backtrack to the v 5.3 version of the ipp because of this bug.

I'm using sampling code that's coming from the ipp documentation; for instance:

bool CGenerate2xSubsample::Reduce_2D_Intel(eReductionType inWhichReduction,
Ipp32f *In, int NxIn, int NyIn,
Ipp32f *Out, int NxOut, int NyOut)
{
WriteMammoLogFileString("tttReduce 2d startedn");
IppiSize size = {NxIn,NyIn};
IppiRect srect = {0,0,NxIn,NyIn};
IppiRect drect = {0,0,NxOut,NyOut};
int bufsize;
Ipp8u* buf;
IppStatus status = ippStsNoErr;
/* calculation of work buffer size */
int theType = IPPI_INTER_NN;
switch (inWhichReduction){
case EReduceNearest:
theType = IPPI_INTER_NN;
break;
case EReduceLinear:
theType = IPPI_INTER_LINEAR;
break;
case EReduceCubic:
theType = IPPI_INTER_CUBIC;
break;
case EReduceLanczos:
theType = IPPI_INTER_LANCZOS;
break;
case EReduceCubicBSpline:
theType = IPPI_INTER_CUBIC2P_BSPLINE;
break;
case EReduceCubicCatMullrom:
theType = IPPI_INTER_CUBIC2P_CATMULLROM;
break;
case EReduceSuper:
theType = IPPI_INTER_SUPER;
break;
}
ippiResizeGetBufSize( srect, drect, 1, theType, &bufsize );
/* memory allocate */
buf = ippsMalloc_8u( bufsize );
if( NULL != buf )
status = ippiResizeSqrPixel_32f_C1R(
In, size, NxIn*sizeof(Ipp32f), srect,
Out, NxOut*sizeof(Ipp32f), drect,
((float)NxOut)/((float)NxIn), ((float)NyOut)/((float)NyIn),
0, 0, theType, buf );

/* memory free */
if( NULL != buf ) ippsFree( buf );
WriteMammoLogFileString("tttReduce 2d donen");

if (status == ippStsNoErr)
return true;
else return false;
}

That code, and the upsampling variation, fails catastrophically when the bitmap size gets to about 3 or lower on either side for a bitmap. In v 5.3, the resulting bitmap is definitely wrong, but it's not catastrophically wrong-- in v 6.0, the produced bitmap contains values that are in the negative 8 million range from a range of 0-65535. In fact, the exact same code in v 5.3 is relatively well behaved, but the code in v 6 causes serious machine-dependent stability problems as well.

I don't know if it's a problem in the documentation or not, but it seems that there's a general haziness about whether to use ippiMalloc_32f_C1 or ippsMalloc_32f for single channel data. For instance, if I use ippsMalloc_32f, then I just use the ippi functions by specifying the step size to be the number of columns * sizeof(type). I'm guessing that that assumption fails here?

The issue as identified in my code sample and a previous one I posted that operates on a smallish bitmap is the step value calculaton made by IPP. If you substitute the correct value rather than the one calculated by the IPP malloc functions, the other API's perform as expected. There are even instances where IPP will crash your app if you use its step value calculations. At some point Vladamir will eventually listen, I'm sure of that.

Some of the underlying tech of IPPis VERY good indeed. That's why we're using it. I've decided to look at the obfuscations of the IPP docs and the failings of some of the APIsas a good thing. It will prevent many from doing anything useful with the API thus giving the few that get past it an advantage.

The issue is not in calculation of step in IPP. The problem is that you ignore actual data layout in your code and assume there is no padding in bitmap data you obtain through Windows API.

Vladimir

To whom it may concern,

This discussion alsowas recorded to IPP KB. Please see
http://software.intel.com/en-us/articles/resize-function-ippiresizesqrpixel-crashed-for-small-image/ and it includes one ippiResizeSqrPixelC sample code.

Best Regards,
Ying

Quoting - Vladimir Dudnik (Intel)

The issue is not in calculation of step in IPP. The problem is that you ignore actual data layout in your code and assume there is no padding in bitmap data you obtain through Windows API.

Vladimir

yes-- because I'm not using a bitmap, I'm using an array of floats that I've declared not to have any padding on them. So, I'm right to make the assumption, because I know exactly how my memory is declared.

Guess I'll just have to override the given function with one that works for small arrays.

Hello,

regardless of what you are going to override you have to use IPP function with correct and valid parameters. In case of correct usage IPP functions will work with array of any size.

Regards,
Vladimir

Quoting - Vladimir Dudnik (Intel)
Hello,

regardless of what you are going to override you have to use IPP function with correct and valid parameters. In case of correct usage IPP functions will work with array of any size.

Regards,
Vladimir

So, what was incorrect in my usage? If I have an image with smaller than 4 pixels on an edge, the above function and it's sister to go in the opposite direction produce bogus and random results. I'd really like to get those working...

I thought I provided corrected sample. Do you find any issues with this code (archive resize.zip)?

Regards,
Vladimir

Attachments: 

AttachmentSize
Downloadapplication/zip resize.zip49.22 KB

Quoting - Vladimir Dudnik (Intel)
I thought I provided corrected sample. Do you find any issues with this code (archive resize.zip)?

Regards,
Vladimir

Yeah, that sample doesn't help.

Make some code with some floats, say a 10x10, and then shrink it gradually to 1x1. Watch the random values that appear if you try to grow back up to 10x10 from, say, 2x4. But it must be in float space! I don't care about ipp8u images.

Hi Mark,

Very thanks for an example. Yes, really, we had an error :(
It will be corrected in following release.
Now I recommend to you the workaround - to change interpolation type to increase very small source images:

if (size.NxIn < 6 || size.NyIn < 6) {
if (theType == IPPI_INTER_LANCZOS)
theType = IPPI_INTER_CUBIC;
if (size.NxIn < 4 || size.NyIn < 4) {
if ((theType == IPPI_INTER_CUBIC) ||
(theType == IPPI_INTER_CUBIC2P_BSPLINE) ||
(theType == IPPI_INTER_CUBIC2P_CATMULLROM) ||
(theType == IPPI_INTER_CUBIC2P_B05C03))
theType = IPPI_INTER_LINEAR;
}
}

I think that it's quite correct for such small sizes.

Thanks,
Yuri

Hi Yuri,

Thanks much for looking into this, and I'm looking forward to the fix.

Linear will probably be fine; I'd think that it would make a difference to have the different styles on the smaller sizes of the pyramids.

(incidentally, what about having a templateable pyramid, instead of one that's ipp8u? That way I could just use the ipp32f version for the images I need)

Thanks again!
Mark

Quoting - Yuri Tikhomirov (Intel)

Hi Mark,

Very thanks for an example. Yes, really, we had an error :(
It will be corrected in following release.
Now I recommend to you the workaround - to change interpolation type to increase very small source images:

if (size.NxIn < 6 || size.NyIn < 6) {
if (theType == IPPI_INTER_LANCZOS)
theType = IPPI_INTER_CUBIC;
if (size.NxIn < 4 || size.NyIn < 4) {
if ((theType == IPPI_INTER_CUBIC) ||
(theType == IPPI_INTER_CUBIC2P_BSPLINE) ||
(theType == IPPI_INTER_CUBIC2P_CATMULLROM) ||
(theType == IPPI_INTER_CUBIC2P_B05C03))
theType = IPPI_INTER_LINEAR;
}
}

I think that it's quite correct for such small sizes.

Thanks,
Yuri

Hi Mark,

you probably may try ippiPyramidLayerDown/Up functions from ipp computer vision library (ippcv). These functions support Ipp32f data type

Regards,
Vladimir

Quoting - Vladimir Dudnik (Intel)
Hi Mark,

you probably may try ippiPyramidLayerDown/Up functions from ipp computer vision library (ippcv). These functions support Ipp32f data type

Regards,
Vladimir

Hi Vladimir,

After rereading the documentation, I see what you're saying. Specifically, looking at example 14-6 in the ippi documentation has an example with float-space pyramids. There appears to be some hackeration to get the structure to fit into the IppiPyramid structure, which itself has a pointer to the Ipp8u type but not the Ipp32f type. Definitely doable, but certainly not clean. I'll take a look at it, but if those functions just end up calling the interpolation code (and why wouldn't they? Unless there's repetitive code in here...), then they'll probably have the same problems.

Mark

Quoting - Yuri Tikhomirov (Intel)

Hi Mark,

Very thanks for an example. Yes, really, we had an error :(
It will be corrected in following release.
Now I recommend to you the workaround - to change interpolation type to increase very small source images:

if (size.NxIn < 6 || size.NyIn < 6) {
if (theType == IPPI_INTER_LANCZOS)
theType = IPPI_INTER_CUBIC;
if (size.NxIn < 4 || size.NyIn < 4) {
if ((theType == IPPI_INTER_CUBIC) ||
(theType == IPPI_INTER_CUBIC2P_BSPLINE) ||
(theType == IPPI_INTER_CUBIC2P_CATMULLROM) ||
(theType == IPPI_INTER_CUBIC2P_B05C03))
theType = IPPI_INTER_LINEAR;
}
}

I think that it's quite correct for such small sizes.

Thanks,
Yuri

An udpate about this bug: it was fixed in the IPP 6.1 update 2 release.

Some examples of marginal English from IPP manual- just a few of many - FYI

/* Query how big can be max output bitstream */
/* Learn how many memory block needed for the decoder */
/* Query how big has to be each block */

Thanks for report, do you mean IPP manual or UMC/UIC manual?

Regards,
Vladimir

Quoting - Vladimir Dudnik (Intel)
Thanks for report, do you mean IPP manual or UMC/UIC manual?

Regards,
Vladimir

This one...
Intel Integrated Performance
Primitives for Intel Architecture
Unified Speech Component Interface

Basically one who speaks native english "can get it" but I think, as others seem to, that Intel should make these issues go away. For those OTHER ESL (English is a Second Language) folks, reading this may not quite get the meaning if the English is distorted.

Yeah, thanks, we will correct these mistakes

Regards,
Vladimir

Leave a Comment

Please sign in to add a comment. Not a member? Join today