Intel® Integrated Performance Primitives
Community support and discussions relating to developing high-performance vision, signal, security, and storage applications.
This community is designed for sharing of public information. Please do not share Intel or third-party confidential information here.
6628 Discussions

ippiConvert_1u8u_C1R exists, what about ippiConvert_1u8u_C3R?

Valued Contributor I
If I wanted to convert 1-bit bi-tonal image to 24-bit RGB image I would have to:

1. Allocate intermediate 8-bit image buffer.

2. Call ippiConvert_1u8u_C1R() to get 8-bit bi-tonal image with pixel values 0x00 and 0xFF.

3. Allocate final 24-bit image buffer.

4. Call ippiSet_8u_C3R() to set background color in the buffer.

5. Call ippiSet_8u_C3MR() to set foreground color using 8-bit grayscale image as a mask assuming the mask is single-channel.

If the mask isn't single-channel (which again, is not documented!), then I would also need two additional steps:

3a. Allocate 24-bit mask buffer.
3b. Call ippiDup_8u_C1C3R() to replicate 8-bit mask to all three channels of 24-bit mask buffer.

That makes this seemingly simple operation rather complex with anywhere between 5 and 7 steps and it also makes me use 2.33 times more memory than it should be needed to perform the conversion.

It would be better if there was a direct conversion -- ippiConvert_1u8u_C3R() where you can specify background and foreground colors as parameters.


0 Kudos
8 Replies
New Contributor I
>>If the mask isn't single-channel (which again, is not documented!)

If the mask would be multi channel, the ippiSet function had to be renamed to ippiSet_8u_C3M3R
But that isn't the case, so the mask IS single channel

>>That makes this seemingly simple operation rather complex
A mask operation never is simple for a processor. It's just that "simple" in case of a human brain

You heard the sentence: "Small code isn't the same as fast code" - so if you want it fast you sometimes need much much more code - you must decide whether it's worth is
Valued Contributor I
>>If the mask would be multi channel, the ippiSet function had to be renamed to ippiSet_8u_C3M3R

What is the purpose of documentation if I have to rely on function name to figure that out?

>>A mask operation never is simple for a processor.

You misunderstood me -- when I said "rather complex" I was refering to the whole conversion process, not just masking. Try reading that sentence in the proper context.

I see this as a feedback rather than an issue. Just to be fair, IPP leverages on the intel processor giving out applications very much boosting in performance, which i don't see it as an ease to my coding. Wel, fair enough, it would be extra points if less coding is needed.
For example, the DFT, FFT, houghlines operations in ippi, the gave my applications up to 300% betterperformance, but i need to write like 20 lines more code. I guess anyone would know how to balance this. For DFT operations, i only need to input the image and some settings params for OpenCV cv::dft, whereas i need to init, alloc dft, free, deinit for IPP's dft. Butgaugingon the performance boost IPP is giving, of course i would use it rather than OpenCV.
Another example i'm am facing. There's no API in ippi that does exp for an image (complex data, z = a + bj). I have to use the vector one, ipps_exp_32fc for every row.
Its nice of you to share with intel your feedback. Maybe forfuturerelease they would add in additional APIs.
Valued Contributor I
Of course it is feedback, I would submit it to Premier Support if it was an issue :)

With that out of the way, I don't mind writing 20 lines of code myself, but I have a problem when those 20 lines make my code use more intermediate buffers and memory for no good reason.

Recently I submitted problem report for md5 function (the one which computes checksum in one go) -- it was giving wrong results for files larger than 256 MB in size. I believe that was fixed, but still the function interface was designed poorly -- it cannot accept 64-bit block length thus preventing you to use it to calculate checksum on a memory-mapped file larger than 4GB.

The excuse I was given is that the IPP API is still 32-bit (as if it would be a problem to use LARGE_INTEGER or similar structure and pass a pointer), and that I can accomplish the same using three or four other md5 functions. As I said I don't mind additional coding, but in that particular case, I would really like to be calculate md5 with one function call using the paging facilities of the OS without having to process multi-gigabyte files block by block and without messing with ugly pointer arithmetics.

It is great to have fine control and low-level APIs, but it would also be nice to have simple alternatives for the most common tasks for those who don't have time for, or simply don't need so much detail.
Hi all,

that is an interesting question on 64-bit IPP API. We actually really consider the importance of that, in what functional areas it does make sense, what is the industry trend on this and so on. So your feedback is really important and useful to know.

We also think on how to make the use of IPP easier andconsider possibilities to create C++ framework on top of IPP, so would like to know your opinion on that subject.

Valued Contributor I

Regarding 64-bit API -- I consider it mandatory for all functions that can operate on large datasets. An example would be checksum and encryption/decryption APIs. Why would I need to load 8 GB ISO file block by block and process it using several functions when I could do it with one function call? Of course, such a function should have a callback mechanism to enable progress indication and cancelation.

Furthermore, all APIs that could potentially work with files should accept 64-bit filesizes. Files won't get smaller in the future, only larger.

Finally, PLEASE DON'T create C++ framework for IPP.

It would be an additional level of abstraction, it would prevent people using other languages (C, assembler, whatever) to reap the benefits of simpler interface and I sincerely doubt it would make IPP usage any simpler.

In my opinion, what you should do is take a few "primitives" that are often used together, and create a new function which does the same as the combination of those primitives, but faster and without using extra memory for intermediate buffers.

That is the only thing that would be beneficial -- it would simplify common tasks for those who don't need fine-grained control, and also offer better performance with lower memory footprint.
Hello Igor,

If we were to add a C++ framework it would be in addition to not instead of the low-level primitives. In other words, it would be a framework on top of C-based IPP primitives, providing a cleaner interface to those who prefer to work in the C++ environment, but not removing the ability to work with the low-level C language primitives.

Valued Contributor I

I understand that it wouldn't replace low level primitives. However:

1. Judging by the UIC interface, I am afraid that IPP C++ interface won't actually be cleaner.

2. Providing a wrapper for low-level functions is not beneficial -- every C++ developer can write such a wrapper on their own, and it would probably suit their needs better if they developed it for themselves.

What we cannot write (easily) is a NEW higher-level API which would combine functionality of several low-level primitives.

True, you could do that with a C++ wrapper but that wouldn't improve performance, only ease of use (if done right).

However, if you combined several low-level primitives which are often used together into a new API call by eliminating intermediate steps, that would improve both ease of use and performance without adding yet another useless abstraction layer.

People are so keen to use C++ nowadays, but they usually don't understand that C++ is not about having cleaner interface (by means of hiding implementation ugliness), and about having the ability to specify forgotten variables in the middle of the code.

If you don't need (or know how to properly use) inheritance, polymorphism, if you can't provide orthogonality in your class interface, if the code using your C++ classes looks like a pirate release title (i.e. The.Definitive.Guide.To.Windows.Server.2003), and if you don't reuse portions of your code but instead you copy/paste and modify, chances are that your code isn't a very good candidate for C++ -- you should better stick with plain C and save everyone some headache.

I cringe when I see code like this:
[cpp]imageCn.ColorSpec().DataRange().SetAsRange16u(1 << colorSpec.DataRange()->BitDepth());[/cpp]
In my personal opinion that is an abuse of the C++ language. If that is your idea of a cleaner interface then please, for the love of God, don't do it with the IPP as well.

It's a waste of resources which would be better used anywhere else, such as in augmenting the very poor documentation, or correcting existing API design mistakes such as the lack of 64-bit support, or functions that receive more than 4 parameters directly instead of receiving a pointer to a structure.