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