You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

152 lines
3.7 KiB

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