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

ipp 2017 update 2 Histogram buffer size issue

Stella_Y_
Beginner
1,106 Views

I've encountered a  problem of calculating the image histogram when using the latest ipp static library(2017 update 2)

The issue happened when I call the ippiHistogramGetBufferSize function.I needed to calculate the buffer size before doing histogram for single-float type image, but this function return  0 in sizeBuffer . Then it will crash my histogram calculating code. I doubted it was the potential bug for this function.

const int WIDTH = 5;
const int HEIGHT = 5;
const int nbins =5;
int nLevels [] = {nbins +1};
ippiSize roi = {WIDTH,HEIGHT};
int sizeHistObj,sizeBuffer;

ippiHistogramGetBufferSize(ipp32f, roi, nLevels, 1, 1, &sizeHistObj,&sizeBuffer);

I've tired ipp8u,ipp16u,ipp16s type, they were ok, although return a big memeory size refer to ipp16u or ipp16s. 

Please somebody come to help .
 

 

0 Kudos
1 Solution
Igor_A_Intel
Employee
1,106 Views

Hi Stella,

1) you don't analyze status code after IPP function execution - with your code it indicates "wrong step"

2) you've forgotten that step is in bytes - therefore you should multiply it by sizeof( float )

below is a bit corrected code:

#include <stdio.h>
#include "ipp.h"
 
#define nBins 5
 
int main(){
    int w;
    float *hh1;
    const int HEIGHT = 5;
    const int WIDTH = 6;
    IppiSize roi = {WIDTH, HEIGHT};
    IppStatus sts;
    int nLevels[] = { nBins+1 };
    Ipp32f lowerLevel[] = {0};
    Ipp32f upperLevel[] = {255};
    int sizeHistObj;
    int sizeBuffer;
    IppiHistogramSpec* pHistObj;
    Ipp8u* pBuffer;
    Ipp32u pHistVec[nBins];
 
 /* fill the data */
 
//    ippInit(); /* rudiment, exists for compatibility with "old" IPP versions */
    hh1 = (float*)ippsMalloc_32f( HEIGHT * WIDTH );
 
    for( w = 0; w < HEIGHT * WIDTH; w++ ){
        hh1 = (float)3.5 * w;
    }
 
//get sizes for spec and buffer
    ippiHistogramGetBufferSize( ipp32f, roi, nLevels, 1/*nChan*/, 1/*uniform*/, &sizeHistObj, &sizeBuffer );
    pHistObj = (IppiHistogramSpec*)ippsMalloc_8u( sizeHistObj );
    pBuffer = ippsMalloc_8u( sizeBuffer );
 
//initialize spec
    ippiHistogramUniformInit( ipp32f, lowerLevel, upperLevel, nLevels, 1, pHistObj );
 
// calculate histogram
    sts = ippiHistogram_32f_C1R( hh1, WIDTH * sizeof( Ipp32f ), roi, pHistVec, pHistObj, pBuffer );
    if( ippStsNoErr != sts ){
        printf( "%s\n", ippGetStatusString( sts ));
        return( -1 );
    }
    for( w = 0; w < nBins; w++ ){
        printf("bin = %d contains %d values\n", w, pHistVec );
    }
    ippsFree( hh1 );
    ippsFree( pHistObj );
    ippsFree( pBuffer );
 
    return 0;
 }
 

it works correctly:

bin = 0 contains 15 values
bin = 1 contains 15 values
bin = 2 contains 0 values
bin = 3 contains 0 values
bin = 4 contains 0 values
Press any key to continue . . .

regards, Igor 

View solution in original post

0 Kudos
5 Replies
Igor_A_Intel
Employee
1,106 Views

Hi Stella,

how the bufferSize==0 can crash you code? Could you be more specific and/or provide a reproducer? The size of buffer equal to zero means that this function doesn't need any intermediate buffer for histogram calculation, nothing more.

regards, Igor

0 Kudos
Stella_Y_
Beginner
1,106 Views

Thanks Igor, Now I understand the bufferSize==0 is normal behavior. But I can't run the histogram calculation in my program after the initialization. Below is my code:

/* fill the data */ 
ippInit(); 

float* hh1 = (float*)malloc( 5 * 6 * sizeof(float) );

for(w =0;w<30;w++) 

     hh1 = (float)3.5*w; 

const int HEIGHT = 5; 

const int WIDTH = 6;

IppiSize roi = {WIDTH, HEIGHT}; 

IppStatus sts; 

{ const int nBins = 5;

 int nLevels[] = { nBins+1 }; 

 Ipp32f lowerLevel[] = {0}; 

 Ipp32f upperLevel[] = {255}; 
 int sizeHistObj; 
 int sizeBuffer; 
 IppiHistogramSpec* pHistObj; 
 Ipp8u* pBuffer; 
 Ipp32u pHistVec[nBins]; 

 //get sizes for spec and buffer 
 ippiHistogramGetBufferSize(ipp32f, roi, nLevels, 1/*nChan*/, 1/*uniform*/, &sizeHistObj,&sizeBuffer); 

pHistObj = (IppiHistogramSpec*)ippsMalloc_8u( sizeHistObj ); 

pBuffer = ippsMalloc_8u( sizeBuffer ); 

//initialize spec 
ippiHistogramUniformInit( ipp32f, lowerLevel, upperLevel, nLevels, 1, pHistObj ); 

// calculate histogram 
sts = ippiHistogram_32f_C1R( hh1, WIDTH, roi, pHistVec, pHistObj, pBuffer ); 

ippsFree( pHistObj ); 
ippsFree( pBuffer );

 for(i = 0;i<nBins;i++)  
     printf(" %u \n",++*pHistVec);
}

So when I print out the bin value of the histogram, it turns out the wrong number which even greater than the total number of the array.

0 Kudos
Jing_Xu
Employee
1,106 Views

I tested your code, didn't find any problem.

How did you compile the code? Please try to use the following command to build the code.

gcc test.c -o test -I<IPP_INCLUDE_PATH> <IPP_LIB_PATH>/libippi.a <IPP_LIB_PATH>/libipps.a <IPP_LIB_PATH>/libippcore.a

B.t.w., you don't need to call ippInit() anymore. It will be called automatically.

0 Kudos
Igor_A_Intel
Employee
1,107 Views

Hi Stella,

1) you don't analyze status code after IPP function execution - with your code it indicates "wrong step"

2) you've forgotten that step is in bytes - therefore you should multiply it by sizeof( float )

below is a bit corrected code:

#include <stdio.h>
#include "ipp.h"
 
#define nBins 5
 
int main(){
    int w;
    float *hh1;
    const int HEIGHT = 5;
    const int WIDTH = 6;
    IppiSize roi = {WIDTH, HEIGHT};
    IppStatus sts;
    int nLevels[] = { nBins+1 };
    Ipp32f lowerLevel[] = {0};
    Ipp32f upperLevel[] = {255};
    int sizeHistObj;
    int sizeBuffer;
    IppiHistogramSpec* pHistObj;
    Ipp8u* pBuffer;
    Ipp32u pHistVec[nBins];
 
 /* fill the data */
 
//    ippInit(); /* rudiment, exists for compatibility with "old" IPP versions */
    hh1 = (float*)ippsMalloc_32f( HEIGHT * WIDTH );
 
    for( w = 0; w < HEIGHT * WIDTH; w++ ){
        hh1 = (float)3.5 * w;
    }
 
//get sizes for spec and buffer
    ippiHistogramGetBufferSize( ipp32f, roi, nLevels, 1/*nChan*/, 1/*uniform*/, &sizeHistObj, &sizeBuffer );
    pHistObj = (IppiHistogramSpec*)ippsMalloc_8u( sizeHistObj );
    pBuffer = ippsMalloc_8u( sizeBuffer );
 
//initialize spec
    ippiHistogramUniformInit( ipp32f, lowerLevel, upperLevel, nLevels, 1, pHistObj );
 
// calculate histogram
    sts = ippiHistogram_32f_C1R( hh1, WIDTH * sizeof( Ipp32f ), roi, pHistVec, pHistObj, pBuffer );
    if( ippStsNoErr != sts ){
        printf( "%s\n", ippGetStatusString( sts ));
        return( -1 );
    }
    for( w = 0; w < nBins; w++ ){
        printf("bin = %d contains %d values\n", w, pHistVec );
    }
    ippsFree( hh1 );
    ippsFree( pHistObj );
    ippsFree( pBuffer );
 
    return 0;
 }
 

it works correctly:

bin = 0 contains 15 values
bin = 1 contains 15 values
bin = 2 contains 0 values
bin = 3 contains 0 values
bin = 4 contains 0 values
Press any key to continue . . .

regards, Igor 

0 Kudos
Stella_Y_
Beginner
1,106 Views

Great Thanks, Igor and Jing.

Now I find out the root cause of the program failure, in the ippiHistogram_<mod> function the srcStep parameter should be set in byte. when I modified the code as Igor suggested, the program ran correctly then.

regards,

Stella

0 Kudos
Reply