151 line
3.7 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. #include <lol/engine-internal.h>
  11. #if defined __ANDROID__
  12. #include <jni.h>
  13. #include <android/log.h>
  14. extern "C" {
  15. #include <android_native_app_glue.h>
  16. }
  17. #include "../../image/image-private.h"
  18. namespace lol
  19. {
  20. extern ANativeActivity *g_activity;
  21. /*
  22. * Image implementation class
  23. */
  24. class AndroidImageCodec : public ImageCodec
  25. {
  26. public:
  27. virtual char const *GetName() { return "<AndroidImageCodec>"; }
  28. virtual bool Load(Image *image, char const *path);
  29. virtual bool Save(Image *image, char const *path);
  30. virtual bool Close();
  31. virtual uint8_t *GetData() const;
  32. private:
  33. jobject m_bmp;
  34. jintArray m_array;
  35. jint *m_pixels;
  36. };
  37. DECLARE_IMAGE_CODEC(AndroidImageCodec, 100)
  38. bool AndroidImageCodec::Load(Image *image, char const *path)
  39. {
  40. JNIEnv *env;
  41. jint res = g_activity->vm->GetEnv((void **)&env, JNI_VERSION_1_2);
  42. if (res < 0)
  43. {
  44. #if !LOL_BUILD_RELEASE
  45. Log::Error("JVM environment not found, trying to attach thread\n");
  46. #endif
  47. res = g_activity->vm->AttachCurrentThread(&env, nullptr);
  48. }
  49. if (res < 0)
  50. {
  51. #if !LOL_BUILD_RELEASE
  52. Log::Error("JVM environment not found, cannot open image %s\n", path);
  53. #endif
  54. return false;
  55. }
  56. jclass cls = env->GetObjectClass(g_activity->clazz);
  57. jmethodID mid;
  58. mid = env->GetMethodID(cls, "openImage",
  59. "(Ljava/lang/String;)Landroid/graphics/Bitmap;");
  60. jstring name = env->NewStringUTF(path);
  61. m_bmp = env->CallObjectMethod(g_activity->clazz, mid, name);
  62. env->DeleteLocalRef(name);
  63. if (!m_bmp)
  64. {
  65. #if !LOL_BUILD_RELEASE
  66. Log::Error("could not load %s\n", path);
  67. #endif
  68. return false;
  69. }
  70. env->NewGlobalRef(m_bmp);
  71. /* Get image dimensions */
  72. mid = env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I");
  73. m_size.x = env->CallIntMethod(g_activity->clazz, mid, m_bmp);
  74. mid = env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I");
  75. m_size.y = env->CallIntMethod(g_activity->clazz, mid, m_bmp);
  76. /* Get pixels */
  77. m_array = env->NewIntArray(m_size.x * m_size.y);
  78. env->NewGlobalRef(m_array);
  79. mid = env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V");
  80. env->CallVoidMethod(g_activity->clazz, mid, m_bmp, m_array);
  81. m_pixels = env->GetIntArrayElements(m_array, 0);
  82. for (int n = 0; n < m_size.x * m_size.y; n++)
  83. {
  84. uint32_t u = m_pixels[n];
  85. u = (u & 0xff00ff00) | ((u & 0xff0000) >> 16) | ((u & 0xff) << 16);
  86. m_pixels[n] = u;
  87. }
  88. m_format = PixelFormat::RGBA_8;
  89. return true;
  90. }
  91. bool AndroidImageCodec::Save(Image *image, char const *path)
  92. {
  93. UNUSED(path);
  94. /* TODO: unimplemented */
  95. }
  96. bool AndroidImageCodec::Close()
  97. {
  98. JNIEnv *env;
  99. jint res = g_activity->vm->GetEnv((void **)&env, JNI_VERSION_1_2);
  100. if (res < 0)
  101. {
  102. #if !LOL_BUILD_RELEASE
  103. Log::Error("JVM environment not found, cannot close image\n");
  104. #endif
  105. return false;
  106. }
  107. jclass cls = env->GetObjectClass(g_activity->clazz);
  108. jmethodID mid;
  109. env->ReleaseIntArrayElements(m_array, m_pixels, 0);
  110. env->DeleteGlobalRef(m_array);
  111. /* Free image */
  112. mid = env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V");
  113. env->CallVoidMethod(g_activity->clazz, mid, m_bmp);
  114. env->DeleteGlobalRef(m_bmp);
  115. return true;
  116. }
  117. uint8_t *AndroidImageCodec::GetData() const
  118. {
  119. return (uint8_t *)m_pixels;
  120. }
  121. } /* namespace lol */
  122. #endif /* __ANDROID__ */