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;
5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = new GLFrame(gl_env_ptr);
5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame->Init(width, height)) {
5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  } else {
5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    delete frame;
5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return JNI_FALSE;
5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeAllocateWithTexture(JNIEnv* env,
6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                      jobject thiz,
6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                      jobject gl_env,
6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                      jint tex_id,
6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                      jint width,
6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                      jint height) {
6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (!gl_env_ptr) return JNI_FALSE;
6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = new GLFrame(gl_env_ptr);
6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame->InitWithTexture(tex_id, width, height)) {
7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  } else {
7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    delete frame;
7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return JNI_FALSE;
7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeAllocateWithFbo(JNIEnv* env,
7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jobject thiz,
7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jobject gl_env,
8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jint fbo_id,
8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jint width,
8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jint height) {
8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (!gl_env_ptr) return JNI_FALSE;
8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = new GLFrame(gl_env_ptr);
8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame->InitWithFbo(fbo_id, width, height)) {
8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  } else {
8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    delete frame;
9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return JNI_FALSE;
9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeAllocateExternal(JNIEnv* env,
9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                   jobject thiz,
9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                   jobject gl_env) {
9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (!gl_env_ptr) return JNI_FALSE;
9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = new GLFrame(gl_env_ptr);
10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame->InitWithExternalTexture()) {
10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  } else {
10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    delete frame;
10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return JNI_FALSE;
10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeDeallocate(JNIEnv* env, jobject thiz) {
10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return ToJBool(DeleteNativeObject<GLFrame>(env, thiz));
11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeData(JNIEnv* env,
11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jobject thiz,
11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jbyteArray data,
11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jint offset,
11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jint length) {
11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && data) {
11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jbyte* bytes = env->GetByteArrayElements(data, NULL);
12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    if (bytes) {
12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      const bool success = frame->WriteData(reinterpret_cast<const uint8_t*>(bytes + offset), length);
12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      env->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      return ToJBool(success);
12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennjbyteArray Java_android_filterfw_core_GLFrame_getNativeData(JNIEnv* env, jobject thiz) {
13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && frame->Size() > 0) {
13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jbyteArray result = env->NewByteArray(frame->Size());
13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jbyte* data = env->GetByteArrayElements(result, NULL);
13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    frame->CopyDataTo(reinterpret_cast<uint8_t*>(data), frame->Size());
13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    env->ReleaseByteArrayElements(result, data, 0);
13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return result;
13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return NULL;
13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeInts(JNIEnv* env,
14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jobject thiz,
14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                          jintArray ints) {
14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && ints) {
14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jint* int_ptr = env->GetIntArrayElements(ints, NULL);
14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const int length = env->GetArrayLength(ints);
14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    if (int_ptr) {
14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      const bool success = frame->WriteData(reinterpret_cast<const uint8_t*>(int_ptr),
15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                            length * sizeof(jint));
15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      env->ReleaseIntArrayElements(ints, int_ptr, JNI_ABORT);
15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      return ToJBool(success);
15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennjintArray Java_android_filterfw_core_GLFrame_getNativeInts(JNIEnv* env, jobject thiz) {
15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && frame->Size() > 0 && (frame->Size() % sizeof(jint) == 0)) {
16165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jintArray result = env->NewIntArray(frame->Size() / sizeof(jint));
16265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jint* data = env->GetIntArrayElements(result, NULL);
16365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    frame->CopyDataTo(reinterpret_cast<uint8_t*>(data), frame->Size());
16465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    env->ReleaseIntArrayElements(result, data, 0);
16565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return result;
16665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn   }
16765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn   return NULL;
16865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
16965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
17065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeFloats(JNIEnv* env,
17165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jobject thiz,
17265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jfloatArray floats) {
17365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
17465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && floats) {
17565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jfloat* float_ptr = env->GetFloatArrayElements(floats, NULL);
17665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const int length = env->GetArrayLength(floats);
17765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    if (float_ptr) {
17865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      // Convert floats to RGBA buffer
17965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      uint8_t* rgba_buffer = new uint8_t[length];
18065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      ConvertFloatsToRGBA(float_ptr, length, rgba_buffer);
18165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      env->ReleaseFloatArrayElements(floats, float_ptr, JNI_ABORT);
18265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
18365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      // Write RGBA buffer to frame
18465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      const bool success = frame->WriteData(rgba_buffer, length);
18565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
18665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      // Clean-up
18765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      delete[] rgba_buffer;
18865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      return ToJBool(success);
18965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
19065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
19165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
19265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
19365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
19465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennjfloatArray Java_android_filterfw_core_GLFrame_getNativeFloats(JNIEnv* env, jobject thiz) {
19565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
19665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && frame->Size() > 0) {
19765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // Create the result array
19865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jfloatArray result = env->NewFloatArray(frame->Size());
19965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jfloat* float_array = env->GetFloatArrayElements(result, NULL);
20065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
20165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // Read the frame pixels
20265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    uint8_t* pixels = new uint8_t[frame->Size()];
20365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    frame->CopyDataTo(pixels, frame->Size());
20465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
20565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // Convert them to floats
20665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    ConvertRGBAToFloats(pixels, frame->Size(), float_array);
20765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
20865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    // Clean-up
20965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    delete[] pixels;
21065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    env->ReleaseFloatArrayElements(result, float_array, 0);
21165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return result;
21265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
21365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return NULL;
21465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
21565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
21665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeBitmap(JNIEnv* env,
21765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jobject thiz,
21865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jobject bitmap,
21965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jint size) {
22065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
22165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && bitmap) {
22265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    uint8_t* pixels;
22365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&pixels));
224eba8254c8cae92d653c5203f65cb36f3fc724f9dAndrew Hsieh    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
22565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      const bool success = frame->WriteData(pixels, size);
22665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      return ToJBool(success &&
227eba8254c8cae92d653c5203f65cb36f3fc724f9dAndrew Hsieh                     AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
22865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
22965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
23065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
23165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
23265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
23365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_getNativeBitmap(JNIEnv* env,
23465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jobject thiz,
23565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                            jobject bitmap) {
23665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
23765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (frame && bitmap) {
23865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    uint8_t* pixels;
23965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    const int result = AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void**>(&pixels));
240eba8254c8cae92d653c5203f65cb36f3fc724f9dAndrew Hsieh    if (result == ANDROID_BITMAP_RESULT_SUCCESS) {
24165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      frame->CopyDataTo(pixels, frame->Size());
242eba8254c8cae92d653c5203f65cb36f3fc724f9dAndrew Hsieh      return (AndroidBitmap_unlockPixels(env, bitmap) == ANDROID_BITMAP_RESULT_SUCCESS);
24365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    }
24465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
24565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
24665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
24765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
24865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeViewport(JNIEnv* env,
24965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                              jobject thiz,
25065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                              jint x,
25165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                              jint y,
25265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                              jint width,
25365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                              jint height) {
25465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
25565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? ToJBool(frame->SetViewport(x, y, width, height)) : JNI_FALSE;
25665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
25765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
25865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjint Java_android_filterfw_core_GLFrame_getNativeTextureId(JNIEnv* env, jobject thiz) {
25965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
26065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? frame->GetTextureId() : -1;
26165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
26265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
26365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjint Java_android_filterfw_core_GLFrame_getNativeFboId(JNIEnv* env, jobject thiz) {
26465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
26565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? frame->GetFboId() : -1;
26665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
26765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
26865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_generateNativeMipMap(JNIEnv* env, jobject thiz) {
26965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
27065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? ToJBool(frame->GenerateMipMap()) : JNI_FALSE;
27165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
27265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
27365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_setNativeTextureParam(JNIEnv* env,
27465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jobject thiz,
27565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jint param,
27665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                  jint value) {
27765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
27865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? ToJBool(frame->SetTextureParameter(param, value)) : JNI_FALSE;
27965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
28065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
28165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeResetParams(JNIEnv* env, jobject thiz) {
28265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
28365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return frame ? ToJBool(frame->ResetTexParameters()) : JNI_FALSE;
28465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
28565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
28665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeCopyFromNative(JNIEnv* env,
28765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                 jobject thiz,
28865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                                 jobject frame) {
28965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* this_frame = ConvertFromJava<GLFrame>(env, thiz);
29065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  NativeFrame* other_frame = ConvertFromJava<NativeFrame>(env, frame);
29165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (this_frame && other_frame) {
29265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return ToJBool(this_frame->WriteData(other_frame->Data(), other_frame->Size()));
29365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
29465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
29565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
29665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
29765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeCopyFromGL(JNIEnv* env,
29865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                             jobject thiz,
29965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                             jobject frame) {
30065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* this_frame = ConvertFromJava<GLFrame>(env, thiz);
30165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* other_frame = ConvertFromJava<GLFrame>(env, frame);
30265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if (this_frame && other_frame) {
30365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return ToJBool(this_frame->CopyPixelsFrom(other_frame));
30465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  }
30565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return JNI_FALSE;
30665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
30765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
30865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeFocus(JNIEnv* env, jobject thiz) {
30965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
31065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return ToJBool(frame && frame->FocusFrameBuffer());
31165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
31265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
31365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeReattachTexToFbo(JNIEnv* env, jobject thiz) {
31465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
31565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return ToJBool(frame && frame->ReattachTextureToFbo());
31665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
31765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
31865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean Java_android_filterfw_core_GLFrame_nativeDetachTexFromFbo(JNIEnv* env, jobject thiz) {
31965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  GLFrame* frame = ConvertFromJava<GLFrame>(env, thiz);
32065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return ToJBool(frame && frame->DetachTextureFromFbo());
32165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
32265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
323