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