Patrick Fuentes Patrick Fuentes - 27 days ago 7
Linux Question

Casting issue in C++ Eclipse (Linux-Mint12)

I am trying to parallelize a program (written in sequential code) to increase its performance (speedup). As a whole, the program performs image processing by zooming into images. To do so, it employs bicubic interpolation (takes into account the mean of the 16 surrounding pixels to compute a single pixel value). The following code performs said function, but I am trying to make it work with 16 pixels at a time (making it work with matrixes and vectors instead of vectors and unsigned chars), which will allow me to introduce SSE later on.

Getting back to the matter at hand, the error in my code shows up when I perform the following operation:

color[c]=bicubicInterpolate_paralelo(arr, auxx, auxy);


The operation equals the row of a 3x16 matrix (color[c]) to a 16 element vector (valorPixelCanal -> seen later in my code) returned by the function bicubicInterpolate_paralelo. It produces the following error:


CImg-1.5.2/CImg.h:27491:46: error: cast from ‘const unsigned char*’ to
‘unsigned char’ loses precision [-fpermissive]


I have tried casting in the following manner:

color[c] = <reinterpret_cast(const char*)>(bicubicInterpolate_paralelo(arr, auxx, auxy))


However, it did not solve my problem. If any of you can give me a hand with this I would sincerely appreciate it; my code is provided below, if you have any questions as to how other parts of it work I will gladly answer them. Thank you in advance!

void cubicInterpolate_paralelo(unsigned char p[64]/*4*/, unsigned char x[16]/*1*/, unsigned char* arr) {

for (int ii=0; ii<16; ii++)
{
arr[ii] = p[1+(4*ii)] + 0.5 * x[ii] *(p[2+(4*ii)] - p[0+(4*ii)] + x[ii]*(2.0*p[0+(4*ii)] - 5.0*p[1+(4*ii)] + 4.0*p[2+(4*ii)] - p[3+(4*ii)] + x[ii]*(3.0*(p[1+(4*ii)] - p[2+(4*ii)]) + p[3+(4*ii)] - p[0+(4*ii)])));
}
}

unsigned char* bicubicInterpolate_paralelo (unsigned char p[64][64]/*4,4*/, unsigned char x[16]/*1*/, unsigned char y[16]/*1*/) {
unsigned char arr[64][16], valorPixelCanal[16];
int ii, kk, jj, ss;
int counter = 0;
unsigned char aar[16][64];

for(ii=0; ii<64; ii++) {
cubicInterpolate_paralelo(p[ii], y, arr[ii]);
}

for (jj=0; jj<16; jj++)
{
for (ss=0; ss<16; ss++)
{
aar[jj][counter] = arr[0][ss];
aar[jj][counter+1] = arr[1][ss];
aar[jj][counter+2] = arr[2][ss];
aar[jj][counter+3] = arr[3][ss];
counter = counter + 4;
}
}

for(kk=0; kk<16; kk++) {
cubicInterpolate_paralelo(aar[kk], x, valorPixelCanal);
}
return valorPixelCanal;
}

CImg<unsigned char> zoom_paralelo (CImg<unsigned char> img, int zFactor) {
int i, j, k, l, c, jj;
unsigned char arr[64][64];
unsigned char color[3][16];
unsigned char auxx[16],auxy[16];

CImg<unsigned char> z_img( zFactor*(img.width()-2)-zFactor+1, zFactor*(img.height()-1)-zFactor+1, 1, 3, 0 );


#pragma omp parallel for schedule(guided, 4) num_threads(4) private(arr, c, l, k, i, j) lastprivate(color) firstprivate(zFactor) // øNecesita collapse?

for(i=0; i<z_img.width(); i++) {


for(j=0; j<z_img.height(); j++) {
//For R,G,B

for(c=0; c<3; c++) {

for(l=0; l<64 /*4*/; l++){

for(k=0; k<64 /*4*/; k++){

arr[l][k] = img(i/zFactor +l, j/zFactor +k, 0, c); // img (x,y,z,c)
}
}

for(jj=0; jj<16; jj++)
{
auxx[jj] = (unsigned char)(i%zFactor)/zFactor;
auxy[jj] = (unsigned char)(j%zFactor)/zFactor;
}
color[c]=bicubicInterpolate_paralelo(arr, auxx, auxy);
}
z_img.draw_point(i,j,color);
}
}
return z_img;

}

Answer

In bicubicInterpolate_paralelo you return a pointer to a local data array. This pointer is invalid after function return.

Then you are trying to store this pointer value (unsigned char*) in unsigned char array.

Describe how exactly this function is supposed to work so we can propose the idea how to fix it.

//EDIT: OK, I see your problem. You wish to return the array of 16 chars.

It will be better to return it with output parameter:

Instead of:

unsigned char* bicubicInterpolate_paralelo (unsigned char p[64][64]/*4,4*/, unsigned char x[16]/*1*/, unsigned char y[16]/*1*/) {

you should do:

void/some_status bicubicInterpolate_paralelo (unsigned char p[64][64]/*4,4*/, unsigned char x[16]/*1*/, unsigned char y[16]/*1*/, unsigned char (*output)[16]) {

with call:

bicubicInterpolate_paralelo(arr, auxx, auxy, color[c]);

now you can write directly to output instead of valorPixelCanal