SDL_image and bmp loading

Member
Posts: 567
Joined: 2004.07
Post: #1
I finally managed to hack together a texture file (.h/.c), and it works fine. The only problem, as far as I can see, is that SDL-image forgets that bmps are in bgr, not RGB, and so it switches the red and blue channels, which as you can imagine, is quite annoying. I would rather not convert everything over to a png, so is there a quick and easy solution to all this?
[edit]Just as I thought. I looked at the source, and guess what? NO BGR SUPPORT![/edit]

It's not magic, it's Ruby.
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #2
If you are using SDL, just use the format conversion functions.
SDL docWiki
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #3
Uhm, the pixel format of the surface returned indicates that it is indeed in BGR format. You should be converting it anyway since 32bpp textures are MUCH faster than 24. You probably should come up with some sort of pixel format mechanism for your own code anyway because SDL's doesn't have anything that tells OpenGL what kind of images yours is. For example, if you have 8 bits per channel and one channel, it could be GL_UMINANCE, GL_ALPHA, GL_RED, GL_GREEN, or GL_BLUE.
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #4
is there anyway to figure out whether a surface is BGR or RGB? What in the SDL_PixelFormat would say so?

It's not magic, it's Ruby.
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #5
The rshift and bshift parts... Honestly though, just use the surface converter to make anything 24 bit into 32 bit RGBA because the 24 bit formats are slower. Keep 16 bit and 8 bit unpalleted things untouched though. You can determine bits per pixel with the bpp variable.
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #6
meaning...

It's not magic, it's Ruby.
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #7
Ok, here is some source:

Code:
//Loads an image from a file, converting it to the appropriate format
SDL_Surface *loadImage(const char *fileName)
{
    //Attempt to load the image
    SDL_Surface *image = NULL;
    image = IMG_Load(filename);
    if (! image)
    {
        LOG_ERROR("Could not load image %s", fileName);
        return NULL;
    }

    //Check the format
    switch (image->format->BitsPerPixel)
    {
    case 8:
        //It's 8 bit, do whatever
        break;
    case 16:
        //It's 16 bit, do whatever
        break;
    case 24:
        //It's 24 bit, so always convert (someone check my pixel format for me!)
        SDL_PixelFormat format = {NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, 255};
        SDL_Surface *temp = SDL_ConvertSurface(image, &format, SDL_SWSURFACE);
        SDL_FreeSurface(image);
        image = temp;
        break;
    case 32:
        //It's 32 bit, so convert only if it's ABGR (and really, check this pixel format!)
        if (image->format->rshift > image->format->bshift)
        {
            SDL_PixelFormat format = {NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, 255};
            SDL_Surface *temp = SDL_ConvertSurface(image, &format, SDL_SWSURFACE);
            SDL_FreeSurface(image);
            image = temp;
        }
        break;
    default:
        LOG_ERROR("Unknown image format for %s", fileName);
    }

    return image;
}
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #8
Thank you, and sorry for the trouble I caused y'all... Sad

[edit]Why does it say there is a parse error before format? (SDL_PixelFormat)?

It's not magic, it's Ruby.
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #9
Oh no trouble. I didn't test that code BTW, so sorry about the syntax error - I just roughed out code and didn't test it or anything. Anyway, the fixed, syntax checked but still untested version is:

Code:
//Loads an image from a file, converting it to the appropriate format
SDL_Surface *loadImage(const char *fileName)
{
    //Attempt to load the image
    SDL_Surface *image = NULL;
    image = IMG_Load(fileName);
    if (! image)
    {
        LOG_ERROR("Could not load image %s", fileName);
        return NULL;
    }

    //Check the format
    switch (image->format->BitsPerPixel)
    {
    case 8:
        //It's 8 bit, do whatever
        break;
    case 16:
        //It's 16 bit, do whatever
        break;
    case 24:
        //It's 24 bit, so always convert (someone check my pixel format for me!)
        //Note that this scoping is used to prevent the declaration of format twice....
        {
            SDL_PixelFormat format = {NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, 255};
            SDL_Surface *temp = SDL_ConvertSurface(image, &format, SDL_SWSURFACE);
            SDL_FreeSurface(image);
            image = temp;
            break;
        }
    case 32:
        //It's 32 bit, so convert only if it's ABGR (and really, check this pixel format!)
        if (image->format->Rshift > image->format->Bshift)
        {
            SDL_PixelFormat format = {NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, 255};
            SDL_Surface *temp = SDL_ConvertSurface(image, &format, SDL_SWSURFACE);
            SDL_FreeSurface(image);
            image = temp;
        }
        break;
    default:
        LOG_ERROR("Unknown image format for %s", fileName);
    }

    return image;
}
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #10
hmm, not quite. You have the values wrong. You wrote it as ABGR, when it is supposed to be RGBA.
in place of the previous values, put 0xFF000000 0x00FF0000 0x0000FF00 0x000000FF

It's not magic, it's Ruby.
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #11
Oh right, you are on a Mac. Those values are little endian (so they are correct for me), however, they won't work for you. I'd suggest you use the functions in SDL_endian.h to make it all crossplatform.
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #12
ahh... Cool! I was wondering what endian was for...
*goes off in search of way to use endian*

It's not magic, it's Ruby.
Quote this message in a reply
Nibbie
Posts: 2
Joined: 2008.09
Post: #13
I just ran into some crazy texture-loading issues when updating from SDL_image 1.2.7 to 1.2.10 on my Mac, and was glad to find your thread! I'm using PNGs, but the same fix worked for me.

For cross-platform compatibility, I used the following tweak:
Code:
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
SDL_PixelFormat format = { NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF, 0, 255 };
#else
SDL_PixelFormat format = { NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, 255 };
#endif

This appears to work correctly on both PowerPC and Intel Macs, using both old and new versions of the SDL_image framework.

Thanks!
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #14
Yay a zombie thread trying to resurrect the use of SDL_Image for OpenGL texture loading. Since my last post in this thread 4 years ago, I've learned my lesson about SDL_Image and have made other posts to much the same effect.

DON'T USE IT. It's really slow, not just a little slow, but really really slow. It's also not very flexible and requires more work to force into submission than just using libPNG/libJPEG especially when somebody is handing you the source to do it.

Do you really care about more than just PNG loading and maybe JPEG loading for larger images? Probably not.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Trouble using SDL_image with XCode 3.2.3 Snow Leopard code4fun 1 4,371 Sep 22, 2010 10:47 PM
Last Post: OneSadCookie
  Installing SDL_image & SDL_mixer bronxbomber92 8 5,740 Oct 14, 2006 09:39 PM
Last Post: szymczyk
  SDL_image + libpng + Panther = version mismatch BobbyWatson 2 4,172 Oct 23, 2005 03:55 AM
Last Post: BobbyWatson
  I Need help with SDL_image.h LidLad 8 4,930 Oct 2, 2005 05:37 PM
Last Post: LidLad
  SDL_image errors mevdev 7 4,636 Sep 17, 2005 10:01 AM
Last Post: sealfin