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