153 lines
3.6 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #if defined __ANDROID__
  14. #include <jni.h>
  15. #include <android/log.h>
  16. extern "C" {
  17. #include <android_native_app_glue.h>
  18. }
  19. #include "core.h"
  20. #include "../../image/image-private.h"
  21. using namespace std;
  22. namespace lol
  23. {
  24. extern ANativeActivity *g_activity;
  25. /*
  26. * Image implementation class
  27. */
  28. DECLARE_IMAGE_LOADER(AndroidImageData, 100)
  29. {
  30. public:
  31. virtual bool Open(char const *);
  32. virtual bool Save(char const *);
  33. virtual bool Close();
  34. virtual uint8_t *GetData() const;
  35. private:
  36. jobject bmp;
  37. jintArray array;
  38. jint *pixels;
  39. };
  40. bool AndroidImageData::Open(char const *path)
  41. {
  42. JNIEnv *env;
  43. jint res = g_activity->vm->GetEnv((void **)&env, JNI_VERSION_1_2);
  44. if (res < 0)
  45. {
  46. #if !LOL_BUILD_RELEASE
  47. Log::Error("JVM environment not found, trying to attach thread\n");
  48. #endif
  49. res = g_activity->vm->AttachCurrentThread(&env, nullptr);
  50. }
  51. if (res < 0)
  52. {
  53. #if !LOL_BUILD_RELEASE
  54. Log::Error("JVM environment not found, cannot open image %s\n", path);
  55. #endif
  56. return false;
  57. }
  58. jclass cls = env->GetObjectClass(g_activity->clazz);
  59. jmethodID mid;
  60. mid = env->GetMethodID(cls, "openImage",
  61. "(Ljava/lang/String;)Landroid/graphics/Bitmap;");
  62. jstring name = env->NewStringUTF(path);
  63. bmp = env->CallObjectMethod(g_activity->clazz, mid, name);
  64. env->DeleteLocalRef(name);
  65. if (!bmp)
  66. {
  67. #if !LOL_BUILD_RELEASE
  68. Log::Error("could not load %s\n", path);
  69. #endif
  70. return false;
  71. }
  72. env->NewGlobalRef(bmp);
  73. /* Get image dimensions */
  74. mid = env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I");
  75. m_size.x = env->CallIntMethod(g_activity->clazz, mid, bmp);
  76. mid = env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I");
  77. m_size.y = env->CallIntMethod(g_activity->clazz, mid, bmp);
  78. /* Get pixels */
  79. array = env->NewIntArray(m_size.x * m_size.y);
  80. env->NewGlobalRef(array);
  81. mid = env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V");
  82. env->CallVoidMethod(g_activity->clazz, mid, bmp, array);
  83. pixels = env->GetIntArrayElements(array, 0);
  84. for (int n = 0; n < m_size.x * m_size.y; n++)
  85. {
  86. uint32_t u = pixels[n];
  87. u = (u & 0xff00ff00) | ((u & 0xff0000) >> 16) | ((u & 0xff) << 16);
  88. pixels[n] = u;
  89. }
  90. m_format = PixelFormat::RGBA_8;
  91. return true;
  92. }
  93. bool AndroidImageData::Save(char const *path)
  94. {
  95. UNUSED(path);
  96. /* TODO: unimplemented */
  97. }
  98. bool AndroidImageData::Close()
  99. {
  100. JNIEnv *env;
  101. jint res = g_activity->vm->GetEnv((void **)&env, JNI_VERSION_1_2);
  102. if (res < 0)
  103. {
  104. #if !LOL_BUILD_RELEASE
  105. Log::Error("JVM environment not found, cannot close image\n");
  106. #endif
  107. return false;
  108. }
  109. jclass cls = env->GetObjectClass(g_activity->clazz);
  110. jmethodID mid;
  111. env->ReleaseIntArrayElements(array, pixels, 0);
  112. env->DeleteGlobalRef(array);
  113. /* Free image */
  114. mid = env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V");
  115. env->CallVoidMethod(g_activity->clazz, mid, bmp);
  116. env->DeleteGlobalRef(bmp);
  117. return true;
  118. }
  119. uint8_t *AndroidImageData::GetData() const
  120. {
  121. return (uint8_t *)pixels;
  122. }
  123. } /* namespace lol */
  124. #endif /* __ANDROID__ */