1a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams/* 2a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * Copyright (C) 2012 The Android Open Source Project 3a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 4a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 5a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * you may not use this file except in compliance with the License. 6a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * You may obtain a copy of the License at 7a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 8a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * http://www.apache.org/licenses/LICENSE-2.0 9a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 10a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * Unless required by applicable law or agreed to in writing, software 11a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * distributed under the License is distributed on an "AS IS" BASIS, 12a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * See the License for the specific language governing permissions and 14a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * limitations under the License. 15a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams */ 16a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 17a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Samspackage android.support.v8.renderscript; 18a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 19a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Samsimport android.util.Log; 20a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 21a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams/** 22a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * Intrinsic for applying a per-channel lookup table. Each 23a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * channel of the input has an independant lookup table. The 24a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * tables are 256 entries in size and can cover the full value 25a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * range of {@link Element#U8_4}. 26a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams **/ 27baf4b4a16ff2ab85653438b93db9af03d4375f2dTim Murraypublic class ScriptIntrinsicLUT extends ScriptIntrinsic { 28a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams private final Matrix4f mMatrix = new Matrix4f(); 29a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams private Allocation mTables; 30a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams private final byte mCache[] = new byte[1024]; 31a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams private boolean mDirty = true; 326f5555db1af436bb5aad430e6e00aa5b69d5ca6cMiao Wang // API level for the intrinsic 336f5555db1af436bb5aad430e6e00aa5b69d5ca6cMiao Wang private static final int INTRINSIC_API_LEVEL = 19; 34a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 35bec39b6de685a7dddb1925c7e9f83fae20388de3Miao Wang protected ScriptIntrinsicLUT(long id, RenderScript rs) { 36a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams super(id, rs); 37a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 38a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 39a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams /** 40a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * Supported elements types are {@link Element#U8_4} 41a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 42a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * The defaults tables are identity. 43a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 44032b2c2c8a3cf2c55f6f08557f2648d799766c4eStephen Hines * @param rs The RenderScript context 45a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @param e Element type for intputs and outputs 46a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 47a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @return ScriptIntrinsicLUT 48a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams */ 49a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams public static ScriptIntrinsicLUT create(RenderScript rs, Element e) { 506f5555db1af436bb5aad430e6e00aa5b69d5ca6cMiao Wang long id; 516f5555db1af436bb5aad430e6e00aa5b69d5ca6cMiao Wang boolean mUseIncSupp = rs.isUseNative() && 526f5555db1af436bb5aad430e6e00aa5b69d5ca6cMiao Wang android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL; 536f5555db1af436bb5aad430e6e00aa5b69d5ca6cMiao Wang 546f5555db1af436bb5aad430e6e00aa5b69d5ca6cMiao Wang id = rs.nScriptIntrinsicCreate(3, e.getID(rs), mUseIncSupp); 55a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 56baf4b4a16ff2ab85653438b93db9af03d4375f2dTim Murray ScriptIntrinsicLUT si = new ScriptIntrinsicLUT(id, rs); 576f5555db1af436bb5aad430e6e00aa5b69d5ca6cMiao Wang si.setIncSupp(mUseIncSupp); 58baf4b4a16ff2ab85653438b93db9af03d4375f2dTim Murray si.mTables = Allocation.createSized(rs, Element.U8(rs), 1024); 59baf4b4a16ff2ab85653438b93db9af03d4375f2dTim Murray for (int ct=0; ct < 256; ct++) { 60baf4b4a16ff2ab85653438b93db9af03d4375f2dTim Murray si.mCache[ct] = (byte)ct; 61baf4b4a16ff2ab85653438b93db9af03d4375f2dTim Murray si.mCache[ct + 256] = (byte)ct; 62baf4b4a16ff2ab85653438b93db9af03d4375f2dTim Murray si.mCache[ct + 512] = (byte)ct; 63baf4b4a16ff2ab85653438b93db9af03d4375f2dTim Murray si.mCache[ct + 768] = (byte)ct; 64baf4b4a16ff2ab85653438b93db9af03d4375f2dTim Murray } 65baf4b4a16ff2ab85653438b93db9af03d4375f2dTim Murray si.setVar(0, si.mTables); 66baf4b4a16ff2ab85653438b93db9af03d4375f2dTim Murray return si; 67a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 68a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 69a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 70a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams private void validate(int index, int value) { 71a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams if (index < 0 || index > 255) { 72a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams throw new RSIllegalArgumentException("Index out of range (0-255)."); 73a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 74a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams if (value < 0 || value > 255) { 75a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams throw new RSIllegalArgumentException("Value out of range (0-255)."); 76a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 77a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 78a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 79a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams /** 80a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * Set an entry in the red channel lookup table 81a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 82a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @param index Must be 0-255 83a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @param value Must be 0-255 84a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams */ 85a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams public void setRed(int index, int value) { 86a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams validate(index, value); 87a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams mCache[index] = (byte)value; 88a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams mDirty = true; 89a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 90a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 91a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams /** 92a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * Set an entry in the green channel lookup table 93a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 94a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @param index Must be 0-255 95a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @param value Must be 0-255 96a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams */ 97a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams public void setGreen(int index, int value) { 98a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams validate(index, value); 99a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams mCache[index+256] = (byte)value; 100a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams mDirty = true; 101a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 102a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 103a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams /** 104a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * Set an entry in the blue channel lookup table 105a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 106a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @param index Must be 0-255 107a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @param value Must be 0-255 108a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams */ 109a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams public void setBlue(int index, int value) { 110a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams validate(index, value); 111a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams mCache[index+512] = (byte)value; 112a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams mDirty = true; 113a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 114a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 115a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams /** 116a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * Set an entry in the alpha channel lookup table 117a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 118a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @param index Must be 0-255 119a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @param value Must be 0-255 120a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams */ 121a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams public void setAlpha(int index, int value) { 122a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams validate(index, value); 123a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams mCache[index+768] = (byte)value; 124a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams mDirty = true; 125a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 126a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 127a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 128a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams /** 129a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * Invoke the kernel and apply the lookup to each cell of ain 130a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * and copy to aout. 131a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 132a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @param ain Input allocation 133a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @param aout Output allocation 134a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams */ 135a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams public void forEach(Allocation ain, Allocation aout) { 136a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams if (mDirty) { 137a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams mDirty = false; 138a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams mTables.copyFromUnchecked(mCache); 139a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 140a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams forEach(0, ain, aout, null); 141a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 142a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 143a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams /** 144a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * Get a KernelID for this intrinsic kernel. 145a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * 146a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams * @return Script.KernelID The KernelID object. 147a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams */ 148a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams public Script.KernelID getKernelID() { 149a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams return createKernelID(0, 3, null, null); 150a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams } 151a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams} 152a5e8cafe9173abee2b47e7c927210a22934a30e5Jason Sams 153