Merge "Update IP and IP2" into jb-mr2-dev

This commit is contained in:
Jason Sams
2013-03-08 22:34:04 +00:00
committed by Android (Google) Code Review
75 changed files with 1351 additions and 303 deletions

View File

@ -18,7 +18,6 @@ package com.android.rs.image;
import java.lang.Math;
import android.renderscript.Allocation;
public class BWFilter extends TestBase {
private ScriptC_bwfilter mScript;

View File

@ -12,8 +12,7 @@
// 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)
#include "ip.rsh"
uchar alpha = 0x0;

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#include "ip.rsh"
//#pragma rs_fp_relaxed
static float sr = 0.f;

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#include "ip.rsh"
#pragma rs_fp_relaxed

View File

@ -14,10 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed
#include "ip.rsh"
static rs_matrix4x4 Mat;

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_full
#include "ip.rsh"
static float brightM = 0.f;
static float brightC = 0.f;

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed
#include "ip.rsh"
int32_t gWidth;
int32_t gHeight;

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed
#include "ip.rsh"
int32_t gWidth;
int32_t gHeight;

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#include "ip.rsh"
uchar4 __attribute__((kernel)) root(uchar4 v_in) {
return v_in;

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_full
#include "ip.rsh"
static float bright = 0.f;

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#include "ip.rsh"
#include "fisheye_approx.rsh"

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed
#include "ip.rsh"
#include "fisheye_approx.rsh"

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#include "ip.rsh"
#include "fisheye.rsh"

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed
#include "ip.rsh"
#include "fisheye.rsh"

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed
#include "ip.rsh"
uchar __attribute__((kernel)) genRand() {
return (uchar)rsRand(0xff);

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed
#include "ip.rsh"
const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};

View File

@ -0,0 +1,20 @@
/*
* Copyright (C) 2013 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)

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#include "ip.rsh"
#include "levels.rsh"

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed
#include "ip.rsh"
#include "levels.rsh"

View File

@ -12,8 +12,7 @@
// 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)
#include "ip.rsh"
uint32_t gMaxIteration = 500;
uint32_t gDimX = 1024;

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#include "ip.rsh"
//#pragma rs_fp_relaxed
static double shadowFilterMap[] = {

View File

@ -1,6 +1,20 @@
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed
/*
* Copyright (C) 2013 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.
*/
#include "ip.rsh"
int height;

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#include "ip.rsh"
float vibrance = 0.f;

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#include "ip.rsh"
#include "vignette_approx.rsh"

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed
#include "ip.rsh"
#include "vignette_approx.rsh"

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#include "ip.rsh"
#include "vignette.rsh"

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#pragma rs_fp_relaxed
#include "ip.rsh"
#include "vignette.rsh"

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image)
#include "ip.rsh"
//#pragma rs_fp_relaxed
static int histR[256] = {0}, histG[256] = {0}, histB[256] = {0};

View File

@ -26,8 +26,8 @@ LOCAL_STATIC_JAVA_LIBRARIES := android.support.v8.renderscript
LOCAL_PACKAGE_NAME := ImageProcessing2
LOCAL_SDK_VERSION := 8
LOCAL_RENDERSCRIPT_TARGET_API := 17
LOCAL_RENDERSCRIPT_COMPATIBILITY := 17
LOCAL_RENDERSCRIPT_TARGET_API := 18
LOCAL_RENDERSCRIPT_COMPATIBILITY := 18
LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE := $(TOPDIR)external/clang/lib/Headers \
$(TOPDIR)frameworks/rs/scriptc

View File

@ -0,0 +1,34 @@
/*
* 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.image2;
import java.lang.Math;
public class BWFilter extends TestBase {
private ScriptC_bwfilter mScript;
public void createTest(android.content.res.Resources res) {
mScript = new ScriptC_bwfilter(mRS);
}
public void runTest() {
mScript.invoke_prepareBwFilter(50, 50, 50);
mScript.forEach_bwFilterKernel(mInPixelsAllocation, mOutPixelsAllocation);
}
}

View File

@ -44,8 +44,10 @@ public class Blend extends TestBase {
new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
currentIntrinsic = pos;
runTest();
act.updateDisplay();
if (mRS != null) {
runTest();
act.updateDisplay();
}
}
public void onNothingSelected(AdapterView parent) {

View File

@ -0,0 +1,93 @@
/*
* 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.image2;
import java.lang.Math;
import android.graphics.Bitmap;
import android.support.v8.renderscript.*;
import android.util.Log;
import android.widget.SeekBar;
import android.widget.TextView;
public class Blur25G extends TestBase {
private final int MAX_RADIUS = 25;
private float mRadius = MAX_RADIUS;
private ScriptIntrinsicBlur mIntrinsic;
private ScriptC_greyscale mScript;
private Allocation mScratchPixelsAllocation1;
private Allocation mScratchPixelsAllocation2;
public Blur25G() {
}
public boolean onBar1Setup(SeekBar b, TextView t) {
t.setText("Radius");
b.setProgress(100);
return true;
}
public void onBar1Changed(int progress) {
mRadius = ((float)progress) / 100.0f * MAX_RADIUS;
if (mRadius <= 0.10f) {
mRadius = 0.10f;
}
mIntrinsic.setRadius(mRadius);
}
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);
mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create());
mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create());
mScript = new ScriptC_greyscale(mRS);
mScript.forEach_toU8(mInPixelsAllocation, mScratchPixelsAllocation1);
mIntrinsic = ScriptIntrinsicBlur.create(mRS, Element.U8(mRS));
mIntrinsic.setRadius(MAX_RADIUS);
mIntrinsic.setInput(mScratchPixelsAllocation1);
}
public void runTest() {
mIntrinsic.forEach(mScratchPixelsAllocation2);
}
public void setupBenchmark() {
mIntrinsic.setRadius(MAX_RADIUS);
}
public void exitBenchmark() {
mIntrinsic.setRadius(mRadius);
}
public void updateBitmap(Bitmap b) {
mScript.forEach_toU8_4(mScratchPixelsAllocation2, mOutPixelsAllocation);
mOutPixelsAllocation.copyTo(b);
}
}

View File

@ -0,0 +1,79 @@
/*
* 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.image2;
import java.lang.Math;
import android.support.v8.renderscript.*;
import android.util.Log;
public class ColorCube extends TestBase {
private Allocation mCube;
private ScriptC_colorcube mScript;
private ScriptIntrinsic3DLUT mIntrinsic;
private boolean mUseIntrinsic;
public ColorCube(boolean useIntrinsic) {
mUseIntrinsic = useIntrinsic;
}
private void initCube() {
final int sx = 32;
final int sy = 32;
final int sz = 16;
Type.Builder tb = new Type.Builder(mRS, Element.U8_4(mRS));
tb.setX(sx);
tb.setY(sy);
tb.setZ(sz);
Type t = tb.create();
mCube = Allocation.createTyped(mRS, t);
int dat[] = new int[sx * sy * sz];
for (int z = 0; z < sz; z++) {
for (int y = 0; y < sy; y++) {
for (int x = 0; x < sx; x++ ) {
int v = 0xff000000;
v |= (0xff * x / (sx - 1));
v |= (0xff * y / (sy - 1)) << 8;
v |= (0xff * z / (sz - 1)) << 16;
dat[z*sy*sx + y*sx + x] = v;
}
}
}
mCube.copyFromUnchecked(dat);
}
public void createTest(android.content.res.Resources res) {
mScript = new ScriptC_colorcube(mRS, res, R.raw.colorcube);
mIntrinsic = ScriptIntrinsic3DLUT.create(mRS, Element.U8_4(mRS));
initCube();
mScript.invoke_setCube(mCube);
mIntrinsic.setLUT(mCube);
}
public void runTest() {
if (mUseIntrinsic) {
mIntrinsic.forEach(mInPixelsAllocation, mOutPixelsAllocation);
} else {
mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
}
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.image2;
import java.lang.Math;
public class Contrast extends TestBase {
private ScriptC_contrast mScript;
public void createTest(android.content.res.Resources res) {
mScript = new ScriptC_contrast(mRS);
}
public void runTest() {
mScript.invoke_setBright(50.f);
mScript.forEach_contrast(mInPixelsAllocation, mOutPixelsAllocation);
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.image2;
import java.lang.Math;
import android.support.v8.renderscript.*;
public class Exposure extends TestBase {
private ScriptC_exposure mScript;
public void createTest(android.content.res.Resources res) {
mScript = new ScriptC_exposure(mRS);
}
public void runTest() {
mScript.invoke_setBright(50.f);
mScript.forEach_exposure(mInPixelsAllocation, mOutPixelsAllocation);
}
}

View File

@ -16,9 +16,6 @@
package com.android.rs.image2;
import java.lang.Math;
import android.support.v8.renderscript.*;
import android.util.Log;
public class Greyscale extends TestBase {

View File

@ -47,12 +47,73 @@ import java.io.IOException;
public class ImageProcessingActivity2 extends Activity
implements SeekBar.OnSeekBarChangeListener {
private final String TAG = "Img";
private final String RESULT_FILE = "image_processing_result.csv";
public final String RESULT_FILE = "image_processing_result.csv";
RenderScript mRS;
Allocation mInPixelsAllocation;
Allocation mInPixelsAllocation2;
Allocation mOutPixelsAllocation;
/**
* Define enum type for test names
*/
public enum TestName {
// totally there are 38 test cases
LEVELS_VEC3_RELAXED ("Levels Vec3 Relaxed"),
LEVELS_VEC4_RELAXED ("Levels Vec4 Relaxed"),
LEVELS_VEC3_FULL ("Levels Vec3 Full"),
LEVELS_VEC4_FULL ("Levels Vec4 Full"),
BLUR_RADIUS_25 ("Blur radius 25"),
INTRINSIC_BLUE_RADIUS_25 ("Intrinsic Blur radius 25"),
GREYSCALE ("Greyscale"),
GRAIN ("Grain"),
FISHEYE_FULL ("Fisheye Full"),
FISHEYE_RELAXED ("Fisheye Relaxed"),
FISHEYE_APPROXIMATE_FULL ("Fisheye Approximate Full"),
FISHEYE_APPROXIMATE_RELAXED ("Fisheye Approximate Relaxed"),
VIGNETTE_FULL ("Vignette Full"),
VIGNETTE_RELAXED ("Vignette Relaxed"),
VIGNETTE_APPROXIMATE_FULL ("Vignette Approximate Full"),
VIGNETTE_APPROXIMATE_RELAXED ("Vignette Approximate Relaxed"),
GROUP_TEST_EMULATED ("Group Test (emulated)"),
GROUP_TEST_NATIVE ("Group Test (native)"),
CONVOLVE_3X3 ("Convolve 3x3"),
INTRINSICS_CONVOLVE_3X3 ("Intrinsics Convolve 3x3"),
COLOR_MATRIX ("ColorMatrix"),
INTRINSICS_COLOR_MATRIX ("Intrinsics ColorMatrix"),
INTRINSICS_COLOR_MATRIX_GREY ("Intrinsics ColorMatrix Grey"),
COPY ("Copy"),
CROSS_PROCESS_USING_LUT ("CrossProcess (using LUT)"),
CONVOLVE_5X5 ("Convolve 5x5"),
INTRINSICS_CONVOLVE_5X5 ("Intrinsics Convolve 5x5"),
MANDELBROT ("Mandelbrot"),
INTRINSICS_BLEND ("Intrinsics Blend"),
INTRINSICS_BLUR_25G ("Intrinsics Blur 25 uchar"),
VIBRANCE ("Vibrance"),
BW_FILTER ("BW Filter"),
SHADOWS ("Shadows"),
CONTRAST ("Contrast"),
EXPOSURE ("Exposure"),
WHITE_BALANCE ("White Balance"),
COLOR_CUBE ("Color Cube"),
COLOR_CUBE_3D_INTRINSIC ("Color Cube (3D LUT intrinsic)");
private final String name;
private TestName(String s) {
name = s;
}
// return quoted string as displayed test name
public String toString() {
return name;
}
}
Bitmap mBitmapIn;
Bitmap mBitmapIn2;
Bitmap mBitmapOut;
String mTestNames[];
private Spinner mSpinner;
private SeekBar mBar1;
@ -77,6 +138,7 @@ public class ImageProcessingActivity2 extends Activity
private boolean mDoingBenchmark;
private TestBase mTest;
private int mRunCount;
public void updateDisplay() {
mTest.updateBitmap(mBitmapOut);
@ -135,98 +197,125 @@ public class ImageProcessingActivity2 extends Activity
}
void changeTest(int testID) {
void changeTest(TestName testName) {
if (mTest != null) {
mTest.destroy();
}
switch(testID) {
case 0:
switch(testName) {
case LEVELS_VEC3_RELAXED:
mTest = new LevelsV4(false, false);
break;
case 1:
case LEVELS_VEC4_RELAXED:
mTest = new LevelsV4(false, true);
break;
case 2:
case LEVELS_VEC3_FULL:
mTest = new LevelsV4(true, false);
break;
case 3:
case LEVELS_VEC4_FULL:
mTest = new LevelsV4(true, true);
break;
case 4:
case BLUR_RADIUS_25:
mTest = new Blur25(false);
break;
case 5:
case INTRINSIC_BLUE_RADIUS_25:
mTest = new Blur25(true);
break;
case 6:
case GREYSCALE:
mTest = new Greyscale();
break;
case 7:
case GRAIN:
mTest = new Grain();
break;
case 8:
case FISHEYE_FULL:
mTest = new Fisheye(false, false);
break;
case 9:
case FISHEYE_RELAXED:
mTest = new Fisheye(false, true);
break;
case 10:
case FISHEYE_APPROXIMATE_FULL:
mTest = new Fisheye(true, false);
break;
case 11:
case FISHEYE_APPROXIMATE_RELAXED:
mTest = new Fisheye(true, true);
break;
case 12:
case VIGNETTE_FULL:
mTest = new Vignette(false, false);
break;
case 13:
case VIGNETTE_RELAXED:
mTest = new Vignette(false, true);
break;
case 14:
case VIGNETTE_APPROXIMATE_FULL:
mTest = new Vignette(true, false);
break;
case 15:
case VIGNETTE_APPROXIMATE_RELAXED:
mTest = new Vignette(true, true);
break;
case 16:
case GROUP_TEST_EMULATED:
mTest = new GroupTest(false);
break;
case 17:
case GROUP_TEST_NATIVE:
mTest = new GroupTest(true);
break;
case 18:
case CONVOLVE_3X3:
mTest = new Convolve3x3(false);
break;
case 19:
case INTRINSICS_CONVOLVE_3X3:
mTest = new Convolve3x3(true);
break;
case 20:
case COLOR_MATRIX:
mTest = new ColorMatrix(false, false);
break;
case 21:
case INTRINSICS_COLOR_MATRIX:
mTest = new ColorMatrix(true, false);
break;
case 22:
case INTRINSICS_COLOR_MATRIX_GREY:
mTest = new ColorMatrix(true, true);
break;
case 23:
case COPY:
mTest = new Copy();
break;
case 24:
case CROSS_PROCESS_USING_LUT:
mTest = new CrossProcess();
break;
case 25:
case CONVOLVE_5X5:
mTest = new Convolve5x5(false);
break;
case 26:
case INTRINSICS_CONVOLVE_5X5:
mTest = new Convolve5x5(true);
break;
case 27:
case MANDELBROT:
mTest = new Mandelbrot();
break;
case 28:
case INTRINSICS_BLEND:
mTest = new Blend();
break;
case INTRINSICS_BLUR_25G:
mTest = new Blur25G();
break;
case VIBRANCE:
mTest = new Vibrance();
break;
case BW_FILTER:
mTest = new BWFilter();
break;
case SHADOWS:
mTest = new Shadows();
break;
case CONTRAST:
mTest = new Contrast();
break;
case EXPOSURE:
mTest = new Exposure();
break;
case WHITE_BALANCE:
mTest = new WhiteBalance();
break;
case COLOR_CUBE:
mTest = new ColorCube(false);
break;
case COLOR_CUBE_3D_INTRINSIC:
mTest = new ColorCube(true);
break;
}
mTest.createBaseTest(this, mBitmapIn, mBitmapIn2, mBitmapOut);
@ -238,45 +327,14 @@ public class ImageProcessingActivity2 extends Activity
}
void setupTests() {
mTestNames = new String[29];
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] = "Intrinsic Blur radius 25";
mTestNames[6] = "Greyscale";
mTestNames[7] = "Grain";
mTestNames[8] = "Fisheye Full";
mTestNames[9] = "Fisheye Relaxed";
mTestNames[10] = "Fisheye Approximate Full";
mTestNames[11] = "Fisheye Approximate Relaxed";
mTestNames[12] = "Vignette Full";
mTestNames[13] = "Vignette Relaxed";
mTestNames[14] = "Vignette Approximate Full";
mTestNames[15] = "Vignette Approximate Relaxed";
mTestNames[16] = "Group Test (emulated)";
mTestNames[17] = "Group Test (native)";
mTestNames[18] = "Convolve 3x3";
mTestNames[19] = "Intrinsics Convolve 3x3";
mTestNames[20] = "ColorMatrix";
mTestNames[21] = "Intrinsics ColorMatrix";
mTestNames[22] = "Intrinsics ColorMatrix Grey";
mTestNames[23] = "Copy";
mTestNames[24] = "CrossProcess (using LUT)";
mTestNames[25] = "Convolve 5x5";
mTestNames[26] = "Intrinsics Convolve 5x5";
mTestNames[27] = "Mandelbrot";
mTestNames[28] = "Intrinsics Blend";
mTestSpinner.setAdapter(new ArrayAdapter<String>(
this, R.layout.spinner_layout, mTestNames));
mTestSpinner.setAdapter(new ArrayAdapter<TestName>(
this, R.layout.spinner_layout, TestName.values()));
}
private AdapterView.OnItemSelectedListener mTestSpinnerListener =
new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
changeTest(pos);
changeTest(TestName.values()[pos]);
}
public void onNothingSelected(AdapterView parent) {
@ -291,7 +349,8 @@ public class ImageProcessingActivity2 extends Activity
mBitmapIn = loadBitmap(R.drawable.img1600x1067);
mBitmapIn2 = loadBitmap(R.drawable.img1600x1067b);
mBitmapOut = loadBitmap(R.drawable.img1600x1067);
mBitmapOut = Bitmap.createBitmap(mBitmapIn.getWidth(), mBitmapIn.getHeight(),
mBitmapIn.getConfig());
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
@ -324,23 +383,22 @@ public class ImageProcessingActivity2 extends Activity
mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
mBenchmarkResult.setText("Result: not run");
mRS = RenderScript.create(this);
mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn);
mInPixelsAllocation2 = Allocation.createFromBitmap(mRS, mBitmapIn2);
mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut);
setupTests();
changeTest(0);
changeTest(TestName.LEVELS_VEC3_RELAXED);
}
private Bitmap loadBitmap(int resource) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
return copyBitmap(BitmapFactory.decodeResource(getResources(), resource, options));
}
private static Bitmap copyBitmap(Bitmap source) {
Bitmap b = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig());
Canvas c = new Canvas(b);
c.drawBitmap(source, 0, 0, null);
source.recycle();
return b;
return BitmapFactory.decodeResource(getResources(), resource, options);
}
// button hook
@ -364,10 +422,10 @@ public class ImageProcessingActivity2 extends Activity
try {
BufferedWriter rsWriter = new BufferedWriter(new FileWriter(resultFile));
Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath());
for (int i = 0; i < mTestNames.length; i++ ) {
changeTest(i);
for (TestName tn: TestName.values()) {
changeTest(tn);
float t = getBenchmark();
String s = new String("" + mTestNames[i] + ", " + t);
String s = new String("" + tn.toString() + ", " + t);
rsWriter.write(s + "\n");
Log.v(TAG, "Test " + s + "ms\n");
}
@ -375,7 +433,7 @@ public class ImageProcessingActivity2 extends Activity
} catch (IOException e) {
Log.v(TAG, "Unable to write result file " + e.getMessage());
}
changeTest(0);
changeTest(TestName.LEVELS_VEC3_RELAXED);
}
// For benchmark test
@ -392,7 +450,6 @@ public class ImageProcessingActivity2 extends Activity
mTest.finish();
} while (t > java.lang.System.currentTimeMillis());
//Log.v(TAG, "Benchmarking");
int ct = 0;
t = java.lang.System.currentTimeMillis();

View File

@ -18,7 +18,6 @@ package com.android.rs.image2;
import java.lang.Math;
import android.support.v8.renderscript.*;
import android.util.Log;
import android.widget.SeekBar;
import android.widget.TextView;

View File

@ -0,0 +1,32 @@
/*
* 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.image2;
public class Shadows extends TestBase {
private ScriptC_shadows mScript;
public void createTest(android.content.res.Resources res) {
mScript = new ScriptC_shadows(mRS);
}
public void runTest() {
mScript.invoke_prepareShadows(50.f);
mScript.forEach_shadowsKernel(mInPixelsAllocation, mOutPixelsAllocation);
}
}

View File

@ -90,18 +90,17 @@ public class TestBase {
public final void createBaseTest(ImageProcessingActivity2 ipact, Bitmap b, Bitmap b2, Bitmap outb) {
act = ipact;
mRS = RenderScript.create(act);
mRS = ipact.mRS;
mInPixelsAllocation = Allocation.createFromBitmap(mRS, b);
mInPixelsAllocation2 = Allocation.createFromBitmap(mRS, b2);
mOutPixelsAllocation = Allocation.createFromBitmap(mRS, outb);
mInPixelsAllocation = ipact.mInPixelsAllocation;
mInPixelsAllocation2 = ipact.mInPixelsAllocation2;
mOutPixelsAllocation = ipact.mOutPixelsAllocation;
createTest(act.getResources());
}
// Must override
public void createTest(android.content.res.Resources res) {
android.util.Log.e("img", "implement createTest");
}
// Must override
@ -113,7 +112,6 @@ public class TestBase {
}
public void destroy() {
mRS.destroy();
}
public void updateBitmap(Bitmap b) {

View File

@ -0,0 +1,32 @@
/*
* 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.image2;
public class Vibrance extends TestBase {
private ScriptC_vibrance mScript;
public void createTest(android.content.res.Resources res) {
mScript = new ScriptC_vibrance(mRS);
}
public void runTest() {
mScript.set_vibrance(50.f);
mScript.invoke_prepareVibrance();
mScript.forEach_vibranceKernel(mInPixelsAllocation, mOutPixelsAllocation);
}
}

View File

@ -16,7 +16,6 @@
package com.android.rs.image2;
import android.support.v8.renderscript.*;
import android.widget.SeekBar;
import android.widget.TextView;

View File

@ -0,0 +1,38 @@
/*
* 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.image2;
import java.lang.Math;
import android.support.v8.renderscript.*;
public class WhiteBalance extends TestBase {
private ScriptC_wbalance mScript;
public void createTest(android.content.res.Resources res) {
mScript = new ScriptC_wbalance(mRS);
}
public void runTest() {
mScript.set_histogramSource(mInPixelsAllocation);
mScript.set_histogramWidth(mInPixelsAllocation.getType().getX());
mScript.set_histogramHeight(mInPixelsAllocation.getType().getY());
mScript.invoke_prepareWhiteBalance();
mScript.forEach_whiteBalanceKernel(mInPixelsAllocation, mOutPixelsAllocation);
}
}

View File

@ -12,8 +12,7 @@
// 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.image2)
#include "ip.rsh"
uchar alpha = 0x0;

View File

@ -0,0 +1,52 @@
/*
* 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.
*/
#include "ip.rsh"
//#pragma rs_fp_relaxed
static float sr = 0.f;
static float sg = 0.f;
static float sb = 0.f;
void prepareBwFilter(uint32_t rw, uint32_t gw, uint32_t bw) {
sr = rw;
sg = gw;
sb = bw;
float imageMin = min(sg,sb);
imageMin = fmin(sr,imageMin);
float imageMax = max(sg,sb);
imageMax = fmax(sr,imageMax);
float avg = (imageMin + imageMax)/2;
sb /= avg;
sg /= avg;
sr /= avg;
}
void bwFilterKernel(const uchar4 *in, uchar4 *out) {
float r = in->r * sr;
float g = in->g * sg;
float b = in->b * sb;
float localMin, localMax, avg;
localMin = fmin(g,b);
localMin = fmin(r,localMin);
localMax = fmax(g,b);
localMax = fmax(r,localMax);
avg = (localMin+localMax) * 0.5f;
out->r = out->g = out->b = rsClamp(avg, 0, 255);
}

View File

@ -0,0 +1,89 @@
/*
* 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.
*/
#include "ip.rsh"
#pragma rs_fp_relaxed
static rs_allocation gCube;
static int4 gDims;
static int4 gCoordMul;
void setCube(rs_allocation c) {
gCube = c;
gDims.x = rsAllocationGetDimX(gCube);
gDims.y = rsAllocationGetDimY(gCube);
gDims.z = rsAllocationGetDimZ(gCube);
gDims.w = 0;
float4 m = (float4)(1.f / 255.f) * convert_float4(gDims - 1);
gCoordMul = convert_int4(m * (float4)0x10000);
rsDebug("dims", gDims);
rsDebug("gCoordMul", gCoordMul);
}
void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
//rsDebug("root", in);
int4 baseCoord = convert_int4(*in) * gCoordMul;
int4 coord1 = baseCoord >> (int4)16;
int4 coord2 = min(coord1 + 1, gDims - 1);
int4 weight2 = baseCoord & 0xffff;
int4 weight1 = (int4)0x10000 - weight2;
uint4 v000 = convert_uint4(rsGetElementAt_uchar4(gCube, coord1.x, coord1.y, coord1.z));
uint4 v100 = convert_uint4(rsGetElementAt_uchar4(gCube, coord2.x, coord1.y, coord1.z));
uint4 v010 = convert_uint4(rsGetElementAt_uchar4(gCube, coord1.x, coord2.y, coord1.z));
uint4 v110 = convert_uint4(rsGetElementAt_uchar4(gCube, coord2.x, coord2.y, coord1.z));
uint4 v001 = convert_uint4(rsGetElementAt_uchar4(gCube, coord1.x, coord1.y, coord2.z));
uint4 v101 = convert_uint4(rsGetElementAt_uchar4(gCube, coord2.x, coord1.y, coord2.z));
uint4 v011 = convert_uint4(rsGetElementAt_uchar4(gCube, coord1.x, coord2.y, coord2.z));
uint4 v111 = convert_uint4(rsGetElementAt_uchar4(gCube, coord2.x, coord2.y, coord2.z));
uint4 yz00 = ((v000 * weight1.x) + (v100 * weight2.x)) >> (int4)8;
uint4 yz10 = ((v010 * weight1.x) + (v110 * weight2.x)) >> (int4)8;
uint4 yz01 = ((v001 * weight1.x) + (v101 * weight2.x)) >> (int4)8;
uint4 yz11 = ((v011 * weight1.x) + (v111 * weight2.x)) >> (int4)8;
uint4 z0 = ((yz00 * weight1.y) + (yz10 * weight2.y)) >> (int4)16;
uint4 z1 = ((yz01 * weight1.y) + (yz11 * weight2.y)) >> (int4)16;
uint4 v = ((z0 * weight1.z) + (z1 * weight2.z)) >> (int4)16;
uint4 v2 = (v + 0x7f) >> (int4)8;
*out = convert_uchar4(v2);
out->a = 0xff;
#if 0
if (in->r != out->r) {
rsDebug("dr", in->r - out->r);
//rsDebug("in", convert_int4(*in));
//rsDebug("coord1", coord1);
//rsDebug("coord2", coord2);
//rsDebug("weight1", weight1);
//rsDebug("weight2", weight2);
//rsDebug("yz00", yz00);
//rsDebug("z0", z0);
//rsDebug("v", v);
//rsDebug("v2", v2);
//rsDebug("out", convert_int4(*out));
}
#endif
}

View File

@ -14,10 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#pragma rs_fp_relaxed
#include "ip.rsh"
static rs_matrix4x4 Mat;
@ -29,10 +26,10 @@ void setMatrix(rs_matrix4x4 m) {
Mat = m;
}
void root(const uchar4 *in, uchar4 *out) {
float4 f = convert_float4(*in);
uchar4 __attribute__((kernel)) root(uchar4 in) {
float4 f = convert_float4(in);
f = rsMatrixMultiply(&Mat, f);
f = clamp(f, 0.f, 255.f);
*out = convert_uchar4(f);
return convert_uchar4(f);
}

View File

@ -0,0 +1,37 @@
/*
* 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.
*/
#include "ip.rsh"
static float brightM = 0.f;
static float brightC = 0.f;
void setBright(float v) {
brightM = pow(2.f, v / 100.f);
brightC = 127.f - brightM * 127.f;
}
void contrast(const uchar4 *in, uchar4 *out)
{
#if 0
out->r = rsClamp((int)(brightM * in->r + brightC), 0, 255);
out->g = rsClamp((int)(brightM * in->g + brightC), 0, 255);
out->b = rsClamp((int)(brightM * in->b + brightC), 0, 255);
#else
float3 v = convert_float3(in->rgb) * brightM + brightC;
out->rgb = convert_uchar3(clamp(v, 0.f, 255.f));
#endif
}

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#pragma rs_fp_relaxed
#include "ip.rsh"
int32_t gWidth;
int32_t gHeight;
@ -24,7 +22,7 @@ rs_allocation gIn;
float gCoeffs[25];
void root(uchar4 *out, uint32_t x, uint32_t y) {
uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
uint32_t x0 = max((int32_t)x-2, 0);
uint32_t x1 = max((int32_t)x-1, 0);
uint32_t x2 = x;
@ -68,8 +66,7 @@ void root(uchar4 *out, uint32_t x, uint32_t y) {
+ convert_float4(rsGetElementAt_uchar4(gIn, x4, y4)) * gCoeffs[24];
p0 = clamp(p0 + p1 + p2 + p3 + p4, 0.f, 255.f);
p0.a = 255.f;
*out = convert_uchar4(p0);
return convert_uchar4(p0);
}

View File

@ -0,0 +1,23 @@
/*
* 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.
*/
#include "ip.rsh"
uchar4 __attribute__((kernel)) root(uchar4 v_in) {
return v_in;
}

View File

@ -14,11 +14,18 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#include "ip.rsh"
void root(const uchar4 *v_in, uchar4 *v_out) {
*v_out = *v_in;
static float bright = 0.f;
void setBright(float v) {
bright = 255.f / (255.f - v);
}
void exposure(const uchar4 *in, uchar4 *out)
{
out->r = rsClamp((int)(bright * in->r), 0, 255);
out->g = rsClamp((int)(bright * in->g), 0, 255);
out->b = rsClamp((int)(bright * in->b), 0, 255);
}

View File

@ -26,7 +26,7 @@ void init_filter(uint32_t dim_x, uint32_t dim_y, float center_x, float center_y,
neg_center = -center;
inv_dimensions.x = 1.f / (float)dim_x;
inv_dimensions.y = 1.f / (float)dim_y;
alpha = k * 2.0 + 0.75;
alpha = k * 2.0f + 0.75f;
axis_scale = (float2)1.f;
if (dim_x > dim_y)
@ -34,15 +34,15 @@ void init_filter(uint32_t dim_x, uint32_t dim_y, float center_x, float center_y,
else
axis_scale.x = (float)dim_x / (float)dim_y;
const float bound2 = 0.25 * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
const float bound2 = 0.25f * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
const float bound = sqrt(bound2);
const float radius = 1.15 * bound;
const float radius = 1.15f * bound;
radius2 = radius*radius;
const float max_radian = M_PI_2 - atan(alpha / bound * sqrt(radius2 - bound2));
factor = bound / max_radian;
}
void root(uchar4 *out, uint32_t x, uint32_t y) {
uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
// Convert x and y to floating point coordinates with center as origin
const float2 inCoord = {(float)x, (float)y};
const float2 coord = mad(inCoord, inv_dimensions, neg_center);
@ -53,6 +53,6 @@ void root(uchar4 *out, uint32_t x, uint32_t y) {
const float scalar = radian * factor * inv_dist;
const float2 new_coord = mad(coord, scalar, center);
const float4 fout = rsSample(in_alloc, sampler, new_coord);
*out = rsPackColorTo8888(fout);
return rsPackColorTo8888(fout);
}

View File

@ -26,7 +26,7 @@ void init_filter(uint32_t dim_x, uint32_t dim_y, float center_x, float center_y,
neg_center = -center;
inv_dimensions.x = 1.f / (float)dim_x;
inv_dimensions.y = 1.f / (float)dim_y;
alpha = k * 2.0 + 0.75;
alpha = k * 2.0f + 0.75f;
axis_scale = (float2)1.f;
if (dim_x > dim_y)
@ -34,15 +34,15 @@ void init_filter(uint32_t dim_x, uint32_t dim_y, float center_x, float center_y,
else
axis_scale.x = (float)dim_x / (float)dim_y;
const float bound2 = 0.25 * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
const float bound2 = 0.25f * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
const float bound = sqrt(bound2);
const float radius = 1.15 * bound;
const float radius = 1.15f * bound;
radius2 = radius*radius;
const float max_radian = M_PI_2 - atan(alpha / bound * sqrt(radius2 - bound2));
factor = bound / max_radian;
}
void root(uchar4 *out, uint32_t x, uint32_t y) {
uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
// Convert x and y to floating point coordinates with center as origin
const float2 inCoord = {(float)x, (float)y};
const float2 coord = mad(inCoord, inv_dimensions, neg_center);
@ -53,6 +53,6 @@ void root(uchar4 *out, uint32_t x, uint32_t y) {
const float scalar = radian * factor * inv_dist;
const float2 new_coord = mad(coord, scalar, center);
const float4 fout = rsSample(in_alloc, sampler, new_coord);
*out = rsPackColorTo8888(fout);
return rsPackColorTo8888(fout);
}

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#include "ip.rsh"
#include "fisheye_approx.rsh"

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#pragma rs_fp_relaxed
#include "ip.rsh"
#include "fisheye_approx.rsh"

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#include "ip.rsh"
#include "fisheye.rsh"

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#pragma rs_fp_relaxed
#include "ip.rsh"
#include "fisheye.rsh"

View File

@ -14,12 +14,10 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#pragma rs_fp_relaxed
#include "ip.rsh"
void genRand(uchar *out) {
*out = (uchar)rsRand(0xff);
uchar __attribute__((kernel)) genRand() {
return (uchar)rsRand(0xff);
}
/*
@ -42,7 +40,7 @@ int32_t gWMask;
int32_t gHMask;
rs_allocation gBlendSource;
void blend9(uchar *out, uint32_t x, uint32_t y) {
uchar __attribute__((kernel)) blend9(uint32_t x, uint32_t y) {
uint32_t x1 = (x-1) & gWMask;
uint32_t x2 = (x+1) & gWMask;
uint32_t y1 = (y-1) & gHMask;
@ -70,14 +68,14 @@ void blend9(uchar *out, uint32_t x, uint32_t y) {
p20 += p02;
p20 = min(p20 >> 10, (uint)255);
*out = (uchar)p20;
return (uchar)p20;
}
float gNoiseStrength;
rs_allocation gNoise;
void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
float4 ip = convert_float4(*in);
uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) {
float4 ip = convert_float4(in);
float pnoise = (float) rsGetElementAt_uchar(gNoise, x & gWMask, y & gHMask);
float energy_level = ip.r + ip.g + ip.b;
@ -89,5 +87,5 @@ void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
uchar4 p = convert_uchar4(ip);
p.a = 0xff;
*out = p;
return p;
}

View File

@ -14,17 +14,23 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#pragma rs_fp_relaxed
#include "ip.rsh"
const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
void root(const uchar4 *v_in, uchar4 *v_out) {
float4 f4 = rsUnpackColor8888(*v_in);
uchar4 __attribute__((kernel)) root(uchar4 v_in) {
float4 f4 = rsUnpackColor8888(v_in);
float3 mono = dot(f4.rgb, gMonoMult);
*v_out = rsPackColorTo8888(mono);
return rsPackColorTo8888(mono);
}
uchar __attribute__((kernel)) toU8(uchar4 v_in) {
float4 f4 = convert_float4(v_in);
return (uchar)dot(f4.rgb, gMonoMult);
}
uchar4 __attribute__((kernel)) toU8_4(uchar v_in) {
return (uchar4)v_in;
}

View File

@ -0,0 +1,20 @@
/*
* Copyright (C) 2013 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.image2)

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#pragma rs_fp_relaxed
#include "ip.rsh"
int32_t gWidth;
int32_t gHeight;
@ -24,21 +22,21 @@ rs_allocation gIn;
float gCoeffs[9];
void root(uchar4 *out, uint32_t x, uint32_t y) {
uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
uint32_t x1 = min((int32_t)x+1, gWidth-1);
uint32_t x2 = max((int32_t)x-1, 0);
uint32_t y1 = min((int32_t)y+1, gHeight-1);
uint32_t y2 = max((int32_t)y-1, 0);
float4 p00 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y1))[0]);
float4 p01 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x, y1))[0]);
float4 p02 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y1))[0]);
float4 p10 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y))[0]);
float4 p11 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x, y))[0]);
float4 p12 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y))[0]);
float4 p20 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x1, y2))[0]);
float4 p21 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x, y2))[0]);
float4 p22 = convert_float4(((uchar4 *)rsGetElementAt(gIn, x2, y2))[0]);
float4 p00 = convert_float4(rsGetElementAt_uchar4(gIn, x1, y1));
float4 p01 = convert_float4(rsGetElementAt_uchar4(gIn, x, y1));
float4 p02 = convert_float4(rsGetElementAt_uchar4(gIn, x2, y1));
float4 p10 = convert_float4(rsGetElementAt_uchar4(gIn, x1, y));
float4 p11 = convert_float4(rsGetElementAt_uchar4(gIn, x, y));
float4 p12 = convert_float4(rsGetElementAt_uchar4(gIn, x2, y));
float4 p20 = convert_float4(rsGetElementAt_uchar4(gIn, x1, y2));
float4 p21 = convert_float4(rsGetElementAt_uchar4(gIn, x, y2));
float4 p22 = convert_float4(rsGetElementAt_uchar4(gIn, x2, y2));
p00 *= gCoeffs[0];
p01 *= gCoeffs[1];
p02 *= gCoeffs[2];
@ -61,7 +59,7 @@ void root(uchar4 *out, uint32_t x, uint32_t y) {
p20 += p02;
p20 = clamp(p20, 0.f, 255.f);
*out = convert_uchar4(p20);
return convert_uchar4(p20);
}

View File

@ -21,24 +21,26 @@ float outWMinOutB;
float overInWMinInB;
rs_matrix3x3 colorMat;
void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
float3 pixel = convert_float4(in[0]).rgb;
uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) {
uchar4 out;
float3 pixel = convert_float4(in).rgb;
pixel = rsMatrixMultiply(&colorMat, pixel);
pixel = clamp(pixel, 0.f, 255.f);
pixel = (pixel - inBlack) * overInWMinInB;
pixel = pixel * outWMinOutB + outBlack;
pixel = clamp(pixel, 0.f, 255.f);
out->xyz = convert_uchar3(pixel);
out->w = 0xff;
out.xyz = convert_uchar3(pixel);
out.w = 0xff;
return out;
}
void root4(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
float4 pixel = convert_float4(in[0]);
uchar4 __attribute__((kernel)) root4(uchar4 in, uint32_t x, uint32_t y) {
float4 pixel = convert_float4(in);
pixel.rgb = rsMatrixMultiply(&colorMat, pixel.rgb);
pixel = clamp(pixel, 0.f, 255.f);
pixel = (pixel - inBlack) * overInWMinInB;
pixel = pixel * outWMinOutB + outBlack;
pixel = clamp(pixel, 0.f, 255.f);
out->xyzw = convert_uchar4(pixel);
return convert_uchar4(pixel);
}

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#include "ip.rsh"
#include "levels.rsh"

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#pragma rs_fp_relaxed
#include "ip.rsh"
#include "levels.rsh"

View File

@ -12,8 +12,7 @@
// 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.image2)
#include "ip.rsh"
uint32_t gMaxIteration = 500;
uint32_t gDimX = 1024;
@ -23,7 +22,7 @@ float lowerBoundX = -2.f;
float lowerBoundY = -2.f;
float scaleFactor = 4.f;
void root(uchar4 *v_out, uint32_t x, uint32_t y) {
uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
float2 p;
p.x = lowerBoundX + ((float)x / gDimX) * scaleFactor;
p.y = lowerBoundY + ((float)y / gDimY) * scaleFactor;
@ -41,16 +40,16 @@ void root(uchar4 *v_out, uint32_t x, uint32_t y) {
if(iter >= gMaxIteration) {
// write a non-transparent black pixel
*v_out = (uchar4){0, 0, 0, 0xff};
return (uchar4){0, 0, 0, 0xff};
} else {
float mi3 = gMaxIteration / 3.f;
if (iter <= (gMaxIteration / 3))
*v_out = (uchar4){0xff * (iter / mi3), 0, 0, 0xff};
return (uchar4){0xff * (iter / mi3), 0, 0, 0xff};
else if (iter <= (((gMaxIteration / 3) * 2)))
*v_out = (uchar4){0xff - (0xff * ((iter - mi3) / mi3)),
(0xff * ((iter - mi3) / mi3)), 0, 0xff};
return (uchar4){0xff - (0xff * ((iter - mi3) / mi3)),
(0xff * ((iter - mi3) / mi3)), 0, 0xff};
else
*v_out = (uchar4){0, 0xff - (0xff * ((iter - (mi3 * 2)) / mi3)),
(0xff * ((iter - (mi3 * 2)) / mi3)), 0xff};
return (uchar4){0, 0xff - (0xff * ((iter - (mi3 * 2)) / mi3)),
(0xff * ((iter - (mi3 * 2)) / mi3)), 0xff};
}
}

View File

@ -0,0 +1,192 @@
/*
* 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.
*/
#include "ip.rsh"
//#pragma rs_fp_relaxed
static double shadowFilterMap[] = {
-0.00591, 0.0001,
1.16488, 0.01668,
-0.18027, -0.06791,
-0.12625, 0.09001,
0.15065, -0.03897
};
static double poly[] = {
0., 0.,
0., 0.,
0.
};
static const int ABITS = 4;
static const int HSCALE = 256;
static const int k1=255 << ABITS;
static const int k2=HSCALE << ABITS;
static double fastevalPoly(double *poly,int n, double x){
double f =x;
double sum = poly[0]+poly[1]*f;
int i;
for (i = 2; i < n; i++) {
f*=x;
sum += poly[i]*f;
}
return sum;
}
static ushort3 rgb2hsv( uchar4 rgb)
{
int iMin,iMax,chroma;
int ri = rgb.r;
int gi = rgb.g;
int bi = rgb.b;
short rv,rs,rh;
if (ri > gi) {
iMax = max (ri, bi);
iMin = min (gi, bi);
} else {
iMax = max (gi, bi);
iMin = min (ri, bi);
}
chroma = iMax - iMin;
// set value
rv = (short)( iMax << ABITS);
// set saturation
if (rv == 0)
rs = 0;
else
rs = (short)((k1*chroma)/iMax);
// set hue
if (rs == 0)
rh = 0;
else {
if ( ri == iMax ) {
rh = (short)( (k2*(6*chroma+gi - bi))/(6*chroma));
if (rh >= k2) rh -= k2;
} else if (gi == iMax)
rh = (short)( (k2*(2*chroma+bi - ri ))/(6*chroma));
else // (bi == iMax )
rh = (short)( (k2*(4*chroma+ri - gi ))/(6*chroma));
}
ushort3 out;
out.x = rv;
out.y = rs;
out.z = rh;
return out;
}
static uchar4 hsv2rgb(ushort3 hsv)
{
int ABITS = 4;
int HSCALE = 256;
int m;
int H,X,ih,is,iv;
int k1=255<<ABITS;
int k2=HSCALE<<ABITS;
int k3=1<<(ABITS-1);
int rr=0;
int rg=0;
int rb=0;
short cv = hsv.x;
short cs = hsv.y;
short ch = hsv.z;
// set chroma and min component value m
//chroma = ( cv * cs )/k1;
//m = cv - chroma;
m = ((int)cv*(k1 - (int)cs ))/k1;
// chroma == 0 <-> cs == 0 --> m=cv
if (cs == 0) {
rb = ( rg = ( rr =( cv >> ABITS) ));
} else {
ih=(int)ch;
is=(int)cs;
iv=(int)cv;
H = (6*ih)/k2;
X = ((iv*is)/k2)*(k2- abs(6*ih- 2*(H>>1)*k2 - k2)) ;
// removing additional bits --> unit8
X=( (X+iv*(k1 - is ))/k1 + k3 ) >> ABITS;
m=m >> ABITS;
// ( chroma + m ) --> cv ;
cv=(short) (cv >> ABITS);
switch (H) {
case 0:
rr = cv;
rg = X;
rb = m;
break;
case 1:
rr = X;
rg = cv;
rb = m;
break;
case 2:
rr = m;
rg = cv;
rb = X;
break;
case 3:
rr = m;
rg = X;
rb = cv;
break;
case 4:
rr = X;
rg = m;
rb = cv;
break;
case 5:
rr = cv;
rg = m ;
rb = X;
break;
}
}
uchar4 rgb;
rgb.r = rr;
rgb.g = rg;
rgb.b = rb;
return rgb;
}
void prepareShadows(float scale) {
double s = (scale>=0)?scale:scale/5;
for (int i = 0; i < 5; i++) {
poly[i] = fastevalPoly(shadowFilterMap+i*2,2 , s);
}
}
void shadowsKernel(const uchar4 *in, uchar4 *out) {
ushort3 hsv = rgb2hsv(*in);
double v = (fastevalPoly(poly,5,hsv.x/4080.)*4080);
if (v>4080) v = 4080;
hsv.x = (unsigned short) ((v>0)?v:0);
*out = hsv2rgb(hsv);
}

View File

@ -1,6 +1,20 @@
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#pragma rs_fp_relaxed
/*
* Copyright (C) 2013 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.
*/
#include "ip.rsh"
int height;
@ -56,51 +70,49 @@ void setRadius(int rad) {
}
}
void copyIn(const uchar4 *in, float4 *out) {
*out = convert_float4(*in);
float4 __attribute__((kernel)) copyIn(uchar4 in) {
return convert_float4(in);
}
void vert(uchar4 *out, uint32_t x, uint32_t y) {
uchar4 __attribute__((kernel)) vert(uint32_t x, uint32_t y) {
float3 blurredPixel = 0;
const float *gPtr = gaussian;
int gi = 0;
uchar4 out;
if ((y > radius) && (y < (height - radius))) {
for (int r = -radius; r <= radius; r ++) {
const float4 *i = (const float4 *)rsGetElementAt(ScratchPixel2, x, y + r);
blurredPixel += i->xyz * gPtr[0];
gPtr++;
float4 i = rsGetElementAt_float4(ScratchPixel2, x, y + r);
blurredPixel += i.xyz * gaussian[gi++];
}
} else {
for (int r = -radius; r <= radius; r ++) {
int validH = rsClamp((int)y + r, (int)0, (int)(height - 1));
const float4 *i = (const float4 *)rsGetElementAt(ScratchPixel2, x, validH);
blurredPixel += i->xyz * gPtr[0];
gPtr++;
float4 i = rsGetElementAt_float4(ScratchPixel2, x, validH);
blurredPixel += i.xyz * gaussian[gi++];
}
}
out->xyz = convert_uchar3(clamp(blurredPixel, 0.f, 255.f));
out->w = 0xff;
out.xyz = convert_uchar3(clamp(blurredPixel, 0.f, 255.f));
out.w = 0xff;
return out;
}
void horz(float4 *out, uint32_t x, uint32_t y) {
float3 blurredPixel = 0;
const float *gPtr = gaussian;
float4 __attribute__((kernel)) horz(uint32_t x, uint32_t y) {
float4 blurredPixel = 0;
int gi = 0;
if ((x > radius) && (x < (width - radius))) {
for (int r = -radius; r <= radius; r ++) {
const float4 *i = (const float4 *)rsGetElementAt(ScratchPixel1, x + r, y);
blurredPixel += i->xyz * gPtr[0];
gPtr++;
float4 i = rsGetElementAt_float4(ScratchPixel1, x + r, y);
blurredPixel += i * gaussian[gi++];
}
} else {
for (int r = -radius; r <= radius; r ++) {
// Stepping left and right away from the pixel
int validX = rsClamp((int)x + r, (int)0, (int)(width - 1));
const float4 *i = (const float4 *)rsGetElementAt(ScratchPixel1, validX, y);
blurredPixel += i->xyz * gPtr[0];
gPtr++;
float4 i = rsGetElementAt_float4(ScratchPixel1, validX, y);
blurredPixel += i * gaussian[gi++];
}
}
out->xyz = blurredPixel;
return blurredPixel;
}

View File

@ -0,0 +1,70 @@
/*
* 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.
*/
#include "ip.rsh"
float vibrance = 0.f;
static const float Rf = 0.2999f;
static const float Gf = 0.587f;
static const float Bf = 0.114f;
static float S = 0.f;
static float MS = 0.f;
static float Rt = 0.f;
static float Gt = 0.f;
static float Bt = 0.f;
static float Vib = 0.f;
void vibranceKernel(const uchar4 *in, uchar4 *out) {
float R, G, B;
int r = in->r;
int g = in->g;
int b = in->b;
float red = (r-max(g, b))/256.f;
float sx = (float)(Vib/(1+native_exp(-red*3)));
S = sx+1;
MS = 1.0f - S;
Rt = Rf * MS;
Gt = Gf * MS;
Bt = Bf * MS;
int t = (r + g) / 2;
R = r;
G = g;
B = b;
float Rc = R * (Rt + S) + G * Gt + B * Bt;
float Gc = R * Rt + G * (Gt + S) + B * Bt;
float Bc = R * Rt + G * Gt + B * (Bt + S);
out->r = rsClamp(Rc, 0, 255);
out->g = rsClamp(Gc, 0, 255);
out->b = rsClamp(Bc, 0, 255);
}
void prepareVibrance() {
Vib = vibrance/100.f;
S = Vib + 1;
MS = 1.0f - S;
Rt = Rf * MS;
Gt = Gf * MS;
Bt = Bf * MS;
}

View File

@ -31,29 +31,29 @@ void init_vignette(uint32_t dim_x, uint32_t dim_y, float center_x, float center_
else
axis_scale.x = (float)dim_x / (float)dim_y;
const float max_dist = 0.5 * length(axis_scale);
const float max_dist = 0.5f * length(axis_scale);
sloped_inv_max_dist = desired_slope * 1.f/max_dist;
// Range needs to be between 1.3 to 0.6. When scale is zero then range is
// 1.3 which means no vignette at all because the luminousity difference is
// less than 1/256. Expect input scale to be between 0.0 and 1.0.
const float neg_range = 0.7*sqrt(desired_scale) - 1.3;
const float neg_range = 0.7f*sqrt(desired_scale) - 1.3f;
sloped_neg_range = exp(neg_range * desired_slope);
shade = desired_shade;
opp_shade = 1.f - desired_shade;
}
void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) {
// Convert x and y to floating point coordinates with center as origin
const float4 fin = convert_float4(*in);
const float4 fin = convert_float4(in);
const float2 inCoord = {(float)x, (float)y};
const float2 coord = mad(inCoord, inv_dimensions, neg_center);
const float sloped_dist_ratio = length(axis_scale * coord) * sloped_inv_max_dist;
const float lumen = opp_shade + shade / ( 1.0 + sloped_neg_range * exp(sloped_dist_ratio) );
const float lumen = opp_shade + shade / ( 1.0f + sloped_neg_range * exp(sloped_dist_ratio) );
float4 fout;
fout.rgb = fin.rgb * lumen;
fout.w = fin.w;
*out = convert_uchar4(fout);
return convert_uchar4(fout);
}

View File

@ -31,30 +31,29 @@ void init_vignette(uint32_t dim_x, uint32_t dim_y, float center_x, float center_
else
axis_scale.x = (float)dim_x / (float)dim_y;
const float max_dist = 0.5 * length(axis_scale);
const float max_dist = 0.5f * length(axis_scale);
sloped_inv_max_dist = desired_slope * 1.f/max_dist;
// Range needs to be between 1.3 to 0.6. When scale is zero then range is
// 1.3 which means no vignette at all because the luminousity difference is
// less than 1/256. Expect input scale to be between 0.0 and 1.0.
const float neg_range = 0.7*sqrt(desired_scale) - 1.3;
const float neg_range = 0.7f*sqrt(desired_scale) - 1.3f;
sloped_neg_range = exp(neg_range * desired_slope);
shade = desired_shade;
opp_shade = 1.f - desired_shade;
}
void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) {
// Convert x and y to floating point coordinates with center as origin
const float4 fin = convert_float4(*in);
const float4 fin = convert_float4(in);
const float2 inCoord = {(float)x, (float)y};
const float2 coord = mad(inCoord, inv_dimensions, neg_center);
const float sloped_dist_ratio = fast_length(axis_scale * coord) * sloped_inv_max_dist;
// TODO: add half_exp once implemented
const float lumen = opp_shade + shade * half_recip(1.f + sloped_neg_range * exp(sloped_dist_ratio));
const float lumen = opp_shade + shade * half_recip(1.f + sloped_neg_range * native_exp(sloped_dist_ratio));
float4 fout;
fout.rgb = fin.rgb * lumen;
fout.w = fin.w;
*out = convert_uchar4(fout);
return convert_uchar4(fout);
}

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#include "ip.rsh"
#include "vignette_approx.rsh"

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#pragma rs_fp_relaxed
#include "ip.rsh"
#include "vignette_approx.rsh"

View File

@ -14,8 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#include "ip.rsh"
#include "vignette.rsh"

View File

@ -14,9 +14,7 @@
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.android.rs.image2)
#pragma rs_fp_relaxed
#include "ip.rsh"
#include "vignette.rsh"

View File

@ -0,0 +1,142 @@
/*
* 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.
*/
#include "ip.rsh"
//#pragma rs_fp_relaxed
static int histR[256] = {0}, histG[256] = {0}, histB[256] = {0};
rs_allocation histogramSource;
uint32_t histogramHeight;
uint32_t histogramWidth;
static float scaleR;
static float scaleG;
static float scaleB;
static uchar4 estimateWhite() {
for (int i = 0; i < 256; i++) {
histR[i] = 0; histG[i] = 0; histB[i] = 0;
}
for (uint32_t i = 0; i < histogramHeight; i++) {
for (uint32_t j = 0; j < histogramWidth; j++) {
uchar4 in = rsGetElementAt_uchar4(histogramSource, j, i);
histR[in.r]++;
histG[in.g]++;
histB[in.b]++;
}
}
int min_r = -1, min_g = -1, min_b = -1;
int max_r = 0, max_g = 0, max_b = 0;
int sum_r = 0, sum_g = 0, sum_b = 0;
for (int i = 1; i < 255; i++) {
int r = histR[i];
int g = histG[i];
int b = histB[i];
sum_r += r;
sum_g += g;
sum_b += b;
if (r>0){
if (min_r < 0) min_r = i;
max_r = i;
}
if (g>0){
if (min_g < 0) min_g = i;
max_g = i;
}
if (b>0){
if (min_b < 0) min_b = i;
max_b = i;
}
}
int sum15r = 0, sum15g = 0, sum15b = 0;
int count15r = 0, count15g = 0, count15b = 0;
int tmp_r = 0, tmp_g = 0, tmp_b = 0;
for (int i = 254; i >0; i--) {
int r = histR[i];
int g = histG[i];
int b = histB[i];
tmp_r += r;
tmp_g += g;
tmp_b += b;
if ((tmp_r > sum_r/20) && (tmp_r < sum_r/5)) {
sum15r += r*i;
count15r += r;
}
if ((tmp_g > sum_g/20) && (tmp_g < sum_g/5)) {
sum15g += g*i;
count15g += g;
}
if ((tmp_b > sum_b/20) && (tmp_b < sum_b/5)) {
sum15b += b*i;
count15b += b;
}
}
uchar4 out;
if ((count15r>0) && (count15g>0) && (count15b>0) ){
out.r = sum15r/count15r;
out.g = sum15g/count15g;
out.b = sum15b/count15b;
}else {
out.r = out.g = out.b = 255;
}
return out;
}
void prepareWhiteBalance() {
uchar4 estimation = estimateWhite();
int minimum = min(estimation.r, min(estimation.g, estimation.b));
int maximum = max(estimation.r, max(estimation.g, estimation.b));
float avg = (minimum + maximum) / 2.f;
scaleR = avg/estimation.r;
scaleG = avg/estimation.g;
scaleB = avg/estimation.b;
}
static unsigned char contrastClamp(int c)
{
int N = 255;
c &= ~(c >> 31);
c -= N;
c &= (c >> 31);
c += N;
return (unsigned char) c;
}
void whiteBalanceKernel(const uchar4 *in, uchar4 *out) {
float Rc = in->r*scaleR;
float Gc = in->g*scaleG;
float Bc = in->b*scaleB;
out->r = contrastClamp(Rc);
out->g = contrastClamp(Gc);
out->b = contrastClamp(Bc);
}