Brian D
Brian D

Reputation: 10143

JNI + Type Conversion (Signed Short to Unsigned Short, for example)

I'm in JNI hell with typeconversions out the wazoo:

Here's the general flow of things:

There has GOT to be a better way to do this.

On top of all that crap, it's not working. I'm getting back all noise, which I feel might be a result of the unsigned short arrays in C (useful for bit-switching) and the signed short arrays in C. This is a major problem.

So I guess my general question is, how can I improve this so that I'm not dealing with all of these problems converting between types, including signed/unsigned issues.

Anything you can suggest will be appreciated..

Upvotes: 1

Views: 1429

Answers (1)

finnw
finnw

Reputation: 48629

I don't see the benefit of having an intermediate short representation, since the Java code works with floats and the C code works with doubles. I would do something like this:

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;
}

Upvotes: 2

Related Questions