1a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard/*
2a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * Copyright (C) 2012 The Android Open Source Project
3a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard *
4a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * Licensed under the Apache License, Version 2.0 (the "License");
5a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * you may not use this file except in compliance with the License.
6a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * You may obtain a copy of the License at
7a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard *
8a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard *      http://www.apache.org/licenses/LICENSE-2.0
9a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard *
10a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * Unless required by applicable law or agreed to in writing, software
11a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * distributed under the License is distributed on an "AS IS" BASIS,
12a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * See the License for the specific language governing permissions and
14a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * limitations under the License.
15a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard */
160d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
170d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardpackage com.android.gallery3d.filtershow.filters;
180d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
19f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport android.content.res.Resources;
200d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport android.graphics.Bitmap;
21f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport android.graphics.Canvas;
22708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hofordimport android.graphics.Matrix;
23f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport android.graphics.Rect;
24f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport com.android.gallery3d.R;
25708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hofordimport com.android.gallery3d.filtershow.imageshow.MasterImage;
26ce9ceff5776a9b0479c30cbeb2a9388b44df1865nicolasroardimport com.android.gallery3d.filtershow.pipeline.FilterEnvironment;
27bed4ef971605f343785c3f4c244a1ada51d764cdMiao Wangimport android.renderscript.Allocation;
28bed4ef971605f343785c3f4c244a1ada51d764cdMiao Wangimport android.renderscript.Element;
29bed4ef971605f343785c3f4c244a1ada51d764cdMiao Wangimport android.renderscript.RenderScript;
30bed4ef971605f343785c3f4c244a1ada51d764cdMiao Wangimport android.renderscript.Script.LaunchOptions;
31bed4ef971605f343785c3f4c244a1ada51d764cdMiao Wangimport android.renderscript.Type;
3237f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hofordimport android.util.Log;
33a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford
3437f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hofordpublic class ImageFilterVignette extends ImageFilterRS {
3571f04cbaedbb89e313e0b86b531640db2d3f6016nicolasroard    private static final String LOGTAG = "ImageFilterVignette";
36f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private Bitmap mOverlayBitmap;
3737f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    private ScriptC_vignette mScript;
3837f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    FilterVignetteRepresentation mParameters;
3937f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    public static final int MODE_VIGNETTE = FilterVignetteRepresentation.MODE_VIGNETTE;
4037f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    public static final int MODE_EXPOSURE = FilterVignetteRepresentation.MODE_EXPOSURE;
4137f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    public static final int MODE_SATURATION = FilterVignetteRepresentation.MODE_SATURATION;
4237f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    public static final int MODE_CONTRAST = FilterVignetteRepresentation.MODE_CONTRAST;
4337f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    public static final int MODE_FALLOFF = FilterVignetteRepresentation.MODE_FALLOFF;
440d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
45bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard    public ImageFilterVignette() {
46bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard        mName = "Vignette";
470d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
480d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
49a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford    @Override
5071f04cbaedbb89e313e0b86b531640db2d3f6016nicolasroard    public FilterRepresentation getDefaultRepresentation() {
51a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford        FilterVignetteRepresentation representation = new FilterVignetteRepresentation();
5271f04cbaedbb89e313e0b86b531640db2d3f6016nicolasroard        return representation;
5371f04cbaedbb89e313e0b86b531640db2d3f6016nicolasroard    }
5471f04cbaedbb89e313e0b86b531640db2d3f6016nicolasroard
5537f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    @Override
5637f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    public void useRepresentation(FilterRepresentation representation) {
5737f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mParameters = (FilterVignetteRepresentation) representation;
5837f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    }
5937f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
60a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford    native protected void nativeApplyFilter(
6137f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford            Bitmap bitmap, int w, int h, int cx, int cy, float radx, float rady,
6237f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford            float strength, float finalValue);
63a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford
64a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford    private float calcRadius(float cx, float cy, int w, int h) {
65a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford        float d = cx;
66a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford        if (d < (w - cx)) {
67a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford            d = w - cx;
68a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford        }
69a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford        if (d < cy) {
70a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford            d = cy;
71a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford        }
72a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford        if (d < (h - cy)) {
73a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford            d = h - cy;
74a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford        }
75a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford        return d * d * 2.0f;
76a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford    }
770d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
7881eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    @Override
7937f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    protected void createFilter(Resources res, float scaleFactor, int quality) {
8037f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        RenderScript rsCtx = getRenderScriptContext();
8137f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
821bfb4e42a0dd97a78cd13d35f0c2b7add600357cMiao Wang        mScript = new ScriptC_vignette(rsCtx);
8337f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    }
8437f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
8537f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    @Override
8637f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    protected void runFilter() {
8737f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
8837f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        int w = getInPixelsAllocation().getType().getX();
8937f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        int h = getInPixelsAllocation().getType().getY();
9037f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
9137f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        float cx = w / 2;
9237f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        float cy = h / 2;
9337f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        float r = calcRadius(cx, cy, w, h);
9437f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        float rx = r;
9537f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        float ry = r;
9637f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
97708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford        float[]c = new float[2];
98708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford        if (mParameters.isCenterSet()) {
99708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            Matrix m = getOriginalToScreenMatrix(w, h);
100708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            Rect bounds = MasterImage.getImage().getOriginalBounds();
101708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            c[0] = bounds.right * mParameters.getCenterX();
102708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            c[1] = bounds.bottom * mParameters.getCenterY();
103708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            m.mapPoints(c);
104708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            cx = c[0];
105708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            cy = c[1];
106708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            c[0] = bounds.right * mParameters.getRadiusX();
107708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            c[1] = bounds.bottom * mParameters.getRadiusY();
108708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            m.mapVectors(c);
109708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            rx = c[0];
110708753f5a087eb759ef48fe9b41ef2274d2e88a7John Hoford            ry = c[1];
11137f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        }
11237f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
11337f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_inputWidth(w);
11437f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_inputHeight(h);
11537f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        int v = mParameters.getValue(MODE_VIGNETTE);
11637f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_finalSubtract((v < 0) ? v : 0);
11737f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_finalBright((v > 0) ? -v : 0);
11837f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_finalSaturation(mParameters.getValue(MODE_SATURATION));
11937f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_finalContrast(mParameters.getValue(MODE_CONTRAST));
12037f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_centerx(cx);
12137f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_centery(cy);
12237f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_radiusx(rx);
12337f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_radiusy(ry);
12437f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_strength(mParameters.getValue(MODE_FALLOFF)/10.f);
12537f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.invoke_setupVignetteParams();
12637f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.forEach_vignette(getInPixelsAllocation(), getOutPixelsAllocation());
12737f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    }
12837f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
12937f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    @Override
13099baf61387ab1ef15bb9db5fa3b2b55591e87059John Hoford    public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
13136e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        if (SIMPLE_ICONS && FilterEnvironment.QUALITY_ICON == quality) {
132f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            if (mOverlayBitmap == null) {
13336e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard                Resources res = getEnvironment().getPipeline().getResources();
134f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                mOverlayBitmap = IconUtilities.getFXBitmap(res,
135f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                        R.drawable.filtershow_icon_vignette);
136f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            }
13737f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
138f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            Canvas c = new Canvas(bitmap);
139f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            int dim = Math.max(bitmap.getWidth(), bitmap.getHeight());
140f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            Rect r = new Rect(0, 0, dim, dim);
141f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            c.drawBitmap(mOverlayBitmap, null, r, null);
142f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            return bitmap;
143f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        }
14437f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        Bitmap ret = super.apply(bitmap, scaleFactor, quality);
14581eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard        return bitmap;
1460d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
14737f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
14837f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
14937f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    @Override
15037f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    protected void resetAllocations() {
15137f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
15237f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    }
15337f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
15437f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    @Override
15537f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    public void resetScripts() {
15637f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
15737f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    }
15837f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford
15937f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    @Override
16037f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    protected void bindScriptValues() {
16137f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        int width = getInPixelsAllocation().getType().getX();
16237f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        int height = getInPixelsAllocation().getType().getY();
16337f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_inputWidth(width);
16437f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford        mScript.set_inputHeight(height);
16537f8e432f4eb94d0ab483bfdc2a1fa024508e85fJohn Hoford    }
1660d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard}
167