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 logTiming(myTAG, "PackOutputImage", endnow - startnow); 69 70 startnow = System.nanoTime(); 71 buffers.outAllocation.copyTo(buffers.outputImage); 72 endnow = System.nanoTime(); 73 logTiming(myTAG, "CopyOutputImage", endnow - startnow); 74 75 return buffers.outputImage; 76 } 77 78 /* 79 * Utility Method to extract intermediatory result 80 */ 81 private void extractSharpImage(String name) { 82 83 Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(), 84 buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888); 85 Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap); 86 scriptC.forEach_PackSharpImage(mAllocation); 87 88 mAllocation.copyTo(mBitmap); 89 MediaStoreSaver.savePNG(mBitmap, "sharpd1new", name, renderScript.getApplicationContext()); 90 } 91 /* 92 * Utility Method to extract intermediatory result 93 */ 94 private void extractFuzzyImage(String name) { 95 96 Bitmap mBitmap = Bitmap.createBitmap(buffers.inputImage.getWidth(), 97 buffers.inputImage.getHeight(), Bitmap.Config.ARGB_8888); 98 Allocation mAllocation = Allocation.createFromBitmap(renderScript, mBitmap); 99 scriptC.forEach_PackFuzzyImage(mAllocation); 100 101 mAllocation.copyTo(mBitmap); 102 MediaStoreSaver.savePNG(mBitmap, "fuzzyd1new", name, renderScript.getApplicationContext()); 103 } 104 105 @Override 106 protected void setTargetLayer(LayerInfo layerInfo) { 107 scriptC.invoke_SetTargetLayer(layerInfo.frontDepth, layerInfo.backDepth); 108 } 109 110 @Override 111 protected void setBlendInfo(int dilationRadius) { 112 scriptC.invoke_SetBlendInfo(dilationRadius); 113 } 114 115 @Override 116 protected void setKernelData(int targetLayer, BlurStack blurStack) { 117 KernelDataForRenderScriptd1new kernelData = 118 new KernelDataForRenderScriptd1new(targetLayer, blurStack, renderScript); 119 120 if (ENABLE_FAST_FILTER 121 && kernelData.minDiskRadius > MIN_DISC_RADIUS_FOR_FAST_FILTER) { 122 useFastFilterForCurrentLayer = true; 123 } else { 124 useFastFilterForCurrentLayer = false; 125 } 126 scriptC.set_g_kernel_stack(kernelData.stackAllocation); 127 scriptC.set_galloc_kernel_info(kernelData.infoAllocation); 128 } 129 130 @Override 131 protected void computeLayerMatteBehindFocalDepth() { 132 // Marks active pixels (pixels that are on this target layer); 133 // Marks adjacent pixels that are close enough to active pixels; 134 long startnow; 135 long endnow; 136 137 startnow = System.nanoTime(); 138 //scriptC.forEach_MarkLayerMask(buffers.inAllocation); 139 // Pass sharp meta allocation directly into the kernel 140 scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation); 141 endnow = System.nanoTime(); 142 logTiming(myTAG, "MarkLayerMask", endnow - startnow); 143 144 startnow = System.nanoTime(); 145 //scriptC.forEach_ComputeLayerMatteBehindFocalDepth(buffers.inAllocation); 146 // Pass g_sharp_meta into kernel and get updated g_sharp_meta 147 scriptC.forEach_ComputeLayerMatteBehindFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 148 endnow = System.nanoTime(); 149 logTiming(myTAG, "ComputeLayerMatteBehindFocalDepth", endnow - startnow); 150 } 151 152 @Override 153 protected void filterLayerBehindFocalDepth() { 154 // Filters the target layer and saves the result to {@code g_accum_map} in 155 // .rs file. 156 long startnow; 157 long endnow; 158 159 if (useFastFilterForCurrentLayer) { 160 scriptC.invoke_SetUseIntegralImage(1); 161 Script.LaunchOptions launchOptions = new Script.LaunchOptions(); 162 launchOptions.setX(0, 1); 163 launchOptions.setY(0, buffers.inputImage.getHeight()); 164 165 startnow = System.nanoTime(); 166 scriptC.forEach_ComputeIntegralImageForLayerBehindFocalDepth( 167 buffers.inAllocation, launchOptions); 168 endnow = System.nanoTime(); 169 logTiming(myTAG, "ComputeIntegralImageForLayerBehindFocalDepth", endnow - startnow); 170 } else { 171 scriptC.invoke_SetUseIntegralImage(0); 172 } 173 174 startnow = System.nanoTime(); 175 //scriptC.forEach_FilterLayerBehindFocalDepth(buffers.inAllocation); 176 // Pass g_fuzzy_RGBA into kernel and get g_fuzzy_RGBA as output 177 scriptC.forEach_FilterLayerBehindFocalDepthPassInput(buffers.fuzzyRGBAAllocation, buffers.fuzzyRGBAAllocation); 178 endnow = System.nanoTime(); 179 logTiming(myTAG, "FilterLayerBehindFocalDepth", endnow - startnow); 180 181 //extractFuzzyImage("fuzzy_behind"); 182 //extractSharpImage("sharp_behind"); 183 } 184 185 @Override 186 protected void updateSharpImageUsingFuzzyImage() { 187 long startnow; 188 long endnow; 189 190 startnow = System.nanoTime(); 191 192 //scriptC.forEach_UpdateSharpImageUsingFuzzyImage(buffers.inAllocation); 193 // Pass input and output version of UpdateSharpImageUsingFuzzyImage 194 scriptC.forEach_UpdateSharpUsingFuzzyPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 195 endnow = System.nanoTime(); 196 logTiming(myTAG, "UpdateSharpImageUsingFuzzyImage", endnow - startnow); 197 198 //extractSharpImage("sharp_update"); 199 } 200 201 202 @Override 203 protected void computeLayerMatteInFrontOfFocalDepth() { 204 // Marks active pixels (pixels that are on this target layer); 205 // Marks adjacent pixels that are close enough to active pixels; 206 long startnow; 207 long endnow; 208 209 startnow = System.nanoTime(); 210 //scriptC.forEach_MarkLayerMask(buffers.inAllocation); 211 // Pass sharp meta allocation directly into the kernel 212 scriptC.forEach_MarkLayerMaskPassInput(buffers.sharpActualDepthAllocation); 213 endnow = System.nanoTime(); 214 logTiming(myTAG, "MarkLayerMask", endnow - startnow); 215 216 startnow = System.nanoTime(); 217 //scriptC.forEach_ComputeLayerMatteInFrontOfFocalDepth(buffers.inAllocation); 218 // Pass g_sharp_meta and g_fuzzy_RGBA directly into the kernel 219 scriptC.forEach_ComputeLayerMatteInFrontOfFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 220 endnow = System.nanoTime(); 221 logTiming(myTAG, "ComputeLayerMatteInFrontOfFocalDepth", endnow - startnow); 222 } 223 224 @Override 225 protected void filterLayerInFrontOfFocalDepth() { 226 // Filters the target layer and accumulates the result to {@code 227 // g_accum_map} in .rs file. 228 long startnow; 229 long endnow; 230 if (useFastFilterForCurrentLayer) { 231 scriptC.invoke_SetUseIntegralImage(1); 232 Script.LaunchOptions launchOptions = new Script.LaunchOptions(); 233 launchOptions.setX(0, 1); 234 launchOptions.setY(0, buffers.inputImage.getHeight()); 235 236 startnow = System.nanoTime(); 237 scriptC.forEach_ComputeIntegralImageForLayerInFrontOfFocalDepth( 238 buffers.inAllocation, launchOptions); 239 endnow = System.nanoTime(); 240 logTiming(myTAG, "ComputeIntegralImageForLayerInFrontOfFocalDepth", endnow - startnow); 241 } else { 242 scriptC.invoke_SetUseIntegralImage(0); 243 } 244 startnow = System.nanoTime(); 245 //scriptC.forEach_FilterLayerInFrontOfFocalDepth(buffers.inAllocation); 246 // Pass g_sharp_dilated_depth into kernel and get g_fuzzy_RGBA as output 247 scriptC.forEach_FilterLayerInFrontOfFocalDepthPassInput(buffers.sharpDilatedDepthAllocation, buffers.sharpDilatedDepthAllocation); 248 endnow = System.nanoTime(); 249 logTiming(myTAG, "FilterLayerInFrontOfFocalDepth", endnow - startnow); 250 251 //extractFuzzyImage("fuzzy_front"); 252 //extractSharpImage("sharp_front"); 253 } 254 255 @Override 256 protected void finalizeFuzzyImageUsingSharpImage() { 257 // Blends {@code g_accum_map} and {@code g_focus_map} in .rs file. 258 // Saves the result in {@code g_accum_map}. 259 long startnow; 260 long endnow; 261 startnow = System.nanoTime(); 262 scriptC.forEach_FinalizeFuzzyImageUsingSharpImage(buffers.inAllocation); 263 //scriptC.forEach_FinalizeFuzzyImageUsingSharpImagePassInput(buffers.sharpActualDepthAllocation, buffers.fuzzyRGBAAllocation); 264 endnow = System.nanoTime(); 265 logTiming(myTAG, "FinalizeFuzzyImageUsingSharpImage", endnow - startnow); 266 } 267} 268