/*
* call-seq:
* get_at(x,y)
* get_at([x,y]) # deprecated
*
* Return the color [r,g,b,a] of the pixel at the given coordinate.
*
* Raises IndexError if the coordinates are out of bounds.
*/
VALUE rbgm_surface_getat( int argc, VALUE *argv, VALUE self )
{
SDL_Surface *surf;
int x, y, locked;
Uint32 color;
Uint8 *pixels, *pix;
Uint8 r,g,b,a;
VALUE vx, vy;
Data_Get_Struct(self, SDL_Surface, surf);
rb_scan_args(argc, argv, "11", &vx, &vy);
/* Still support passing position as an Array... for now. */
switch( TYPE(vx) )
{
case T_ARRAY: {
x = NUM2INT( rb_ary_entry(vx,0) );
y = NUM2INT( rb_ary_entry(vx,1) );
break;
}
default: {
x = NUM2INT(vx);
y = NUM2INT(vy);
break;
}
}
if( x < 0 || x > surf->w )
rb_raise(rb_eIndexError,"x index out of bounds (%d, min 0, max %d)",\
x,surf->w);
if( y < 0 || y > surf->h )
rb_raise(rb_eIndexError,"y index out of bounds (%d, min 0, max %d)",\
y,surf->h);
locked = 0;
/* lock surface */
if(SDL_MUSTLOCK(surf))
{
if(SDL_LockSurface(surf)==0)
locked += 1;
else
rb_raise(eSDLError,"could not lock surface: %s",SDL_GetError());
}
/* borrowed from pygame */
pixels = (Uint8 *) surf->pixels;
switch(surf->format->BytesPerPixel)
{
case 1:
color = (Uint32)*((Uint8 *)(pixels + y * surf->pitch) + x);
break;
case 2:
color = (Uint32)*((Uint16 *)(pixels + y * surf->pitch) + x);
break;
case 3:
pix = ((Uint8 *)(pixels + y * surf->pitch) + x * 3);
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
color = (pix[0]) + (pix[1]<<8) + (pix[2]<<16);
#else
color = (pix[2]) + (pix[1]<<8) + (pix[0]<<16);
#endif
break;
default: /*case 4:*/
color = *((Uint32*)(pixels + y * surf->pitch) + x);
break;
}
/* end borrowed from pygame */
/* recursively unlock surface*/
while(locked>1)
{
SDL_UnlockSurface(surf);
locked -= 1;
}
SDL_GetRGBA(color, surf->format, &r, &g, &b, &a);
return rb_ary_new3(4,UINT2NUM(r),UINT2NUM(g),UINT2NUM(b),UINT2NUM(a));
}