Reply
Thread Tools
Posts: 317 | Thanked: 787 times | Joined on Oct 2009 @ Krakow, Poland
#1
I use the following code to convert 32bit RGBA bitmap to 16bit and upload it to graphic hardware:

Code:
int i, j;
GLubyte* pixels8888 = surfaceRGBA->pixels;
GLushort * pixels4444 = 
    malloc(sizeof(GLushort) * surfaceRGBA -> w * surfaceRGBA -> h);

for (i = 0; i < surfaceRGBA -> w * surfaceRGBA -> h; i++) {
    j = i << 2;
    pixels4444[i] = (pixels8888[j+3] >> 4) 
                    + ((pixels8888[j+2] >> 4) << 4) 
                    + ((pixels8888[j+1] >> 4) << 8) 
                    + ((pixels8888[j] >> 4) << 12);
}

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surfaceRGBA->w, surfaceRGBA->h, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels4444);
//free(pixels4444);
The conversion totally works. I have a problem with last line. When it is uncommented my app crashes with following error:

Code:
*** glibc detected *** /opt/cloudgps/cloudgps: free(): invalid next size (normal): 0x00052788 ***
What is wrong with this free() call? How should I correctly free memory allocated for conversion (pixels4444)?

Thanks in advance.

Resolution:
The error in the code snippet above is that pixels4444 should not be freed right after calling glTexImage2D because pixels4444 can be used by OpenGL later. According to this:
OpenGL loads textures in a lazy fashion - that is, the actual loading of the texture to be used doesn't occur until the texture is used. In this case it doesn't happen until the call to glDrawArrays that you've measured.

Last edited by dwaradzyn; 2010-07-11 at 13:16. Reason: Resolution
 
Posts: 726 | Thanked: 345 times | Joined on Apr 2010 @ Sweden
#2
Just to help debugging:

Always check the return value of malloc calls.

Have you tried writing a program that does just this operation? If not, do so.
 

The Following User Says Thank You to Joorin For This Useful Post:
Posts: 317 | Thanked: 787 times | Joined on Oct 2009 @ Krakow, Poland
#3
You are right about checking return value - I should always do that. But in this particular issue malloc succeeds (if it would fail there will be immediate segfault because of NULL pointer). I will try to isolate this from whole program and investigate further. Anyway thanks for your input.

As the case is not closed yet more thoughts are welcome.
 
Posts: 3,617 | Thanked: 2,412 times | Joined on Nov 2009 @ Cambridge, UK
#4
Looking online, the usual cause of this error seems to be either using the variable after freeing it, or overrunning the malloced buffer when assigning to it.
 
Posts: 726 | Thanked: 345 times | Joined on Apr 2010 @ Sweden
#5
My gut feeling in this case is that you've done a double free or something similar somewhere else so isolating this functionality is just the first step.
 
fnordianslip's Avatar
Posts: 670 | Thanked: 359 times | Joined on May 2007
#6
You could try using valgrind.
 

The Following User Says Thank You to fnordianslip For This Useful Post:
Posts: 8 | Thanked: 2 times | Joined on Jun 2009
#7
Like Rob1n, I suspect that it's a buffer overrun, Valgrind might help in its detection as fnordianslip suggested. There's a possibility that the bounds check in the for loop might not work the way you think (compiler dependent I believe). It might be evaulating i < surfaceRGBA -> w and then multiplying that by surfaceRGBA -> h, which you could eliminate with i < (surfaceRGBA -> w * surfaceRGBA -> h), but I'm not sure that'd cause the problem.
 
juise-'s Avatar
Posts: 186 | Thanked: 192 times | Joined on Jan 2010 @ Finland
#8
It seems that the buffer is given as parameter to glTexImage2D(). Check the documentation to see exactly what that function does to the buffer.

Does the free() work if you comment out the call to glTexImage2D()?

Does it work if you place it immediately after malloc()?
__________________
Trout have underwater weapons.
 

The Following User Says Thank You to juise- For This Useful Post:
Posts: 3 | Thanked: 1 time | Joined on Feb 2010
#9
try his one: (comment out the function call glTexImage2D(...), uncomment the free(...)
Code:
int i, j;
GLubyte* pixels8888 = surfaceRGBA->pixels;
GLushort * pixels4444 = 
    malloc(sizeof(GLushort) * surfaceRGBA -> w * surfaceRGBA -> h);

for (i = 0; i < surfaceRGBA -> w * surfaceRGBA -> h; i++) {
    j = i << 2;
    pixels4444[i] = (pixels8888[j+3] >> 4) 
                    + ((pixels8888[j+2] >> 4) << 4) 
                    + ((pixels8888[j+1] >> 4) << 8) 
                    + ((pixels8888[j] >> 4) << 12);
}

// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surfaceRGBA->w, surfaceRGBA->h, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels4444);

free(pixels4444);
if it works, you know where to search....
 

The Following User Says Thank You to manu_dibango For This Useful Post:
Posts: 317 | Thanked: 787 times | Joined on Oct 2009 @ Krakow, Poland
#10
Originally Posted by juise- View Post
It seems that the buffer is given as parameter to glTexImage2D(). Check the documentation to see exactly what that function does to the buffer.

Does the free() work if you comment out the call to glTexImage2D()?

Does it work if you place it immediately after malloc()?
free() works when glTextImage2D is commented. Khronos API docs say nothing about memory management, but standard OpenGL docs say that I should free my pixels as they are copied to video memory after call to glTextImage2D.

Thanks everyone for your help.
 
Reply


 
Forum Jump


All times are GMT. The time now is 12:17.