I am using a dynamically allocated array to store the addresses of screen lines for a graphics application that uses the Graphics SDL Library. I am using the following code to create and initialise the array:
The types of the variables are those required by SDL, however I get the following error:
error: invalid conversion from ‘Uint8*’ to ‘unsigned char’
and the compiler indicates that the error is in the 'for' loop line. I have tried many different ways of casting the expression including putting (Uint8 *) after the '=' but it does not work. What am I doing wrong?
Well it compiles now but i get a segmentation fault when the program runs, so it must be changing the way the pointer works. The code that uses the array is probably contributing to the segmentation fault and is as follows:
1 2 3 4 5 6
Uint8 *PixelAddress;
void SetPixelAddress(int x,int y) {PixelAddress=(Uint8 *)LineAddress[y]+x*BytesPerPixel;}
// and further on i use the pointer to set a pixel
*PixelAddress=DrawColour;
The curious thing is that if I use the code, as I have it originally in my first post, and change the array so it 's size is set when it is declared and get rid of the dynamic allocation it works... so not sure what is going on... unfortunately I need the dynamic allocation, any more ideas?
I have removed the cast as suggested, I still get the segmentation error. I am storing the LineAddress to avoid multiplying it each time. I have not combined the address calculation and pixel setting functions as you have suggested.
What I don't understand is why this works without the dynamic allocation:
1 2 3 4 5 6 7 8 9 10 11 12
Uint8 *ScreenAddress;
Uint16 BytesPerLine;
Uint8 *LineAddress[800];
Uint8 *PixelAddress;
for (int index=0; index<Height; index++) LineAddress[index]=ScreenAddress+(index*BytesPerLine);
// calculating the address
void SetPixelAddress(int x,int y) {PixelAddress=(Uint8 *)LineAddress[y]+x*BytesPerPixel;}
// and further on i use the pointer to set a pixel
*PixelAddress=DrawColour;
but stops working as soon as I do this:
1 2 3
Uint8 *LineAddress;
LineAddress = new Uint8[Height];
I think your "optimization" is actually slower than if you didn't optimize. You've replaced a
multiply with an add and a memory access. I think it would be better if you avoid the problem
altogether and remove your LineAddress array.
But, if you really want to keep it, and it crashes the first time into SetPixelAddress, then I'd
suggest printing out the values of x, y, LineAddress[y], and the calculated address to make
sure they all look right.
Your right, I am doing optimisations from the old days when multiplies were very costly, with faster processors now I need to update my optimisation practises! Removed it an it works fine. Thanks.
For the record, the 'optimised' version does seem to work faster, the other version stutters noticeably, not sure why. The final version as follows worked:
This is for pixel-level access, isn't it? The way I do this is
1 2 3 4 5 6 7 8 9 10 11
uchar *pix=/*...*/;
for (ulong y=0;y<h;y++){
uchar *pix0=pix;
for (ulong x=0;x<w;x++){
pix[Roffset]=/*...*/;
pix[Goffset]=/*...*/;
pix[Boffset]=/*...*/;
pix+=advance; //advance: size of a pixel in bytes
}
pix=pix0+pitch; //pitch: size of a scan line in bytes (padding included)
}
I always work with 24- and 32-bit surfaces in memory.