I would like developping a program which computes two frames: one large and one small. I try to resize the small one for fit with the large one by a simple proportionnal transform (and then add them but the problem is not there).
The code is very short :
Variables ended by HD mean it’s the large frame
Variables ended by LD mean it’s the small frame
__global__ void d_framemix(float *outputImage, float *inputDataHD, float *inputDataLD, unsigned short widthHD, unsigned short heightHD , unsigned short widthLD,unsigned short heightLD)
{
const int xIndex = threadIdx.x + blockDim.x * blockIdx.x;
const int yIndexHD = threadIdx.y * widthHD + widthHD * blockIdx.y * blockDim.x;
const float ratiowidth = (float)widthLD/(float)widthHD;
const float ratioheight = (float)heightLD/(float)heightHD;
const int Index = (int)((float)(xIndex*ratiowidth)+(int)((float)(threadIdx.y * widthHD * ratioheight) + (float)(widthHD * blockIdx.y * blockDim.x * ratioheight));
outputImage[xIndex+yIndexHD]=inputDataLD[Index] + inputDataHD[xIndex+yIndexHD];
}
You have a small image with lets say width and height are half of the big one. You want to resize the small image to the size of the big one (or at least pick the pixels in this manner) and then add the values.
lets say those images are square, so widthLD = heightLD and widthHD = heightHD
What I thought the problem was:
you have the y position in your output image:
Iy = threadIdx.y + (blockIdx.y*blockDim.y)
you want to know the position in the small source image:
Iy_small = Iy * ratioheight
And now you have to multiply by the width of the small source to get the correct memory position:
y_offset = Iy_small * widthLD
Please correct me if I’m wrong but thats how I understood this thing should work.
You are still missing a cast to int. Two strong recommendations:
use tex2D if you can, then you do not need any of that stuff
Don’t put all the index calculation in one line, this is so confusing that you managed to confuse even yourself, not to speak of anyone else who might have to read your code.
Yes, that’s exactly right, but thanks to putting everything in a single line that cast to int that would happen in the Iysmall assignment got lost.
So e.g. line 3 in the large image might become line 1.5 in the small one, which makes no sense.
So something like that might work:
const int Index = (int)((float)(xIndex*ratiowidth)
+(int)((float)((int)((threadIdx.y + (blockIdx.y * blockDim.y))*ratioheight)*widthLD));
But I’d like to empahsize once more: When a programmer finds obfuscated code like this in production code you better keep him from finding the person who wrote it…