0

I have the following JNI method which I want to convert to Android's RenderScript because that would make my project a little bit simpler to manage.

Here is the JNI method:

static void applyRGBCurve(int width, int height, int *pixels, int *rgb) {
    int R[256];
    int G[256];
    int B[256];

    // It seems that they extract the RGB components here
    // to build up a lookup table
    // so, we end up with lookup table for the RED component, GREEN component, BLUE component of each pixel
    for (int i = 0; i < 256; i++) {
        R[i] = (rgb[i] << 16) & 0x00FF0000;
        G[i] = (rgb[i] << 8) & 0x0000FF00;
        B[i] = rgb[i] & 0x000000FF;
    }

    for (int i = 0; i < width * height; i++) {
        // using the lookup tables, they construct each pixel
        pixels[i] =
                (0xFF000000 & pixels[i]) | (R[(pixels[i] >> 16) & 0xFF]) | (G[(pixels[i] >> 8) & 0xFF]) | (B[pixels[i] & 0xFF]);
    }
}

I am new to RenderScript. So I am thankful for any help.

Here is what I tried:

#pragma version(1)
#pragma rs java_package_name(com.example.imageprocessinginkotlin)
#pragma rs_fp_relaxed

int rgb[256];
uint32_t R[256];
uint32_t G[256];
uint32_t B[256];

void prepareChannels(){

    for (int i = 0; i < 256; i++) {
        // HERE I did not know how to apply shift operations in Renderscript
        R[i] = rgb[i] & 0xFF;           
        G[i] = rgb[i] & 0xFF;
        B[i] = rgb[i] & 0xFF;
    }
}

uchar4 RS_KERNEL applyRGBCurve(uchar4 in){

    uchar4 out;

    out.a = in.a;
    out.r = R[in.r];
    out.g = G[in.g];
    out.b = B[in.b];

    return out;
}

From the Java side, it looks like this:

val rs = RenderScript.create(activity)
allocationIn = Allocation.createFromBitmap(rs, bitmap)
allocationOut = Allocation.createFromBitmap(rs, bitmap)

script = ScriptC_tonecurve(rs)

script.set_rgb(item.rgb.toIntArray())
script.invoke_prepareChannels()
script.forEach_applyRGBCurve(allocationIn, allocationOut)
allocationOut.copyTo(bitmap)
binding.imageView.setImageBitmap(bitmap)

Is my Renderscript code an equivalent to the JNI method ? I would say not because the shift operations are missing (compared to the JNI method).

ebeninki
  • 909
  • 1
  • 12
  • 34
  • It's not clear exactly what you're having trouble with. If you don't know the basics of RenderScript, then the simple answer is that you need to learn it. – Michael May 08 '20 at 12:32
  • @Michael: I updated my question. I added my solution to it and hope that some "experts" in RenderScript can help to improve my code if it is wrong. – ebeninki May 08 '20 at 12:51
  • Have you tried splitting out the three channels in Kotlin and setting them on the renderscript program before the `apply` call? – Botje May 08 '20 at 13:34
  • I tried to replicate that what it is in the applyRGBCurve() method by using RenderScript instead of the JNI. Dont know what you mean. – ebeninki May 08 '20 at 15:37
  • You can replace shift with arithmetic operations, but it looks like your R, G and B lookup-tables are just the same, so you can use the same 256-byte LUT for all colors. – Alex Cohn May 09 '20 at 11:56

0 Answers0