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