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