java - JNI + 类型转换(例如,Signed Short 到 Unsigned Short)

标签 java android c java-native-interface type-conversion

我在 JNI hell 中进行类型转换:

这是一般的流程:

  • 读取一个文件,它返回一个 一维 float 组。
  • 转换这些 floats[] 到 shorts[](*4095,我想要一个 12位数字)
  • 将这些短裤[]传递给 C,将它们复制到 无符号短数组
  • 翻转位 制作big-endian java位 用于图像处理的小端
  • 将这些新数字转换成 双[] (/4095)
  • 将 double[] 传递给 图像处理函数
  • 将处理后的 double[] 转换回 short[] (*4095)
  • 简而言之[]翻转位回到 大端
  • 将 short[] 转换回 float (/4095),传回 java
  • 将 float[] 传递给 int 将位排列为的转换 ARGB_8888格式

一定有更好的方法来做到这一点。

最糟糕的是,它不起作用。我恢复了所有噪音,我觉得这可能是 C 中无符号短数组(对位切换有用)和 C 中有符号短数组的结果。这是一个主要问题。

所以我想我的一般问题是,我该如何改进它,这样我就不会处理所有这些类型之间的转换问题,包括签名/未签名问题。

我们将不胜感激您的任何建议..

最佳答案

我没有看到中间short 表示的好处,因为 Java 代码使用 float ,而 C 代码使用 double 。我会做这样的事情:

float[] floats = readFile();

// Convert to little-endian doubles
ByteBuffer bb = ByteBuffer.allocateDirect(4 * floats.length);
bb.order(ByteOrder.LITTLE_ENDIAN);
DoubleBuffer db = bb.asDoubleBuffer();
for (int i = 0; i < floats.length; ++ i) {
    db.put(i, floats[i]);
}

doImageProcessing(bb); // Native method

// Convert double values to ARGB
int j = 0;
int[] argb = new int[floats.length / 4];
for (int i = 0; i < floats.length; i += 4) {
    int a = Math.max(0, Math.min((int) (db.get(i) * 256.0), 255));
    int r = Math.max(0, Math.min((int) (db.get(i+1) * 256.0), 255));
    int g = Math.max(0, Math.min((int) (db.get(i+2) * 256.0), 255));
    int b = Math.max(0, Math.min((int) (db.get(i+3) * 256.0), 255));
    argb[j++] = (a<<24)|(r<<16)|(g<<8)|b;
}

关于java - JNI + 类型转换(例如,Signed Short 到 Unsigned Short),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4848731/

相关文章:

java - libgdx 的模型纹理错误

java - "Endless"来自套接字的 AudioInputStream

java - 在测试用例期间部署工件 - JBoss AS

android - Android 源代码覆盖如何工作?

java - W/System.err : java.net.ConnectException:连接超时

java - 附加实体是否需要在 JPA 中合并?

c - Printf 和 scanf 无法正常工作? C语言编程

c - 将文本文件读取到某一点并在该点输入数据

C sscanf 每次都转字符串的开头

安卓 : Static Fields and Memory Leaks