- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
First, I understand that IPP tries to reduce bloat by excluding some rare staff and functions that can be easily implemented using the existing ones. And I see it as a positive thing. However, I believe that it should support conversions from otherwise unsupported formats to a workable form, so that when I encounter such format I could still efficiently convert and use IPP.
Now, one such thing is a conversion from 2-channel interleaved images to 2-channel planar (and vice versa). Such 2-channel images are sometimes used (for example for grayscale + alpha as in PNG), and are supported by other libraries (like OpenGL). IPP lacks ippiCopy_*_C2P2R and ippiCopy_*_P2C2R functions, and I couldn't find a way to bake them using other functions other than invoking ippiTranspose_*_C1R on each row.
Thank you in advance,
Yakov Galka
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Yakov,
for 16s,32f & 64f data you can use ipps functions with row-by-row access:
/* /////////////////////////////////////////////////////////////////////////////
// Name: ippsCplxToReal
// Purpose: form the real and imaginary parts of the input complex vector
// Parameters:
// pSrc pointer to the input complex vector
// pDstRe pointer to output vector to store the real part
// pDstIm pointer to output vector to store the imaginary part
// len length of the vectors, number of items
// Return:
// ippStsNullPtrErr pointer(s) to the data is NULL
// ippStsSizeErr length of the vectors is less or equal zero
// ippStsNoErr otherwise
*/
IPPAPI(IppStatus, ippsCplxToReal_64fc,( const Ipp64fc* pSrc, Ipp64f* pDstRe,
Ipp64f* pDstIm, int len ))
IPPAPI(IppStatus, ippsCplxToReal_32fc,( const Ipp32fc* pSrc, Ipp32f* pDstRe,
Ipp32f* pDstIm, int len ))
IPPAPI(IppStatus, ippsCplxToReal_16sc,( const Ipp16sc* pSrc, Ipp16s* pDstRe,
Ipp16s* pDstIm, int len ))
/* /////////////////////////////////////////////////////////////////////////////
// Name: ippsRealToCplx
// Purpose: form complex vector from the real and imaginary components
// Parameters:
// pSrcRe pointer to the input vector with real part, may be NULL
// pSrcIm pointer to the input vector with imaginary part, may be NULL
// pDst pointer to the output complex vector
// len length of the vectors
// Return:
// ippStsNullPtrErr pointer to the destination data is NULL
// ippStsSizeErr length of the vectors is less or equal zero
// ippStsNoErr otherwise
//
// Notes: one of the two input pointers may be NULL. In this case
// the corresponding values of the output complex elements is 0
*/
IPPAPI(IppStatus, ippsRealToCplx_64f,( const Ipp64f* pSrcRe,
const Ipp64f* pSrcIm, Ipp64fc* pDst, int len ))
IPPAPI(IppStatus, ippsRealToCplx_32f,( const Ipp32f* pSrcRe,
const Ipp32f* pSrcIm, Ipp32fc* pDst, int len ))
IPPAPI(IppStatus, ippsRealToCplx_16s,( const Ipp16s* pSrcRe,
const Ipp16s* pSrcIm, Ipp16sc* pDst, int len ))
also it's not clear which format and data type you are going to convert - there are available for example the next conversions:
IPPAPI(IppStatus, ippiYCbCr422ToYCbCr420_8u_C2P2R,( const Ipp8u* pSrc, int srcStep, Ipp8u* pDstY, int dstYStep,Ipp8u* pDstCbCr,int dstCbCrStep, IppiSize roiSize ))
IPPAPI(IppStatus, ippiCbYCr422ToYCbCr420_8u_C2P2R,( const Ipp8u* pSrc, int srcStep, Ipp8u* pDstY, int dstYStep,Ipp8u* pDstCbCr,int dstCbCrStep, IppiSize roiSize ))
IPPAPI(IppStatus, ippiYCbCr420ToYCbCr422_8u_P2C2R,(const Ipp8u* pSrcY, int srcYStep,const Ipp8u* pSrcCbCr,
int srcCbCrStep, Ipp8u* pDst, int dstStep, IppiSize roiSize))
IPPAPI(IppStatus, ippiYCbCr420ToYCbCr422_Filter_8u_P2C2R,(const Ipp8u* pSrcY, int srcYStep,const Ipp8u* pSrcCbCr,
int srcCbCrStep, Ipp8u* pDst, int dstStep, IppiSize roiSize,int layout))
and some other...
regards, Igor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Igor,
Thank you for the CplxToReal/RealToCplx tip. It will indeed work for the 2, 4, and 8 byte types.
Yet, we do use images of 8-bit (most frequently), 16-bit (less frequently) and 32-bit (not for this specific conversion, but we are likely to do this in the future) data types.
Unfortunately the YCbCr422ToYCbCr420/YCbCr420ToYCbCr422 family you propose do a downscaling/upscaling in the vertical direction, which makes them inappropriate for the conversion I need. For example,
static const int w = 4, h = 4;
uint8_t src[w*h*2];
for(int i = 0; i < w*h*2; ++i)
src = i;
uint8_t dest1[w*h], dest2[w*h];
memset(dest1, 0xff, sizeof(dest1));
memset(dest2, 0xff, sizeof(dest2));
IppiSize roi = { w, h };
ippiYCbCr422ToYCbCr420_8u_C2P2R(src, w*2, dest1, w, dest2, w, roi);
The contents of dest1 is, correctly,
00 02 04 06
08 0A 0C 0E
10 12 14 16
18 1A 1C 1E
whereas the contents of dest2 is
01 03 05 07
11 13 15 17
FF FF FF FF
FF FF FF FF
or
01 03 05 07
FF FF FF FF
11 13 15 17
FF FF FF FF
if I double the third stride.
Thanks,
Yakov
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Yakov,
ok, I see, so currently you don't have an appropriate workaround for C2P2 & P2C2 for 8u. We'll consider this feature request for one of the future releases.
regards, Igor
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page