1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.gallery3d.filtershow.filters;
18
19import android.graphics.Bitmap;
20import android.graphics.Color;
21import android.graphics.Matrix;
22
23import com.android.gallery3d.R;
24import com.android.gallery3d.filtershow.pipeline.FilterEnvironment;
25
26import android.graphics.Bitmap;
27import android.graphics.Color;
28import android.graphics.Matrix;
29import android.support.v8.renderscript.Allocation;
30import android.support.v8.renderscript.Element;
31import android.support.v8.renderscript.RenderScript;
32import android.support.v8.renderscript.Script.LaunchOptions;
33import android.support.v8.renderscript.Type;
34import android.util.Log;
35
36import com.android.gallery3d.R;
37import com.android.gallery3d.filtershow.pipeline.FilterEnvironment;
38
39public class ImageFilterGrad extends ImageFilterRS {
40    private static final String LOGTAG = "ImageFilterGrad";
41    private ScriptC_grad mScript;
42    private Bitmap mSourceBitmap;
43    private static final int RADIUS_SCALE_FACTOR = 160;
44
45    private static final int STRIP_SIZE = 64;
46
47    FilterGradRepresentation mParameters = new FilterGradRepresentation();
48    private Bitmap mOverlayBitmap;
49
50    public ImageFilterGrad() {
51        mName = "grad";
52    }
53
54    @Override
55    public FilterRepresentation getDefaultRepresentation() {
56        return new FilterGradRepresentation();
57    }
58
59    @Override
60    public void useRepresentation(FilterRepresentation representation) {
61        mParameters = (FilterGradRepresentation) representation;
62    }
63
64    @Override
65    protected void resetAllocations() {
66
67    }
68
69    @Override
70    public void resetScripts() {
71        if (mScript != null) {
72            mScript.destroy();
73            mScript = null;
74        }
75    }
76    @Override
77    protected void createFilter(android.content.res.Resources res, float scaleFactor,
78                                int quality) {
79        createFilter(res, scaleFactor, quality, getInPixelsAllocation());
80    }
81
82    @Override
83    protected void createFilter(android.content.res.Resources res, float scaleFactor,
84                                int quality, Allocation in) {
85        RenderScript rsCtx = getRenderScriptContext();
86
87        Type.Builder tb_float = new Type.Builder(rsCtx, Element.F32_4(rsCtx));
88        tb_float.setX(in.getType().getX());
89        tb_float.setY(in.getType().getY());
90        mScript = new ScriptC_grad(rsCtx, res, R.raw.grad);
91    }
92
93
94    private Bitmap getSourceBitmap() {
95        assert (mSourceBitmap != null);
96        return mSourceBitmap;
97    }
98
99    @Override
100    public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
101        if (SIMPLE_ICONS && FilterEnvironment.QUALITY_ICON == quality) {
102            return bitmap;
103        }
104
105        mSourceBitmap = bitmap;
106        Bitmap ret = super.apply(bitmap, scaleFactor, quality);
107        mSourceBitmap = null;
108
109        return ret;
110    }
111
112    @Override
113    protected void bindScriptValues() {
114        int width = getInPixelsAllocation().getType().getX();
115        int height = getInPixelsAllocation().getType().getY();
116        mScript.set_inputWidth(width);
117        mScript.set_inputHeight(height);
118    }
119
120    @Override
121    protected void runFilter() {
122        int[] x1 = mParameters.getXPos1();
123        int[] y1 = mParameters.getYPos1();
124        int[] x2 = mParameters.getXPos2();
125        int[] y2 = mParameters.getYPos2();
126
127        int width = getInPixelsAllocation().getType().getX();
128        int height = getInPixelsAllocation().getType().getY();
129        Matrix m = getOriginalToScreenMatrix(width, height);
130        float[] coord = new float[2];
131        for (int i = 0; i < x1.length; i++) {
132            coord[0] = x1[i];
133            coord[1] = y1[i];
134            m.mapPoints(coord);
135            x1[i] = (int) coord[0];
136            y1[i] = (int) coord[1];
137            coord[0] = x2[i];
138            coord[1] = y2[i];
139            m.mapPoints(coord);
140            x2[i] = (int) coord[0];
141            y2[i] = (int) coord[1];
142        }
143
144        mScript.set_mask(mParameters.getMask());
145        mScript.set_xPos1(x1);
146        mScript.set_yPos1(y1);
147        mScript.set_xPos2(x2);
148        mScript.set_yPos2(y2);
149
150        mScript.set_brightness(mParameters.getBrightness());
151        mScript.set_contrast(mParameters.getContrast());
152        mScript.set_saturation(mParameters.getSaturation());
153
154        mScript.invoke_setupGradParams();
155        runSelectiveAdjust(
156                getInPixelsAllocation(), getOutPixelsAllocation());
157
158    }
159
160    private void runSelectiveAdjust(Allocation in, Allocation out) {
161        int width = in.getType().getX();
162        int height = in.getType().getY();
163
164        LaunchOptions options = new LaunchOptions();
165        int ty;
166        options.setX(0, width);
167
168        for (ty = 0; ty < height; ty += STRIP_SIZE) {
169            int endy = ty + STRIP_SIZE;
170            if (endy > height) {
171                endy = height;
172            }
173            options.setY(ty, endy);
174            mScript.forEach_selectiveAdjust(in, out, options);
175            if (checkStop()) {
176                return;
177            }
178        }
179    }
180
181    private boolean checkStop() {
182        RenderScript rsCtx = getRenderScriptContext();
183        rsCtx.finish();
184        if (getEnvironment().needsStop()) {
185            return true;
186        }
187        return false;
188    }
189}
190
191