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.presets;
180d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
190d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport android.graphics.Bitmap;
200d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport android.util.Log;
210d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
22bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroardimport com.android.gallery3d.filtershow.ImageStateAdapter;
23e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hofordimport com.android.gallery3d.filtershow.cache.ImageLoader;
240d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport com.android.gallery3d.filtershow.filters.ImageFilter;
258537d097f8827caedc8c39564de54d36eae8b16fRuben Brunkimport com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
260d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport com.android.gallery3d.filtershow.imageshow.ImageShow;
270d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
2892e2341248e99c691f38820503984bc5e2f18811nicolasroardimport java.util.Vector;
2992e2341248e99c691f38820503984bc5e2f18811nicolasroard
300d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardpublic class ImagePreset {
310d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
320d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    private static final String LOGTAG = "ImagePreset";
3393dfe7a1df07a64701369b480578410efb740a27nicolasroard
3493dfe7a1df07a64701369b480578410efb740a27nicolasroard    private ImageShow mEndPoint = null;
3593dfe7a1df07a64701369b480578410efb740a27nicolasroard    private ImageFilter mImageBorder = null;
3693dfe7a1df07a64701369b480578410efb740a27nicolasroard    private float mScaleFactor = 1.0f;
3793dfe7a1df07a64701369b480578410efb740a27nicolasroard    private boolean mIsHighQuality = false;
38e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford    private ImageLoader mImageLoader = null;
3993dfe7a1df07a64701369b480578410efb740a27nicolasroard
400d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    protected Vector<ImageFilter> mFilters = new Vector<ImageFilter>();
410d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    protected String mName = "Original";
420a32b7afc5286a5c7aa334b9338591d61a49731fRuben Brunk    private String mHistoryName = "Original";
430d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    protected boolean mIsFxPreset = false;
440d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
4531529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard    private boolean mDoApplyGeometry = true;
4631529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard    private boolean mDoApplyFilters = true;
4731529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard
488537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk    public final GeometryMetadata mGeoData = new GeometryMetadata();
498537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk
5093dfe7a1df07a64701369b480578410efb740a27nicolasroard    enum FullRotate {
5193dfe7a1df07a64701369b480578410efb740a27nicolasroard        ZERO, NINETY, HUNDRED_EIGHTY, TWO_HUNDRED_SEVENTY
528537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk    }
530d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
540d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public ImagePreset() {
550d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        setup();
560d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
570d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
580a32b7afc5286a5c7aa334b9338591d61a49731fRuben Brunk    public ImagePreset(String historyName) {
590a32b7afc5286a5c7aa334b9338591d61a49731fRuben Brunk        setHistoryName(historyName);
600a32b7afc5286a5c7aa334b9338591d61a49731fRuben Brunk        setup();
610a32b7afc5286a5c7aa334b9338591d61a49731fRuben Brunk    }
620a32b7afc5286a5c7aa334b9338591d61a49731fRuben Brunk
63a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford    public ImagePreset(ImagePreset source, String historyName) {
64a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford        this(source);
6555550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard        if (historyName != null) {
6655550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard            setHistoryName(historyName);
6755550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard        }
68a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford    }
69a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford
700d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public ImagePreset(ImagePreset source) {
71bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard        try {
7293dfe7a1df07a64701369b480578410efb740a27nicolasroard            if (source.mImageBorder != null) {
7393dfe7a1df07a64701369b480578410efb740a27nicolasroard                mImageBorder = source.mImageBorder.clone();
7493dfe7a1df07a64701369b480578410efb740a27nicolasroard            }
75bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard            for (int i = 0; i < source.mFilters.size(); i++) {
76e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford                ImageFilter filter = source.mFilters.elementAt(i).clone();
77e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford                filter.setImagePreset(this);
78e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford                add(filter);
79bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard            }
80bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard        } catch (java.lang.CloneNotSupportedException e) {
81bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard            Log.v(LOGTAG, "Exception trying to clone: " + e);
820d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
830d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mName = source.name();
840d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mHistoryName = source.name();
850d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mIsFxPreset = source.isFx();
86e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford        mImageLoader = source.getImageLoader();
870d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
888537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk        mGeoData.set(source.mGeoData);
890d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
900d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
9131529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard    public void setDoApplyGeometry(boolean value) {
9231529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard        mDoApplyGeometry = value;
9331529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard    }
9431529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard
9531529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard    public void setDoApplyFilters(boolean value) {
9631529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard        mDoApplyFilters = value;
9731529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard    }
9831529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard
9955550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard    public boolean hasModifications() {
10055550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard        if (mImageBorder != null && !mImageBorder.isNil()) {
10155550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard            return true;
10255550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard        }
10355550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard        if (mGeoData.hasModifications()) {
10455550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard            return true;
10555550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard        }
10655550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard        for (int i = 0; i < mFilters.size(); i++) {
10755550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard            ImageFilter filter = mFilters.elementAt(i);
10855550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard            if (!filter.isNil()) {
10955550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard                return true;
11055550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard            }
11155550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard        }
11255550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard        return false;
11355550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard    }
11455550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard
115014a111f10a7523415ca210bc6fe1e4f00183d31John Reck    public boolean isPanoramaSafe() {
116014a111f10a7523415ca210bc6fe1e4f00183d31John Reck        if (mImageBorder != null && !mImageBorder.isNil()) {
117014a111f10a7523415ca210bc6fe1e4f00183d31John Reck            return false;
118014a111f10a7523415ca210bc6fe1e4f00183d31John Reck        }
119014a111f10a7523415ca210bc6fe1e4f00183d31John Reck        if (mGeoData.hasModifications()) {
120014a111f10a7523415ca210bc6fe1e4f00183d31John Reck            return false;
121014a111f10a7523415ca210bc6fe1e4f00183d31John Reck        }
122014a111f10a7523415ca210bc6fe1e4f00183d31John Reck        for (ImageFilter filter : mFilters) {
123014a111f10a7523415ca210bc6fe1e4f00183d31John Reck            if (filter.getFilterType() == ImageFilter.TYPE_VIGNETTE
124014a111f10a7523415ca210bc6fe1e4f00183d31John Reck                    && !filter.isNil()) {
125014a111f10a7523415ca210bc6fe1e4f00183d31John Reck                return false;
126014a111f10a7523415ca210bc6fe1e4f00183d31John Reck            }
12717540e58b8454e820a6273365cee94742d9b9900John Hoford            if (filter.getFilterType() == ImageFilter.TYPE_TINYPLANET
12817540e58b8454e820a6273365cee94742d9b9900John Hoford                    && !filter.isNil()) {
12917540e58b8454e820a6273365cee94742d9b9900John Hoford                return false;
13017540e58b8454e820a6273365cee94742d9b9900John Hoford            }
131014a111f10a7523415ca210bc6fe1e4f00183d31John Reck        }
132014a111f10a7523415ca210bc6fe1e4f00183d31John Reck        return true;
133014a111f10a7523415ca210bc6fe1e4f00183d31John Reck    }
134014a111f10a7523415ca210bc6fe1e4f00183d31John Reck
13593dfe7a1df07a64701369b480578410efb740a27nicolasroard    public void setGeometry(GeometryMetadata m) {
13693dfe7a1df07a64701369b480578410efb740a27nicolasroard        mGeoData.set(m);
13793dfe7a1df07a64701369b480578410efb740a27nicolasroard    }
13893dfe7a1df07a64701369b480578410efb740a27nicolasroard
139a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford    private void setBorder(ImageFilter filter) {
14093dfe7a1df07a64701369b480578410efb740a27nicolasroard        mImageBorder = filter;
14193dfe7a1df07a64701369b480578410efb740a27nicolasroard    }
14293dfe7a1df07a64701369b480578410efb740a27nicolasroard
1430d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public boolean isFx() {
1440d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return mIsFxPreset;
1450d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
1460d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
1470d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public void setIsFx(boolean value) {
1480d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mIsFxPreset = value;
1490d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
1500d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
1510d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public void setName(String name) {
1520d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mName = name;
1530d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mHistoryName = name;
1540d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
1550d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
156e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard    public void setHistoryName(String name) {
1570d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mHistoryName = name;
1580d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
1590d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
160e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford    public ImageLoader getImageLoader() {
161e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford        return mImageLoader;
162e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford    }
163e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford
164e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford    public void setImageLoader(ImageLoader mImageLoader) {
165e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford        this.mImageLoader = mImageLoader;
166e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford    }
167e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford
1680d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public boolean same(ImagePreset preset) {
1690d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        if (preset.mFilters.size() != mFilters.size()) {
1700d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            return false;
1710d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
1720d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        if (!mName.equalsIgnoreCase(preset.name())) {
1730d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            return false;
1740d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
1758537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk
176fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard        if (mDoApplyGeometry != preset.mDoApplyGeometry) {
177fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard            return false;
178fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard        }
179fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard
180fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard        if (mDoApplyGeometry && !mGeoData.equals(preset.mGeoData)) {
1810d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            return false;
1820d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
18393dfe7a1df07a64701369b480578410efb740a27nicolasroard
18478cabea71ab108b1de80a0e63cc16aec6bd64fb2nicolasroard        if (mDoApplyGeometry && mImageBorder != preset.mImageBorder) {
18593dfe7a1df07a64701369b480578410efb740a27nicolasroard            return false;
18693dfe7a1df07a64701369b480578410efb740a27nicolasroard        }
18793dfe7a1df07a64701369b480578410efb740a27nicolasroard
18893dfe7a1df07a64701369b480578410efb740a27nicolasroard        if (mImageBorder != null && !mImageBorder.same(preset.mImageBorder)) {
18993dfe7a1df07a64701369b480578410efb740a27nicolasroard            return false;
19093dfe7a1df07a64701369b480578410efb740a27nicolasroard        }
19193dfe7a1df07a64701369b480578410efb740a27nicolasroard
192fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard        if (mDoApplyFilters != preset.mDoApplyFilters) {
193fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard            if (mFilters.size() > 0 || preset.mFilters.size() > 0) {
1940d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard                return false;
1950d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            }
1960d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
197fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard
198fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard        if (mDoApplyFilters && preset.mDoApplyFilters) {
199fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard            for (int i = 0; i < preset.mFilters.size(); i++) {
200fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard                ImageFilter a = preset.mFilters.elementAt(i);
201fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard                ImageFilter b = mFilters.elementAt(i);
202fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard                if (!a.same(b)) {
203fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard                    return false;
204fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard                }
205fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard            }
206fb90fd60f155f6fef0334a0739be55a2717c17f5nicolasroard        }
2070d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return true;
2080d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
2090d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
2100d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public String name() {
2110d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return mName;
2120d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
2130d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
2140d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public String historyName() {
2150d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return mHistoryName;
2160d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
2170d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
218bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard    public void add(ImageFilter filter) {
219fafb2edbb9928039b887f59685d82593bd79e06aJohn Hoford
22055550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard        if (filter.getFilterType() == ImageFilter.TYPE_BORDER) {
2210a32b7afc5286a5c7aa334b9338591d61a49731fRuben Brunk            setHistoryName(filter.getName());
222a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford            setBorder(filter);
22355550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard        } else if (filter.getFilterType() == ImageFilter.TYPE_FX) {
224a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford            boolean found = false;
225a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford            for (int i = 0; i < mFilters.size(); i++) {
226fafb2edbb9928039b887f59685d82593bd79e06aJohn Hoford                byte type = mFilters.get(i).getFilterType();
227a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford                if (found) {
22855550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard                    if (type != ImageFilter.TYPE_VIGNETTE) {
229fafb2edbb9928039b887f59685d82593bd79e06aJohn Hoford                        mFilters.remove(i);
230fafb2edbb9928039b887f59685d82593bd79e06aJohn Hoford                        continue;
231a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford                    }
232fafb2edbb9928039b887f59685d82593bd79e06aJohn Hoford                }
23355550694a3f40fbf5dfc95c35a8e253aedab931enicolasroard                if (type == ImageFilter.TYPE_FX) {
234fafb2edbb9928039b887f59685d82593bd79e06aJohn Hoford                    mFilters.remove(i);
235fafb2edbb9928039b887f59685d82593bd79e06aJohn Hoford                    mFilters.add(i, filter);
236a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford                    setHistoryName(filter.getName());
237a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford                    found = true;
238a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford                }
239a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford            }
240fafb2edbb9928039b887f59685d82593bd79e06aJohn Hoford            if (!found) {
241fafb2edbb9928039b887f59685d82593bd79e06aJohn Hoford                mFilters.add(filter);
242fafb2edbb9928039b887f59685d82593bd79e06aJohn Hoford                setHistoryName(filter.getName());
243fafb2edbb9928039b887f59685d82593bd79e06aJohn Hoford            }
244a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford        } else {
245a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford            mFilters.add(filter);
246a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford            setHistoryName(filter.getName());
247a19830b4fd9050b48386cd904d99cfd2566cc515John Hoford        }
248e9c55b28a4a155c2e1c1f5aec615a0c56e38ade4John Hoford        filter.setImagePreset(this);
2490d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
2500d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
2510d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public void remove(String filterName) {
2520d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        ImageFilter filter = getFilter(filterName);
2530d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        if (filter != null) {
2540d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            mFilters.remove(filter);
2550d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
2560d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
2570d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
2580d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public int getCount() {
2590d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return mFilters.size();
2600d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
2610d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
2620d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public ImageFilter getFilter(String name) {
2630d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        for (int i = 0; i < mFilters.size(); i++) {
2640d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            ImageFilter filter = mFilters.elementAt(i);
265bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard            if (filter.getName().equalsIgnoreCase(name)) {
2660d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard                return filter;
2670d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            }
2680d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
2690d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return null;
2700d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
2710d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
2720d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public void setup() {
2730d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        // do nothing here
2740d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
2750d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
2760d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public void setEndpoint(ImageShow image) {
2770d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mEndPoint = image;
2780d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
2790d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
2800d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public Bitmap apply(Bitmap original) {
2810d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        // First we apply any transform -- 90 rotate, flip, straighten, crop
28231529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard        Bitmap bitmap = original;
2830d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
28431529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard        if (mDoApplyGeometry) {
28531529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard            bitmap = mGeoData.apply(original, mScaleFactor, mIsHighQuality);
28631529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard        }
28731529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard
28831529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard        if (mDoApplyFilters) {
28931529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard            for (int i = 0; i < mFilters.size(); i++) {
29031529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard                ImageFilter filter = mFilters.elementAt(i);
29131529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard                bitmap = filter.apply(bitmap, mScaleFactor, mIsHighQuality);
29231529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard            }
2930d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
29493dfe7a1df07a64701369b480578410efb740a27nicolasroard
29578cabea71ab108b1de80a0e63cc16aec6bd64fb2nicolasroard        if (mImageBorder != null && mDoApplyGeometry) {
29608458dc637d92ee5f12e34d49c34cc10f4e19c7dnicolasroard            bitmap = mImageBorder.apply(bitmap, mScaleFactor, mIsHighQuality);
29708458dc637d92ee5f12e34d49c34cc10f4e19c7dnicolasroard        }
29808458dc637d92ee5f12e34d49c34cc10f4e19c7dnicolasroard
2990d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        if (mEndPoint != null) {
3000d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            mEndPoint.updateFilteredImage(bitmap);
3010d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
30231529940021b9a18611b1a3fb4a0317ab8c89618nicolasroard
3030d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return bitmap;
3040d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
3050d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
306bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard    public void fillImageStateAdapter(ImageStateAdapter imageStateAdapter) {
307bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard        if (imageStateAdapter == null) {
308bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard            return;
309bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard        }
310bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard        imageStateAdapter.clear();
311bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard        imageStateAdapter.addAll(mFilters);
312bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard        imageStateAdapter.notifyDataSetChanged();
313bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard    }
314bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard
31581eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    public float getScaleFactor() {
31681eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard        return mScaleFactor;
31781eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    }
31881eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard
31981eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    public boolean isHighQuality() {
32081eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard        return mIsHighQuality;
32181eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    }
32281eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard
32381eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    public void setIsHighQuality(boolean value) {
32481eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard        mIsHighQuality = value;
32581eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    }
32681eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard
32781eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    public void setScaleFactor(float value) {
32881eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard        mScaleFactor = value;
32981eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    }
330bf93da72576b28f4e9dfb27f8f3fef702c8ae82dnicolasroard}
331