// // Lol Engine // // Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net> // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See // http://www.wtfpl.net/ for more details. // #if defined HAVE_CONFIG_H # include "config.h" #endif #if defined __ANDROID__ #include <jni.h> #include <android/log.h> extern "C" { #include <android_native_app_glue.h> } #include "core.h" #include "../../image/image-private.h" using namespace std; namespace lol { extern ANativeActivity *g_activity; /* * Image implementation class */ DECLARE_IMAGE_LOADER(AndroidImageData, 100) { public: virtual bool Open(char const *); virtual bool Save(char const *); virtual bool Close(); virtual uint8_t *GetData() const; private: jobject bmp; jintArray array; jint *pixels; }; bool AndroidImageData::Open(char const *path) { JNIEnv *env; jint res = g_activity->vm->GetEnv((void **)&env, JNI_VERSION_1_2); if (res < 0) { #if !LOL_BUILD_RELEASE Log::Error("JVM environment not found, trying to attach thread\n"); #endif res = g_activity->vm->AttachCurrentThread(&env, nullptr); } if (res < 0) { #if !LOL_BUILD_RELEASE Log::Error("JVM environment not found, cannot open image %s\n", path); #endif return false; } jclass cls = env->GetObjectClass(g_activity->clazz); jmethodID mid; mid = env->GetMethodID(cls, "openImage", "(Ljava/lang/String;)Landroid/graphics/Bitmap;"); jstring name = env->NewStringUTF(path); bmp = env->CallObjectMethod(g_activity->clazz, mid, name); env->DeleteLocalRef(name); if (!bmp) { #if !LOL_BUILD_RELEASE Log::Error("could not load %s\n", path); #endif return false; } env->NewGlobalRef(bmp); /* Get image dimensions */ mid = env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I"); m_size.x = env->CallIntMethod(g_activity->clazz, mid, bmp); mid = env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I"); m_size.y = env->CallIntMethod(g_activity->clazz, mid, bmp); /* Get pixels */ array = env->NewIntArray(m_size.x * m_size.y); env->NewGlobalRef(array); mid = env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V"); env->CallVoidMethod(g_activity->clazz, mid, bmp, array); pixels = env->GetIntArrayElements(array, 0); for (int n = 0; n < m_size.x * m_size.y; n++) { uint32_t u = pixels[n]; u = (u & 0xff00ff00) | ((u & 0xff0000) >> 16) | ((u & 0xff) << 16); pixels[n] = u; } m_format = PixelFormat::RGBA_8; return true; } bool AndroidImageData::Save(char const *path) { UNUSED(path); /* TODO: unimplemented */ } bool AndroidImageData::Close() { JNIEnv *env; jint res = g_activity->vm->GetEnv((void **)&env, JNI_VERSION_1_2); if (res < 0) { #if !LOL_BUILD_RELEASE Log::Error("JVM environment not found, cannot close image\n"); #endif return false; } jclass cls = env->GetObjectClass(g_activity->clazz); jmethodID mid; env->ReleaseIntArrayElements(array, pixels, 0); env->DeleteGlobalRef(array); /* Free image */ mid = env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V"); env->CallVoidMethod(g_activity->clazz, mid, bmp); env->DeleteGlobalRef(bmp); return true; } uint8_t *AndroidImageData::GetData() const { return (uint8_t *)pixels; } } /* namespace lol */ #endif /* __ANDROID__ */