Stupid SDL_Image bug, help!
category: general [glöplog]
I've been trying to search about this on google because I thought it was a very characteristic bug but I couldn't find anything except if I wasn't searching for the right keywords.
I think it happens when you load an image with odd width of pixels. The image appears sloped. It's like in my view they divided the width with some number to get something and they lost one pixel on final width or something.
Of course this is easy solvable, I just make all my textures/images having even number of width. But recently I wanted to have some real fonts and tried to use SDL_ttf lib, it renders your texts to an SDL_Surface pointer. So, depending on the font size and type and text a different size of image is rendered so I can't predict when the final image of text will be right or sloped. So for each different text I have to manually insert a bit different font size till I match a case where SDL_Image doesn't screw up. I have some ugly solutions in my head but I am wondering if anyone else has this bug and if there is already a fix out there?
I think it happens when you load an image with odd width of pixels. The image appears sloped. It's like in my view they divided the width with some number to get something and they lost one pixel on final width or something.
Of course this is easy solvable, I just make all my textures/images having even number of width. But recently I wanted to have some real fonts and tried to use SDL_ttf lib, it renders your texts to an SDL_Surface pointer. So, depending on the font size and type and text a different size of image is rendered so I can't predict when the final image of text will be right or sloped. So for each different text I have to manually insert a bit different font size till I match a case where SDL_Image doesn't screw up. I have some ugly solutions in my head but I am wondering if anyone else has this bug and if there is already a fix out there?
Just with a few more tests, it actually happens if the image width is not divisible by four. It's like someone (but not me I think) divided the width with four to say get from width of bytes to width in 32bit pixels or something but this would kill 1-3 pixels of width. Or I don't know, something like that. The slope is obvious why it would happen in these cases. I just don't know why someone should do these operations to just load the image data.
have you tried using the pitch of the image instead of the width ?
That's pretty normal, and you even have that in FreeBASIC, the freeimage lib and other stuff. It's simply faster to handle this data because of the memory bus width or something. I'm not an export on this topic, but this is just for speed's sake. But it seems a bit strange that the same thing is not applied on the TTF extension, maybe you should ask the devs. Or maybe you're using an outdated version of sdl_ttf?
Yeah the SDL_Surface.pitch field is defined as "the length of a surface scanline in bytes", which isn't guaranteed to be the same as the width times the size of a pixel. This allows SDL to insert padding where it wants to for various reasons (mostly memory alignment benefits).
Ok thanks. Simply, I was reading serially the whole data with one loop without minding the padding at the end of each line. I didn't even knew SDL was doing that on it's surfaces and I assumed otherwise. Kinda non practical when it gives me a surface->pixels pointers and tells me this is the pixel data without informing me of the padding but anyways, if it's all for the sake of optimization.
Therefore, never assume :)
It does inform you of the padding. It informs you of it in the "pitch" field ;-)
If I remember correctly, this is a limitation of opengl and such because most (all?) hardware requires textures to be divisible by 4 (but I thought the limitation was actually something like a product of 2 to the n, where n is a positive integer) in order to simplify MIP mapping.
spindle: No, it's not. You might be confused because the default value of GL_UNPACK_ALIGNMENT is 4. This does not mean that other values are not supported. And you seem to throw a bit of pow2-texture requirements into the mix, which were some generations of GPUs back.
@xeron: I have never read the documentation :)