Преобразование типов JNI + (например, подписанный короткий в неподписанный короткий)

1

Я нахожусь в JNI hell с typeconversions out wazoo:

Здесь общий поток вещей:

  • прочитайте файл, и он возвращает меня с помощью 1D массивов поплавков.
  • конвертировать эти плавает [] в шортах [] (* 4095, я хочу 12-разрядное число)
  • передать эти шорты [] в C, который дублирует их в unsigned short array
  • флип бит вокруг создавать бинарные биты little-endian для обработки изображений.
  • преобразуйте эти новые числа в double [] (/4095)
  • передать двойную [] в функция обработки изображений
  • конвертировать обработанный double [] назад в короткий [] (* 4095)
  • коротко свернуть бит [] назад big-endian
  • конвертировать short [] назад в float (/4095), перейти обратно в java
  • передать float [] в int преобразование, которое устанавливает биты в Формат ARGB_8888

У GOT есть лучший способ сделать это.

Помимо всего этого дерьма, он не работает. Я возвращаю все шумы, которые, как я считаю, могут быть результатом беззнаковых коротких массивов в C (полезно для переключения бит) и подписанных коротких массивов в C. Это серьезная проблема.

Итак, я думаю, мой общий вопрос заключается в том, как я могу улучшить это, чтобы я не имел дело со всеми этими проблемами при преобразовании типов, включая проблемы с подписью/без знака.

Все, что вы можете предложить, оценят.

Теги:
type-conversion
jni

1 ответ

2
Лучший ответ

Я не вижу преимущества промежуточного представления short, поскольку код Java работает с поплавками, а код C работает с удвоениями. Я бы сделал что-то вроде этого:

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;
}
  • 0
    Единственная причина коротких замыканий в этом рабочем процессе заключается в том, что нативная функция требует порядка битов с прямым порядком байтов, в то время как данные инициализируются в старшем порядке.
  • 0
    Вы правы, мне не нужен этот промежуточный шаг. Благодарю. Это здорово.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню