Add RS YUV test
This is a new test to cover both the YUV intrinsic and
the rsGetElementAt_uchar_Y,u,v functions.
bug 10826418
Change-Id: Ia187685abcd26066424f03ae7548ea59504c2e14
diff --git a/tests/src/android/renderscript/cts/yuv.rs b/tests/src/android/renderscript/cts/yuv.rs
new file mode 100644
index 0000000..6d45331
--- /dev/null
+++ b/tests/src/android/renderscript/cts/yuv.rs
@@ -0,0 +1,97 @@
+/*
+ * 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 "shared.rsh"
+
+#pragma rs_fp_relaxed
+
+rs_allocation mInput;
+
+rs_allocation mInY;
+rs_allocation mInU;
+rs_allocation mInV;
+
+static uchar4 yuvToRGBA4(uchar y, uchar u, uchar v) {
+ short Y = ((short)y) - 16;
+ short U = ((short)u) - 128;
+ short V = ((short)v) - 128;
+
+ short4 p;
+ p.x = (Y * 298 + V * 409 + 128) >> 8;
+ p.y = (Y * 298 - U * 100 - V * 208 + 128) >> 8;
+ p.z = (Y * 298 + U * 516 + 128) >> 8;
+ p.w = 255;
+ if(p.x < 0) {
+ p.x = 0;
+ }
+ if(p.x > 255) {
+ p.x = 255;
+ }
+ if(p.y < 0) {
+ p.y = 0;
+ }
+ if(p.y > 255) {
+ p.y = 255;
+ }
+ if(p.z < 0) {
+ p.z = 0;
+ }
+ if(p.z > 255) {
+ p.z = 255;
+ }
+
+ return (uchar4){p.x, p.y, p.z, p.w};
+}
+
+void makeRef(rs_allocation ay, rs_allocation au, rs_allocation av, rs_allocation aout) {
+ uint32_t w = rsAllocationGetDimX(ay);
+ uint32_t h = rsAllocationGetDimY(ay);
+
+ for (int y = 0; y < h; y++) {
+ //rsDebug("y", y);
+ for (int x = 0; x < w; x++) {
+
+ int py = rsGetElementAt_uchar(ay, x, y);
+ int pu = rsGetElementAt_uchar(au, x >> 1, y >> 1);
+ int pv = rsGetElementAt_uchar(av, x >> 1, y >> 1);
+
+ //rsDebug("py", py);
+ //rsDebug(" u", pu);
+ //rsDebug(" v", pv);
+
+ uchar4 rgb = yuvToRGBA4(py, pu, pv);
+ //rsDebug(" ", rgb);
+
+ rsSetElementAt_uchar4(aout, rgb, x, y);
+ }
+ }
+}
+
+
+uchar4 __attribute__((kernel)) cvt(uint32_t x, uint32_t y) {
+
+ uchar py = rsGetElementAtYuv_uchar_Y(mInput, x, y);
+ uchar pu = rsGetElementAtYuv_uchar_U(mInput, x, y);
+ uchar pv = rsGetElementAtYuv_uchar_V(mInput, x, y);
+
+ //rsDebug("py2", py);
+ //rsDebug(" u2", pu);
+ //rsDebug(" v2", pv);
+
+ return yuvToRGBA4(py, pu, pv);
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/YuvTest.java b/tests/tests/renderscript/src/android/renderscript/cts/YuvTest.java
new file mode 100644
index 0000000..c2c7275
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/YuvTest.java
@@ -0,0 +1,211 @@
+/*
+ * 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.
+ */
+
+package android.renderscript.cts;
+
+import android.renderscript.*;
+import java.util.Random;
+
+public class YuvTest extends RSBaseCompute {
+ int width;
+ int height;
+ byte [] by;
+ byte [] bu;
+ byte [] bv;
+ Allocation ay;
+ Allocation au;
+ Allocation av;
+
+ protected ScriptC_verify mVerify;
+
+
+ int getCWidth() {
+ return (width + 1) / 2;
+ }
+ int getCHeight() {
+ return (height + 1) / 2;
+ }
+
+ protected void makeYuvBuffer(int w, int h) {
+ Random r = new Random();
+ width = w;
+ height = h;
+
+ by = new byte[w*h];
+ bu = new byte[getCWidth() * getCHeight()];
+ bv = new byte[getCWidth() * getCHeight()];
+
+ for (int i=0; i < by.length; i++) {
+ by[i] = (byte)r.nextInt(256);
+ }
+ for (int i=0; i < bu.length; i++) {
+ bu[i] = (byte)r.nextInt(256);
+ }
+ for (int i=0; i < bv.length; i++) {
+ bv[i] = (byte)r.nextInt(256);
+ }
+
+ Type.Builder tb = new Type.Builder(mRS, Element.U8(mRS));
+ tb.setX(w);
+ tb.setY(h);
+ ay = Allocation.createTyped(mRS, tb.create());
+
+ tb = new Type.Builder(mRS, Element.U8(mRS));
+ tb.setX(w >> 1);
+ tb.setY(h >> 1);
+ au = Allocation.createTyped(mRS, tb.create());
+ av = Allocation.createTyped(mRS, tb.create());
+
+ ay.copyFrom(by);
+ au.copyFrom(bu);
+ av.copyFrom(bv);
+ }
+
+ public Allocation makeOutput() {
+ Type.Builder tb = new Type.Builder(mRS, Element.RGBA_8888(mRS));
+ tb.setX(width);
+ tb.setY(height);
+ Type t = tb.create();
+ return Allocation.createTyped(mRS, t);
+ }
+
+ // Test for the API 17 conversion path
+ // This used a uchar buffer assuming nv21
+ public void testV17() {
+ mVerify = new ScriptC_verify(mRS);
+
+ makeYuvBuffer(120, 96);
+ Allocation aout = makeOutput();
+ Allocation aref = makeOutput();
+
+ byte tmp[] = new byte[(width * height) + (getCWidth() * getCHeight() * 2)];
+ int i = 0;
+ for (int j = 0; j < (width * height); j++) {
+ tmp[i++] = by[j];
+ }
+ for (int j = 0; j < (getCWidth() * getCHeight()); j++) {
+ tmp[i++] = bv[j];
+ tmp[i++] = bu[j];
+ }
+
+ Allocation ta = Allocation.createSized(mRS, Element.U8(mRS), tmp.length);
+ ta.copyFrom(tmp);
+
+
+ ScriptIntrinsicYuvToRGB syuv = ScriptIntrinsicYuvToRGB.create(mRS, Element.U8(mRS));
+ syuv.setInput(ta);
+ syuv.forEach(aout);
+
+ ScriptC_yuv script = new ScriptC_yuv(mRS);
+ script.invoke_makeRef(ay, au, av, aref);
+
+ mVerify.invoke_verify(aref, aout, ay);
+
+ mRS.finish();
+ mVerify.invoke_checkError();
+ waitForMessage();
+ checkForErrors();
+ }
+
+ // Test for the API 18 conversion path with nv21
+ public void test_NV21() {
+ mVerify = new ScriptC_verify(mRS);
+ ScriptC_yuv script = new ScriptC_yuv(mRS);
+ ScriptIntrinsicYuvToRGB syuv = ScriptIntrinsicYuvToRGB.create(mRS, Element.YUV(mRS));
+
+ makeYuvBuffer(512, 512);
+ Allocation aout = makeOutput();
+ Allocation aref = makeOutput();
+
+
+ Type.Builder tb = new Type.Builder(mRS, Element.YUV(mRS));
+ tb.setX(width);
+ tb.setY(height);
+ tb.setYuvFormat(android.graphics.ImageFormat.NV21);
+ Allocation ta = Allocation.createTyped(mRS, tb.create(), Allocation.USAGE_SCRIPT);
+
+ byte tmp[] = new byte[(width * height) + (getCWidth() * getCHeight() * 2)];
+ int i = 0;
+ for (int j = 0; j < (width * height); j++) {
+ tmp[i++] = by[j];
+ }
+ for (int j = 0; j < (getCWidth() * getCHeight()); j++) {
+ tmp[i++] = bv[j];
+ tmp[i++] = bu[j];
+ }
+ ta.copyFrom(tmp);
+ script.invoke_makeRef(ay, au, av, aref);
+
+ syuv.setInput(ta);
+ syuv.forEach(aout);
+ mVerify.invoke_verify(aref, aout, ay);
+
+ script.set_mInput(ta);
+ script.forEach_cvt(aout);
+ mVerify.invoke_verify(aref, aout, ay);
+
+ mRS.finish();
+ mVerify.invoke_checkError();
+ waitForMessage();
+ checkForErrors();
+ }
+
+ // Test for the API 18 conversion path with yv12
+ public void test_YV12() {
+ mVerify = new ScriptC_verify(mRS);
+ ScriptC_yuv script = new ScriptC_yuv(mRS);
+ ScriptIntrinsicYuvToRGB syuv = ScriptIntrinsicYuvToRGB.create(mRS, Element.YUV(mRS));
+
+ makeYuvBuffer(512, 512);
+ Allocation aout = makeOutput();
+ Allocation aref = makeOutput();
+
+
+ Type.Builder tb = new Type.Builder(mRS, Element.YUV(mRS));
+ tb.setX(width);
+ tb.setY(height);
+ tb.setYuvFormat(android.graphics.ImageFormat.YV12);
+ Allocation ta = Allocation.createTyped(mRS, tb.create(), Allocation.USAGE_SCRIPT);
+
+ byte tmp[] = new byte[(width * height) + (getCWidth() * getCHeight() * 2)];
+ int i = 0;
+ for (int j = 0; j < (width * height); j++) {
+ tmp[i++] = by[j];
+ }
+ for (int j = 0; j < (getCWidth() * getCHeight()); j++) {
+ tmp[i++] = bu[j];
+ }
+ for (int j = 0; j < (getCWidth() * getCHeight()); j++) {
+ tmp[i++] = bv[j];
+ }
+ ta.copyFrom(tmp);
+ script.invoke_makeRef(ay, au, av, aref);
+
+ syuv.setInput(ta);
+ syuv.forEach(aout);
+ mVerify.invoke_verify(aref, aout, ay);
+
+ script.set_mInput(ta);
+ script.forEach_cvt(aout);
+ mVerify.invoke_verify(aref, aout, ay);
+
+ mRS.finish();
+ mVerify.invoke_checkError();
+ waitForMessage();
+ checkForErrors();
+ }
+
+}