Phoenix Kokido wrote:
I’ve spent the better part of the evening trying to wade through the
different masks in the pixel format structure trying to solve the
folowing problem. Hopefully someone on this list is feeling generous
and can think a little straighter than me right now.
Problem: I want to read an arbitrary pixel from x,y into a the
following struct.
struct {
Uint8 r;
Uint8 g;
Uint8 b;
} color;
This may be overly simplistic, but I've done this by combining an SDL
example (I think it came with the demos package with SDL 0.8?), which
gets a pixel, and a pair of macros straight from the SDL which I
converted into a function for ease of use, which disassemble the R, G,
and B values. I’m not sure how it handles different 16-bit encodings
etc., but you can give it a try…
/****** This functino just grabs data for one raw pixel from a surface
******/
Uint32 get_pixel(SDL_Surface *surface, Sint32 Xcoord, Sint32 Ycoord)
{
Uint8 r, g, b;
Uint8 *bits;
Uint8 bytespp;
Uint32 pixel;
/* Set the number of bytes per pixel to calculate the pixel offset… */
bytespp = surface->format->BytesPerPixel;
/*calculate the offset (pointer) to the screen->pixels array
* screen->pitch must be the x of the screen times bytes per pixel
*/
bits = ((Uint8 *)surface->pixels) + Ycoord*surface->pitch +
Xcoord*bytespp;
/* We may now get the pixel */
switch(bytespp)
{
case 1:
(Uint8) pixel = *((Uint8 *) bits);
break;
case 2:
(Uint16) pixel = *((Uint16 *) bits);
break;
case 3: /* odd case, create offsets from screen data */
r = *((bits) + surface->format->Rshift / 8);
g = *((bits) + surface->format->Gshift / 8);
b = *((bits) + surface->format->Bshift / 8);
pixel = (r >> surface->format->Rshift) & 0xFF;
pixel = (g >> surface->format->Gshift) & 0xFF;
pixel = (b >> surface->format->Bshift) & 0xFF;
break;
case 4:
(Uint32) pixel = *((Uint32 *) bits);
break;
}
return pixel;
} /* get_pixel() */
/*******************************************************/
void DISEMBLE_RGB(void *inpixel, Uint8 bpp, SDL_PixelFormat *fmt, Uint8
*r, Uint8 *g, Uint8 *b)
{
Uint32 pixel;
switch (bpp) {
case 2:
pixel = *((Uint16
*)(inpixel));
RGB_FROM_PIXEL(pixel, fmt, r, g, b);
break;
case 3:
*r = *(((Uint8
*)inpixel)+fmt->Rshift/8);
*g = *(((Uint8
*)inpixel)+fmt->Gshift/8);
*b = *(((Uint8
*)inpixel)+fmt->Bshift/8);
// pixel = (*r << fmt->Rshift) | (*g <<
fmt->Gshift) | (*b << fmt->Bshift);
break;
case 4:
pixel = *((Uint32
*)(inpixel));
RGB_FROM_PIXEL(pixel, fmt, r, g, b);
break;
}
}
/* Load pixel of the specified format from a buffer and get its R-G-B
values */
void RGB_FROM_PIXEL(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r, Uint8
*g, Uint8 *b)
{
*r = (((pixel&fmt->Rmask)>>fmt->Rshift)<Rloss);
*g = (((pixel&fmt->Gmask)>>fmt->Gshift)<Gloss);
*b = (((pixel&fmt->Bmask)>>fmt->Bshift)<Bloss);
}
/*****************************************************/
Hey, I never said it was pretty...Call get_pixel, then disemble_RGB.
To be more efficient, just find the macros in the SDL header files,
include them, and use the macros. I suspect that the last function,
RGB_FROM_PIXEL, is the one you’re probably most interested in…
Nathan Yawn
@Nathan_A_Yawn