Skip to content

Instantly share code, notes, and snippets.

@eliantor
Created April 23, 2012 13:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eliantor/2471041 to your computer and use it in GitHub Desktop.
Save eliantor/2471041 to your computer and use it in GitHub Desktop.
The java class
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := bitmapsfix
LOCAL_SRC_FILES := bitmaps.c
LOCAL_LDLIBS := -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY)
#include <jni.h>
#include <android/log.h>
#include <android/bitmap.h>
#define LOG_TAG "NATIVE_TRACK"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define RB_CONV(i) ((char)(8.22580645*(i)))
#define G_CONV(i) ((char)(4.04761905*(i)))
#define OPAQUE 0xFF000000
#define A_CONV(i) (OPAQUE & ((int)(i))<<24)
static unsigned char rb_table[32];
static unsigned char g_table[64];
static void init_conversion(void)
{
int i;
for(i=0;i<32;i++)
{
rb_table[i] = 255*i/31;
}
for(i=0;i<64;i++){
g_table[i] = 255*i/63;
}
}
static int _565toARGB(short color)
{
unsigned int red = RB_CONV((color>>11)&31)<<16;
unsigned int green = G_CONV((color>>5)&63)<<8;
unsigned int blue = RB_CONV(color&31);
return OPAQUE|red|green|blue;
}
JNIEXPORT jint JNICALL Java_sincro_trackpaint_utils_Bitmaps_nativeGetPixel
(JNIEnv *env,jclass clazz,jobject jbitmap,jint x,jint y)
{
AndroidBitmapInfo info;
void* pixels;
int ret;
char* pointer;
if((ret =AndroidBitmap_getInfo(env,jbitmap,&info))<0){
LOGE("getInfo failed with error %d",ret);
return 0;
}
LOGI("image:: width = %d, height = %d, stride = %d",info.width,info.height,info.stride);
if((ret = AndroidBitmap_lockPixels(env,jbitmap,&pixels))<0){
LOGE("lockPixels failed with error %d",ret);
}else{
pointer = (char*)pixels;
pointer+=x+(info.stride*y);
if(info.format == ANDROID_BITMAP_FORMAT_A_8){
LOGI("pixel is: %d",A_CONV(*pointer));
return A_CONV(*pointer);
}
if(info.format == ANDROID_BITMAP_FORMAT_RGB_565){
short rgb = ((*pointer)<<8)|*(pointer+1);
return _565toARGB(rgb);
}
AndroidBitmap_unlockPixels(env,jbitmap);
}
return 0;
}
public final class Bitmaps {
private static final String NOT_IMPLEMENTED = "Not yet implemented for formats that are not ARGB_8888";
private Bitmaps(){}
static{
System.loadLibrary("bitmapsfix");
}
public static int getPixel(Bitmap bitmap,int x,int y){
if(bitmap == null) throw new NullPointerException("bitmap can't be null");
final Config config = bitmap.getConfig();
final int pixel;
if(config == Config.ARGB_8888){
pixel = bitmap.getPixel(x, y);
}else if(config == Config.ARGB_4444){
throw new UnsupportedOperationException("Not yet implemented for ARGB_4444");
}else{
checkRecycled(bitmap, "Can't getPixel from a recycled bitmap");
checkPixelAccess(bitmap,x,y);
pixel = nativeGetPixel(bitmap,x,y);
}
return pixel;
}
public static void setPixel(Bitmap bitmap,int x,int y,int color){
if(bitmap == null) throw new NullPointerException("bitmap can't be null");
final Config config = bitmap.getConfig();
if(config == Config.ARGB_8888){
bitmap.setPixel(x, y, color);
}else{
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
}
}
public static void getPixels(Bitmap bitmap,int[] pixels,int offset,int stride,int x,int y,int width,int height){
if(bitmap == null) throw new NullPointerException("bitmap can't be null");
final Config config = bitmap.getConfig();
if(config == Config.ARGB_8888){
bitmap.getPixels(pixels, offset, stride, x, y, width, height);
}else{
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
}
}
public static void setPixels(Bitmap bitmap,int[] pixels,int offset,int stride,int x,int y,int width,int height){
if(bitmap == null) throw new NullPointerException("bitmap can't be null");
final Config config = bitmap.getConfig();
if(config == Config.ARGB_8888){
bitmap.setPixels(pixels, offset, stride, x, y, width, height);
}else{
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
}
}
private static void checkRecycled(Bitmap bitmap , String message){
if(bitmap.isRecycled())
throw new IllegalStateException(message);
}
private static void checkPixelAccess(Bitmap bitmap,int x,int y){
if(x < 0) throw new IllegalArgumentException("x must be positive");
if(y < 0) throw new IllegalArgumentException("y must be positive");
if(x >= bitmap.getWidth()) throw new IllegalArgumentException("x must be < than bitmap.width");
if(y >= bitmap.getHeight()) throw new IllegalArgumentException("y must be < than bitmap.height");
}
private static native int nativeGetPixel(Bitmap bitmap,int x,int y);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment