1package com.android.rs.refocus.d1new; 2 3import com.android.rs.refocus.BlurStack; 4import com.android.rs.refocus.KernelDataForRenderScript; 5import com.android.rs.refocus.LayerInfo; 6import com.android.rs.refocus.MediaStoreSaver; 7import com.android.rs.refocus.R; 8import com.android.rs.refocus.RefocusFilter; 9import com.android.rs.refocus.renderscript.ScriptC_layered_filter_fast_d1new; 10 11import android.graphics.Bitmap; 12import android.support.v8.renderscript.Allocation; 13import android.support.v8.renderscript.RenderScript; 14import android.support.v8.renderscript.Script; 15import android.util.Log; 16/** 17 18/** 19 * An accelerated implementation of RefocusFilter using float32 as pixel 20 * representation. The corresponding RenderScript class is 21 * ScriptC_layered_filter_Fast. Integral image is used for the speedup. 22 * 23 * Example Usage: 24 * 25 * {@code RenderScript renderScript = RenderScript.create(context);} 26 * {@code RefocusFilterd1new rfFilter = new RefocusFilterd1new(renderScript);} 27 * {@code ProgressCallback progress;} 28 * {@code Bitmap result = rfFilter.compute(rgbdImage, blurStack, progress);} 29 * 30 * @author zhl@google.com (Li Zhang) 31 */ 32public class RefocusFilterd1new extends 33 RefocusFilter<ScriptC_layered_filter_fast_d1new> { 34 private static final String myTAG = "RefocusFilterd1new"; 35 private static final boolean ENABLE_FAST_FILTER = true; 36 private static final float MIN_DISC_RADIUS_FOR_FAST_FILTER = 3; 37 boolean useFastFilterForCurrentLayer = false; 38 ImageBuffersForRenderScriptd1new buffers; 39 40 public RefocusFilterd1new(RenderScript rs) { 41 super(rs); 42 } 43 44 @Override 45 protected void initializeScriptAndBuffers(Bitmap inputImage, 46 LayerInfo focalLayer) { 47 scriptC = new ScriptC_layered_filter_fast_d1new(renderScript); 48 49 // Allocates, binds, and initializes buffers that interface between Java 50 // and Render Script. 51 // + 1 is for the boundary case of using integral image. 52 KernelDataForRenderScript.setUseNewRS(true); 53 int margin = KernelDataForRenderScript.getMaxKernelRadius() + 1; 54 buffers = new ImageBuffersForRenderScriptd1new(inputImage, margin, 55 renderScript, scriptC); 56 buffers.initializeRenderScript(focalLayer, scriptC); 57 58 } 59 60 @Override 61 protected Bitmap extractResultImage() { 62 // Extracts the result from .rs file to {@code buffers.outputImage} in Java. 63 long startnow; 64 long endnow; 65 startnow = System.nanoTime(); 66 scriptC.forEach_PackOutputImage(buffers.outAllocation); 67 endnow = System.nanoTime(); 68 Log.d(myTAG, "PackOutputImage: "+(endnow - startnow)+ " ns" ); 69 70 buffers.outAllocation.copyTo(buffers.outputImage); 71 return buffers.outputImage; 72 } 73 74 /* 75 * Utility Method to extract intermediatory result 76 */ 77 private void extractSharpImage(String name) { 78 79 Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(), 80 buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888); 81 Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap); 82 scriptC.forEach_PackSharpImage(mAllocation); 83 84 mAllocation.copyTo(mBitmap); 85 MediaStoreSaver.savePNG(mBitmap, "sharpd1new", name, renderScript.getApplicationContext()); 86 } 87 /* 88 * Utility Method to extract intermediatory result 89 */ 90 private void extractFuzzyImage(String name) { 91 92 Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(), 93 buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888); 94 Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap); 95 scriptC.forEach_PackFuzzyImage(mAllocation); 96 97 mAllocation.copyTo(mBitmap); 98 MediaStoreSaver.savePNG(mBitmap, "fuzzyd1new", name, renderScript.getApplicationContext()); 99 } 100 101 @Override 102 protected void setTargetLayer(LayerInfo layerInfo) { 103 scriptC.invoke_SetTargetLayer(layerInfo.frontDepth, layerInfo.backDepth); 104 } 105 106 @Override 107 protected void setBlendInfo(int dilationRadius) { 108 scriptC.invoke_SetBlendInfo(dilationRadius); 109 } 110 111 @Override 112 protected void setKernelData(int targetLayer, BlurStack blurStack) { 113 KernelDataForRenderScriptd1new kernelData = 114 new KernelDataForRenderScriptd1new(targetLayer, blurStack, renderScript); 115 116 if (ENABLE_FAST_FILTER 117 && kernelData.minDiskRadius > MIN_DISC_RADIUS_FOR_FAST_FILTER) { 118 useFastFilterForCurrentLayer = true; 119 } else { 120 useFastFilterForCurrentLayer = false; 121 } 122 scriptC.set_g_kernel_stack(kernelData.stackAllocation); 123 scriptC.set_galloc_kernel_info(kernelData.infoAllocation); 124 } 125 126 @Override 127 protected void computeLayerMatteBehindFocalDepth() { 128 // Marks active pixels (pixels that are on this target layer); 129 // Marks adjacent pixels that are close enough to active pixels; 130 long startnow; 131 long endnow; 132 133 startnow = System.nanoTime(); 134 //scriptC.forEach_MarkLayerMask(buffers.inAllocation); 135 // Pass sharp meta allocation directly into the kernel 136 scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation, buffers.sharpDilatedDepthAllocation); 137 endnow = System.nanoTime(); 138 Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" ); 139 140 startnow = System.nanoTime(); 141 //scriptC.forEach_ComputeLayerMatteBehindFocalDepth(buffers.inAllocation); 142 // Pass g_sharp_meta into kernel and get updated g_sharp_meta 143 scriptC.forEach_ComputeLayerMatteBehindFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 144 endnow = System.nanoTime(); 145 Log.d(myTAG, "ComputeLayerMatteBehindFocalDepth: "+(endnow - startnow)+ " ns" ); 146 } 147 148 @Override 149 protected void filterLayerBehindFocalDepth() { 150 // Filters the target layer and saves the result to {@code g_accum_map} in 151 // .rs file. 152 long startnow; 153 long endnow; 154 155 if (useFastFilterForCurrentLayer) { 156 scriptC.invoke_SetUseIntegralImage(1); 157 Script.LaunchOptions launchOptions = new Script.LaunchOptions(); 158 launchOptions.setX(0, 1); 159 launchOptions.setY(0, buffers.inputImage.getHeight()); 160 161 startnow = System.nanoTime(); 162 scriptC.forEach_ComputeIntegralImageForLayerBehindFocalDepth( 163 buffers.inAllocation, launchOptions); 164 endnow = System.nanoTime(); 165 Log.d(myTAG, "ComputeIntegralImageForLayerBehindFocalDepth: "+(endnow - startnow)+ " ns" ); 166 } else { 167 scriptC.invoke_SetUseIntegralImage(0); 168 } 169 170 startnow = System.nanoTime(); 171 //scriptC.forEach_FilterLayerBehindFocalDepth(buffers.inAllocation); 172 // Pass g_fuzzy_RGBA into kernel and get g_fuzzy_RGBA as output 173 scriptC.forEach_FilterLayerBehindFocalDepthPassInput(buffers.fuzzyRGBAAllocation, buffers.fuzzyRGBAAllocation); 174 endnow = System.nanoTime(); 175 Log.d(myTAG, "FilterLayerBehindFocalDepth: "+(endnow - startnow)+ " ns" ); 176 //extractFuzzyImage("fuzzy_behind"); 177 //extractSharpImage("sharp_behind"); 178 } 179 180 @Override 181 protected void updateSharpImageUsingFuzzyImage() { 182 long startnow; 183 long endnow; 184 185 startnow = System.nanoTime(); 186 187 //scriptC.forEach_UpdateSharpImageUsingFuzzyImage(buffers.inAllocation); 188 // Pass input and output version of UpdateSharpImageUsingFuzzyImage 189 scriptC.forEach_UpdateSharpUsingFuzzyPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 190 191 endnow = System.nanoTime(); 192 Log.d(myTAG, "updateSharpImageUsingFuzzyImage: "+(endnow - startnow)+ " ns" ); 193 //extractSharpImage("sharp_update"); 194 } 195 196 197 @Override 198 protected void computeLayerMatteInFrontOfFocalDepth() { 199 // Marks active pixels (pixels that are on this target layer); 200 // Marks adjacent pixels that are close enough to active pixels; 201 long startnow; 202 long endnow; 203 204 startnow = System.nanoTime(); 205 //scriptC.forEach_MarkLayerMask(buffers.inAllocation); 206 // Pass sharp meta allocation directly into the kernel 207 scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation, buffers.sharpDilatedDepthAllocation); 208 endnow = System.nanoTime(); 209 Log.d(myTAG, "MarkLayerMask: "+(endnow - startnow)+ " ns" ); 210 211 startnow = System.nanoTime(); 212 //scriptC.forEach_ComputeLayerMatteInFrontOfFocalDepth(buffers.inAllocation); 213 // Pass g_sharp_meta and g_fuzzy_RGBA directly into the kernel 214 scriptC.forEach_ComputeLayerMatteInFrontOfFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 215 endnow = System.nanoTime(); 216 Log.d(myTAG, "ComputeLayerMatteInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" ); 217 } 218 219 @Override 220 protected void filterLayerInFrontOfFocalDepth() { 221 // Filters the target layer and accumulates the result to {@code 222 // g_accum_map} in .rs file. 223 long startnow; 224 long endnow; 225 if (useFastFilterForCurrentLayer) { 226 scriptC.invoke_SetUseIntegralImage(1); 227 Script.LaunchOptions launchOptions = new Script.LaunchOptions(); 228 launchOptions.setX(0, 1); 229 launchOptions.setY(0, buffers.inputImage.getHeight()); 230 231 startnow = System.nanoTime(); 232 scriptC.forEach_ComputeIntegralImageForLayerInFrontOfFocalDepth( 233 buffers.inAllocation, launchOptions); 234 endnow = System.nanoTime(); 235 Log.d(myTAG, "ComputeIntegralImageForLayerInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" ); 236 } else { 237 scriptC.invoke_SetUseIntegralImage(0); 238 } 239 startnow = System.nanoTime(); 240 //scriptC.forEach_FilterLayerInFrontOfFocalDepth(buffers.inAllocation); 241 // Pass g_sharp_dilated_depth into kernel and get g_fuzzy_RGBA as output 242 scriptC.forEach_FilterLayerInFrontOfFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 243 endnow = System.nanoTime(); 244 Log.d(myTAG, "FilterLayerInFrontOfFocalDepth: "+(endnow - startnow)+ " ns" ); 245 246 //extractFuzzyImage("fuzzy_front"); 247 //extractSharpImage("sharp_front"); 248 } 249 250 @Override 251 protected void finalizeFuzzyImageUsingSharpImage() { 252 // Blends {@code g_accum_map} and {@code g_focus_map} in .rs file. 253 // Saves the result in {@code g_accum_map}. 254 long startnow; 255 long endnow; 256 startnow = System.nanoTime(); 257 scriptC.forEach_FinalizeFuzzyImageUsingSharpImage(buffers.inAllocation); 258 //scriptC.forEach_FinalizeFuzzyImageUsingSharpImagePassInput(buffers.sharpActualDepthAllocation, buffers.fuzzyRGBAAllocation); 259 endnow = System.nanoTime(); 260 Log.d(myTAG, "finalizeFuzzyImageUsingSharpImage: "+(endnow - startnow)+ " ns" ); 261 } 262} 263