165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/*
265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2011 The Android Open Source Project
365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License");
565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License.
665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at
765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *      http://www.apache.org/licenses/LICENSE-2.0
965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software
1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS,
1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and
1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License.
1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */
1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "android/bitmap.h"
1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "jni/jni_gl_frame.h"
2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "jni/jni_util.h"
2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "native/core/gl_env.h"
2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "native/core/gl_frame.h"
2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "native/core/native_frame.h"
2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennusing android::filterfw::GLEnv;
2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennusing android::filterfw::GLFrame;
2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennusing android::filterfw::NativeFrame;
2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Helper functions ////////////////////////////////////////////////////////////////////////////////
3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennvoid ConvertFloatsToRGBA(const float* floats, int length, uint8_t* result) {
3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  for (int i = 0; i < length; ++i) {
3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    result[i] = static_cast<uint8_t>(floats[i] * 255.0);
3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennvoid ConvertRGBAToFloats(const uint8_t* rgba, int length, float* result) {
3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  for (int i = 0; i < length; ++i) {
3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    result[i] = rgba[i] / 255.0;
4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// GLFrame JNI implementation //////////////////////////////////////////////////////////////////////
4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeAllocate(JNIEnv* env,
4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                           jobject thiz,
4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                           jobject gl_env,
4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                           jint width,
4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                           jint height) {
4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (!gl_env_ptr) return JNI_FALSE;
51315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV  std::unique_ptr<GLFrame> frame(new GLFrame(gl_env_ptr));
5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame->Init(width, height)) {
53315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV    return ToJBool(WrapOwnedObjectInJava(std::move(frame), env, thiz, true));
5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
55315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV  return JNI_FALSE;
5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeAllocateWithTexture(JNIEnv* env,
5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                      jobject thiz,
6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                      jobject gl_env,
6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                      jint tex_id,
6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                      jint width,
6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                      jint height) {
6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (!gl_env_ptr) return JNI_FALSE;
66315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV  std::unique_ptr<GLFrame> frame(new GLFrame(gl_env_ptr));
6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame->InitWithTexture(tex_id, width, height)) {
68315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV    return ToJBool(WrapOwnedObjectInJava(std::move(frame), env, thiz, true));
6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
70315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV  return JNI_FALSE;
7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeAllocateWithFbo(JNIEnv* env,
7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jobject thiz,
7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jobject gl_env,
7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jint fbo_id,
7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jint width,
7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jint height) {
7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (!gl_env_ptr) return JNI_FALSE;
81315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV  std::unique_ptr<GLFrame> frame(new GLFrame(gl_env_ptr));
8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame->InitWithFbo(fbo_id, width, height)) {
83315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV    return ToJBool(WrapOwnedObjectInJava(std::move(frame), env, thiz, true));
8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
85315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV  return JNI_FALSE;
8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeAllocateExternal(JNIEnv* env,
8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                   jobject thiz,
9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                   jobject gl_env) {
9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (!gl_env_ptr) return JNI_FALSE;
93315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV  std::unique_ptr<GLFrame> frame(new GLFrame(gl_env_ptr));
9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame->InitWithExternalTexture()) {
95315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV    return ToJBool(WrapOwnedObjectInJava(std::move(frame), env, thiz, true));
9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
97315c936a87eea1198cdfe118df0ba4c7b79bfaf8George Burgess IV  return JNI_FALSE;
9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeDeallocate(JNIEnv* env, jobject thiz) {
10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return ToJBool(DeleteNativeObject<GLFrame>(env, thiz));
10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeData(JNIEnv* env,
10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jobject thiz,
10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jbyteArray data,
10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jint offset,
10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jint length) {
10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && data) {
11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jbyte* bytes = env->GetByteArrayElements(data, NULL);
11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    if (bytes) {
11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      const bool success = frame->WriteData(reinterpret_cast<const uint8_t*>(bytes + offset), length);
11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      env->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      return ToJBool(success);
11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennjbyteArray Java_android_filterfw_core_GLFrame_getNativeData(JNIEnv* env, jobject thiz) {
12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && frame->Size() > 0) {
12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jbyteArray result = env->NewByteArray(frame->Size());
12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jbyte* data = env->GetByteArrayElements(result, NULL);
12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    frame->CopyDataTo(reinterpret_cast<uint8_t*>(data), frame->Size());
12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    env->ReleaseByteArrayElements(result, data, 0);
12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return result;
12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return NULL;
13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeInts(JNIEnv* env,
13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jobject thiz,
13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jintArray ints) {
13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && ints) {
13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jint* int_ptr = env->GetIntArrayElements(ints, NULL);
13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const int length = env->GetArrayLength(ints);
14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    if (int_ptr) {
14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      const bool success = frame->WriteData(reinterpret_cast<const uint8_t*>(int_ptr),
14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                            length * sizeof(jint));
14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      env->ReleaseIntArrayElements(ints, int_ptr, JNI_ABORT);
14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      return ToJBool(success);
14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennjintArray Java_android_filterfw_core_GLFrame_getNativeInts(JNIEnv* env, jobject thiz) {
15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && frame->Size() > 0 && (frame->Size() % sizeof(jint) == 0)) {
15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jintArray result = env->NewIntArray(frame->Size() / sizeof(jint));
15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jint* data = env->GetIntArrayElements(result, NULL);
15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    frame->CopyDataTo(reinterpret_cast<uint8_t*>(data), frame->Size());
15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    env->ReleaseIntArrayElements(result, data, 0);
15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return result;
15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn   }
15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn   return NULL;
16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
16165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
16265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeFloats(JNIEnv* env,
16365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jobject thiz,
16465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jfloatArray floats) {
16565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
16665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && floats) {
16765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jfloat* float_ptr = env->GetFloatArrayElements(floats, NULL);
16865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const int length = env->GetArrayLength(floats);
16965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    if (float_ptr) {
17065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      // Convert floats to RGBA buffer
17165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      uint8_t* rgba_buffer = new uint8_t[length];
17265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      ConvertFloatsToRGBA(float_ptr, length, rgba_buffer);
17365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      env->ReleaseFloatArrayElements(floats, float_ptr, JNI_ABORT);
17465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
17565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      // Write RGBA buffer to frame
17665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      const bool success = frame->WriteData(rgba_buffer, length);
17765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
17865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      // Clean-up
17965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      delete[] rgba_buffer;
18065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      return ToJBool(success);
18165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
18265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
18365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
18465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
18565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
18665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennjfloatArray Java_android_filterfw_core_GLFrame_getNativeFloats(JNIEnv* env, jobject thiz) {
18765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
18865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && frame->Size() > 0) {
18965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // Create the result array
19065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jfloatArray result = env->NewFloatArray(frame->Size());
19165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jfloat* float_array = env->GetFloatArrayElements(result, NULL);
19265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
19365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // Read the frame pixels
19465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    uint8_t* pixels = new uint8_t[frame->Size()];
19565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    frame->CopyDataTo(pixels, frame->Size());
19665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
19765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // Convert them to floats
19865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    ConvertRGBAToFloats(pixels, frame->Size(), float_array);
19965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
20065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // Clean-up
20165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    delete[] pixels;
20265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    env->ReleaseFloatArrayElements(result, float_array, 0);
20365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return result;
20465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
20565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return NULL;
20665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
20765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
20865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeBitmap(JNIEnv* env,
20965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jobject thiz,
21065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jobject bitmap,
21165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jint size) {
21265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
21365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && bitmap) {
21465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    uint8_t* pixels;
21565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&pixels));
216eba8254c8cae92d653c5203f65cb36f3fc724f9dAndrew Hsieh    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
21765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      const bool success = frame->WriteData(pixels, size);
21865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      return ToJBool(success &&
219eba8254c8cae92d653c5203f65cb36f3fc724f9dAndrew Hsieh                     AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
22065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
22165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
22265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
22365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
22465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
22565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_getNativeBitmap(JNIEnv* env,
22665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jobject thiz,
22765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jobject bitmap) {
22865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
22965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && bitmap) {
23065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    uint8_t* pixels;
23165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&pixels));
232eba8254c8cae92d653c5203f65cb36f3fc724f9dAndrew Hsieh    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
23365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      frame->CopyDataTo(pixels, frame->Size());
234eba8254c8cae92d653c5203f65cb36f3fc724f9dAndrew Hsieh      return (AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
23565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
23665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
23765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
23865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
23965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
24065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeViewport(JNIEnv* env,
24165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                              jobject thiz,
24265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                              jint x,
24365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                              jint y,
24465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                              jint width,
24565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                              jint height) {
24665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
24765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? ToJBool(frame->SetViewport(x, y, width, height)) : JNI_FALSE;
24865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
24965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
25065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjint Java_android_filterfw_core_GLFrame_getNativeTextureId(JNIEnv* env, jobject thiz) {
25165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
25265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? frame->GetTextureId() : -1;
25365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
25465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
25565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjint Java_android_filterfw_core_GLFrame_getNativeFboId(JNIEnv* env, jobject thiz) {
25665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
25765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? frame->GetFboId() : -1;
25865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
25965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
26065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_generateNativeMipMap(JNIEnv* env, jobject thiz) {
26165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
26265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? ToJBool(frame->GenerateMipMap()) : JNI_FALSE;
26365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
26465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
26565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeTextureParam(JNIEnv* env,
26665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jobject thiz,
26765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jint param,
26865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jint value) {
26965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
27065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? ToJBool(frame->SetTextureParameter(param, value)) : JNI_FALSE;
27165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
27265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
27365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeResetParams(JNIEnv* env, jobject thiz) {
27465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
27565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? ToJBool(frame->ResetTexParameters()) : JNI_FALSE;
27665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
27765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
27865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeCopyFromNative(JNIEnv* env,
27965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                 jobject thiz,
28065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                 jobject frame) {
28165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* this_frame = ConvertFromJava<GLFrame>(env, thiz);
28265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  NativeFrame* other_frame = ConvertFromJava<NativeFrame>(env, frame);
28365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (this_frame && other_frame) {
28465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return ToJBool(this_frame->WriteData(other_frame->Data(), other_frame->Size()));
28565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
28665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
28765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
28865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
28965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeCopyFromGL(JNIEnv* env,
29065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                             jobject thiz,
29165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                             jobject frame) {
29265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* this_frame = ConvertFromJava<GLFrame>(env, thiz);
29365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* other_frame = ConvertFromJava<GLFrame>(env, frame);
29465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (this_frame && other_frame) {
29565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return ToJBool(this_frame->CopyPixelsFrom(other_frame));
29665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
29765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
29865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
29965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
30065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeFocus(JNIEnv* env, jobject thiz) {
30165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
30265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return ToJBool(frame && frame->FocusFrameBuffer());
30365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
30465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
30565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeReattachTexToFbo(JNIEnv* env, jobject thiz) {
30665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
30765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return ToJBool(frame && frame->ReattachTextureToFbo());
30865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
30965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
31065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeDetachTexFromFbo(JNIEnv* env, jobject thiz) {
31165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
31265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return ToJBool(frame && frame->DetachTextureFromFbo());
31365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
31465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
315