/* * 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)); }