Help Getting Pixel Data

This is a discussion on Help Getting Pixel Data within the C++ Programming forums, part of the General Programming Boards category; I'm using SDL to load a greyscale bitmap. I know SDL_surface->pixels is an offset to the pixel data. So I ...

  1. #1
    Registered User IdioticCreation's Avatar
    Join Date
    Nov 2006
    Location
    Lurking about
    Posts
    229

    Help Getting Pixel Data

    I'm using SDL to load a greyscale bitmap. I know SDL_surface->pixels is an offset to the pixel data. So I did this in an attempt to get the individual values:
    Code:
    char* position = (char*) myMap->pixels;
    position += (y * myMap->pitch);
    position += (x * myMap->format->BytesPerPixel);
    Could someone let me know if this is right or now?

    Also another problem Is that I don't really understand what the values are (their type). I want to use them for height mapping.

    Thanks in advance!

  2. #2
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,159
    Quote Originally Posted by IdioticCreation View Post
    I'm using SDL to load a greyscale bitmap. I know SDL_surface->pixels is an offset to the pixel data. So I did this in an attempt to get the individual values:
    Code:
    char* position = (char*) myMap->pixels;
    position += (y * myMap->pitch);
    position += (x * myMap->format->BytesPerPixel);
    Assuming SDL is sane, this looks correct. As for what the values mean, they're probably just device gray levels from 0..255, with 0 meaning "black" and 255 meaning "white."

  3. #3
    Registered User IdioticCreation's Avatar
    Join Date
    Nov 2006
    Location
    Lurking about
    Posts
    229
    Yeah you're right they were, but they were Uint32's and that threw me off. I just casted them to integers and they gave proper values. Is it OK to do it like that?

  4. #4
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,189
    as logn as no values are over 0x7FFFFFF you are fine, otherwise you need to cast it to unsigned int.
    Until you can build a working general purpose reprogrammable computer out of basic components from radio shack, you are not fit to call yourself a programmer in my presence. This is cwhizard, signing off.

  5. #5
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,159
    Quote Originally Posted by IdioticCreation View Post
    Yeah you're right they were, but they were Uint32's and that threw me off. I just casted them to integers and they gave proper values. Is it OK to do it like that?
    Where do you get the idea the data is Uint32? SDL_surface defines "pixels" as a void *, meaning unspecified type. What type the data actually "is" doesn't matter, the only thing that matters is the value of BytesPerPixel. In this case, it should be 1.

    The only thing I'd really change in your code would be to use unsigned char * instead of char *.

  6. #6
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    If you have SDL set up using 32 bit colour then I am pretty sure that the surface will still take up 4 bytes per pixel. To read colour values you only need to get an R, G, or B byte. Just make sure its not the alpha byte.

    And yes, its best to use unsigned types. Otherwise you end up with weird bugs a lot of the time.

  7. #7
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,159
    Quote Originally Posted by mike_g View Post
    If you have SDL set up using 32 bit colour then I am pretty sure that the surface will still take up 4 bytes per pixel.
    4 bytes per pixel isn't the same as "the data type is Uint32." The data type is unknown. All that is known is that:

    Code:
    unsigned char *pix = y * pitch + x * bytes_per_pixel;
    points to the pixel in question. What the data at this location means depends specifically on the data format. Knowing that it's 4 bytes per pixel isn't enough to decode the value, you must also deal with whatever endianness it's stored as.

    Which is why I think it's a little weird to store gray levels in a 4-byte-per-pixel format. It forces you to consider endianness when you shouldn't have to.

    EDIT: If this isn't "true gray," meaning it's actually 32-bit RGB with R==G==B, then yes, you can just dereference the unsigned char * directly. But don't access element 0 -- without knowing the endianness, you can't know whether that's the alpha channel or not. Instead, access pixel[1], which is going to be a color component, regardless of what endianness it's using.

    But if the data really is just gray levels, it's better to store it in an 8-bit gray map, for efficiency both in memory and processing time.
    Last edited by brewbuck; 03-25-2008 at 04:52 PM.

  8. #8
    Registered User IdioticCreation's Avatar
    Join Date
    Nov 2006
    Location
    Lurking about
    Posts
    229
    Actually I had used SDL_GetRGB() so the values were in a SDL_Color which stores r g and b as Uint32's. Thanks for all the help guys.

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,045
    Food for thought.
    Code:
    Uint32 get_pixel(SDL_Surface *surface, int x, int y) {
        Uint8 *p;
        
        if(!surface->pixels) return 0;
        
        p = (Uint8 *)surface->pixels
            + y * surface->pitch
            + x * surface->format->BytesPerPixel;
        
        if(x < 0 || y < 0 || x >= surface->w || y >= surface->h) return 0;
    
        switch(surface->format->BytesPerPixel) {
        case 1:
            return *p;
        case 2:
            return *(Uint16 *)p;
        case 3:
            if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
                return p[0] << 16 | p[1] << 8 | p[2];
            }
            else return p[0] | p[1] << 8 | p[2] << 16;
        case 4:
            return *(Uint32 *)p;
        default:
            return 0;
        }
    }
    Taken almost verbatim from the SDL documentation.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problem with data in allocated memory
    By supi in forum C Programming
    Replies: 3
    Last Post: 06-09-2008, 02:06 AM
  2. data structure design for data aggregation
    By George2 in forum C# Programming
    Replies: 0
    Last Post: 05-20-2008, 06:43 AM
  3. [question]Analyzing data in a two-dimensional array
    By burbose in forum C Programming
    Replies: 2
    Last Post: 06-13-2005, 07:31 AM
  4. File Database & Data Structure :: C++
    By kuphryn in forum C++ Programming
    Replies: 0
    Last Post: 02-24-2002, 10:47 AM
  5. How do I base size of arrays on annother number?
    By Dual-Catfish in forum C++ Programming
    Replies: 15
    Last Post: 09-25-2001, 01:31 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21