Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a45de8c authored by Jason Sams's avatar Jason Sams
Browse files

Add film grain test.

Change-Id: Ic7c7d7f66fbcf9a9e7a031a4c34f9a1372f0a7b7
parent 52541816
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.rs.image;

import java.lang.Math;

import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.Script;
import android.renderscript.ScriptC;
import android.renderscript.Type;
import android.util.Log;
import android.widget.SeekBar;
import android.widget.TextView;

public class Grain extends TestBase {
    private ScriptC_grain mScript;
    private Allocation mNoise;
    private Allocation mNoise2;


    public boolean onBar1Setup(SeekBar b, TextView t) {
        t.setText("Strength");
        b.setProgress(50);
        return true;
    }

    public void onBar1Changed(int progress) {
        float s = progress / 100.0f;
        mScript.set_gNoiseStrength(s);
    }

    public void createTest(android.content.res.Resources res) {
        int width = mInPixelsAllocation.getType().getX();
        int height = mInPixelsAllocation.getType().getY();

        Type.Builder tb = new Type.Builder(mRS, Element.U8(mRS));
        tb.setX(width);
        tb.setY(height);
        mNoise = Allocation.createTyped(mRS, tb.create());
        mNoise2 = Allocation.createTyped(mRS, tb.create());

        mScript = new ScriptC_grain(mRS, res, R.raw.grain);
        mScript.set_gWidth(width);
        mScript.set_gHeight(height);
        mScript.set_gNoiseStrength(0.5f);
        mScript.set_gBlendSource(mNoise);
        mScript.set_gNoise(mNoise2);
    }

    public void runTest() {
        mScript.forEach_genRand(mNoise);
        mScript.forEach_blend9(mNoise2);
        mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
    }

}
+5 −1
Original line number Diff line number Diff line
@@ -140,6 +140,9 @@ public class ImageProcessingActivity extends Activity
        case 5:
            mTest = new Greyscale();
            break;
        case 6:
            mTest = new Grain();
            break;
        }

        mTest.createBaseTest(this, mBitmapIn);
@@ -152,13 +155,14 @@ public class ImageProcessingActivity extends Activity
    }

    void setupTests() {
        mTestNames = new String[6];
        mTestNames = new String[7];
        mTestNames[0] = "Levels Vec3 Relaxed";
        mTestNames[1] = "Levels Vec4 Relaxed";
        mTestNames[2] = "Levels Vec3 Full";
        mTestNames[3] = "Levels Vec4 Full";
        mTestNames[4] = "Blur radius 25";
        mTestNames[5] = "Greyscale";
        mTestNames[6] = "Grain";
        mTestSpinner.setAdapter(new ArrayAdapter<String>(
            this, R.layout.spinner_layout, mTestNames));
    }
+92 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed

void genRand(uchar *out) {
    *out = (uchar)rsRand(0xff);
}

/*
 * Convolution matrix of distance 2 with fixed point of 'kShiftBits' bits
 * shifted. Thus the sum of this matrix should be 'kShiftValue'. Entries of
 * small values are not calculated to gain efficiency.
 * The order ot pixels represented in this matrix is:
 *  1  2  3
 *  4  0  5
 *  6  7  8
 *  and the matrix should be: {230, 56, 114, 56, 114, 114, 56, 114, 56}.
 *  However, since most of the valus are identical, we only use the first three
 *  entries and the entries corresponding to the pixels is:
 *  1  2  1
 *  2  0  2
 *  1  2  1
 */

int32_t gWidth;
int32_t gHeight;

rs_allocation gBlendSource;
void blend9(uchar *out, uint32_t x, uint32_t y) {
    uint32_t x1 = min(x+1, (uint32_t)gWidth);
    uint32_t x2 = max(x-1, (uint32_t)0);
    uint32_t y1 = min(y+1, (uint32_t)gHeight);
    uint32_t y2 = max(y-1, (uint32_t)0);

    uint p00 = 56 *  ((uchar *)rsGetElementAt(gBlendSource, x1, y1))[0];
    uint p01 = 114 * ((uchar *)rsGetElementAt(gBlendSource, x, y1))[0];
    uint p02 = 56 *  ((uchar *)rsGetElementAt(gBlendSource, x2, y1))[0];
    uint p10 = 114 * ((uchar *)rsGetElementAt(gBlendSource, x1, y))[0];
    uint p11 = 230 * ((uchar *)rsGetElementAt(gBlendSource, x, y))[0];
    uint p12 = 114 * ((uchar *)rsGetElementAt(gBlendSource, x2, y))[0];
    uint p20 = 56 *  ((uchar *)rsGetElementAt(gBlendSource, x1, y2))[0];
    uint p21 = 114 * ((uchar *)rsGetElementAt(gBlendSource, x, y2))[0];
    uint p22 = 56 *  ((uchar *)rsGetElementAt(gBlendSource, x2, y2))[0];

    p00 += p01;
    p02 += p10;
    p11 += p12;
    p20 += p21;

    p22 += p00;
    p02 += p11;

    p20 += p22;
    p20 += p02;

    *out = (uchar)(p20 >> 10);
}

float gNoiseStrength;

rs_allocation gNoise;
void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
    float4 ip = convert_float4(*in);
    float pnoise = (float) ((uchar *)rsGetElementAt(gNoise, x, y))[0];

    float energy_level = ip.r + ip.g + ip.b;
    float energy_mask = (28.f - sqrt(energy_level)) * 0.03571f;
    pnoise = (pnoise - 128.f) * energy_mask;

    ip += pnoise * gNoiseStrength;
    ip = clamp(ip, 0.f, 255.f);

    uchar4 p = convert_uchar4(ip);
    p.a = 0xff;
    *out = p;
}