/*
* call-seq:
* get_at(pos)
* get_at(x,y)
*
* Return the color [r,g,b,a] of the pixel at the given coordinate.
*
* This method takes these argument:
* - pos:: the coordinate of the pixel to get the color of.
*
* The coordinate can also be given as two arguments, separate +x+ and +y+
* positions.
*/
VALUE rbgm_surface_getat( int argc, VALUE *argv, VALUE self )
{
SDL_Surface *surf;
int x,y;
int locked=0;
Uint32 color;
Uint8 *pixels, *pix;
Uint8 r,g,b,a;
Data_Get_Struct(self, SDL_Surface, surf);
if(argc>2)
rb_raise(rb_eArgError,"wrong number of arguments (%d for 1)",argc);
if(argc==1)
{
x = NUM2INT(rb_ary_entry(argv[0],0));
y = NUM2INT(rb_ary_entry(argv[0],1));
}
else
{
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
}
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);
/* 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;
}
if((int *)color == NULL)
{
VALUE zero = INT2NUM(0);
return rb_ary_new3(4,zero,zero,zero,zero);
}
SDL_GetRGBA(color, surf->format, &r, &g, &b, &a);
return rb_ary_new3(4,UINT2NUM(r),UINT2NUM(g),UINT2NUM(b),UINT2NUM(a));
}