CacheProcessing.java revision ec1e009a7faea0478e361bc2d48d856ab48a0209
18e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard/*
28e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard * Copyright (C) 2013 The Android Open Source Project
38e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard *
48e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard * Licensed under the Apache License, Version 2.0 (the "License");
58e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard * you may not use this file except in compliance with the License.
68e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard * You may obtain a copy of the License at
78e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard *
88e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard *      http://www.apache.org/licenses/LICENSE-2.0
98e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard *
108e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard * Unless required by applicable law or agreed to in writing, software
118e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard * distributed under the License is distributed on an "AS IS" BASIS,
128e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard * See the License for the specific language governing permissions and
148e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard * limitations under the License.
158e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard */
168e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
178e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroardpackage com.android.gallery3d.filtershow.pipeline;
188e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
198e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroardimport android.graphics.Bitmap;
208e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroardimport android.util.Log;
21ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard
22ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroardimport com.android.gallery3d.filtershow.cache.BitmapCache;
238e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroardimport com.android.gallery3d.filtershow.filters.FilterRepresentation;
24430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroardimport com.android.gallery3d.filtershow.imageshow.GeometryMathUtils;
258e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
26430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroardimport java.util.ArrayList;
278e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroardimport java.util.Vector;
288e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
298e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroardpublic class CacheProcessing {
308e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard    private static final String LOGTAG = "CacheProcessing";
318e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard    private static final boolean DEBUG = false;
328e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard    private Vector<CacheStep> mSteps = new Vector<CacheStep>();
338e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
348e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard    static class CacheStep {
35430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        ArrayList<FilterRepresentation> representations;
368e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        Bitmap cache;
37430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard
38430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        public CacheStep() {
39430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            representations = new ArrayList<FilterRepresentation>();
40430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        }
41430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard
42430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        public void add(FilterRepresentation representation) {
43430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            representations.add(representation);
44430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        }
45430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard
46430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        public boolean canMergeWith(FilterRepresentation representation) {
47430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            for (FilterRepresentation rep : representations) {
48430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                if (!rep.canMergeWith(representation)) {
49430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    return false;
50430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                }
51430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            }
52430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            return true;
53430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        }
54430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard
55430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        public boolean equals(CacheStep step) {
56430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            if (representations.size() != step.representations.size()) {
57430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                return false;
58430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            }
59430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            for (int i = 0; i < representations.size(); i++) {
60430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                FilterRepresentation r1 = representations.get(i);
61430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                FilterRepresentation r2 = step.representations.get(i);
62430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                if (!r1.equals(r2)) {
63430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    return false;
64430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                }
65430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            }
66430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            return true;
67430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        }
68430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard
69430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        public static Vector<CacheStep> buildSteps(Vector<FilterRepresentation> filters) {
70430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            Vector<CacheStep> steps = new Vector<CacheStep>();
71430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            CacheStep step = new CacheStep();
72430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            for (int i = 0; i < filters.size(); i++) {
73430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                FilterRepresentation representation = filters.elementAt(i);
74430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                if (step.canMergeWith(representation)) {
75430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    step.add(representation.copy());
76430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                } else {
77430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    steps.add(step);
78430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    step = new CacheStep();
79430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    step.add(representation.copy());
80430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                }
81430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            }
82430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            steps.add(step);
83430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            return steps;
84430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        }
85430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard
86430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        public String getName() {
87430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            if (representations.size() > 0) {
88430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                return representations.get(0).getName();
89430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            }
90430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            return "EMPTY";
91430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        }
92430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard
93430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        public Bitmap apply(FilterEnvironment environment, Bitmap cacheBitmap) {
94430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            boolean onlyGeometry = true;
95ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard            Bitmap source = cacheBitmap;
96430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            for (FilterRepresentation representation : representations) {
97430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                if (representation.getFilterType() != FilterRepresentation.TYPE_GEOMETRY) {
98430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    onlyGeometry = false;
99430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    break;
100430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                }
101430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            }
102430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            if (onlyGeometry) {
103430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                ArrayList<FilterRepresentation> geometry = new ArrayList<FilterRepresentation>();
104430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                for (FilterRepresentation representation : representations) {
105430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    geometry.add(representation);
106430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                }
107430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                cacheBitmap = GeometryMathUtils.applyGeometryRepresentations(geometry, cacheBitmap);
108430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            } else {
109430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                for (FilterRepresentation representation : representations) {
110430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    cacheBitmap = environment.applyRepresentation(representation, cacheBitmap);
111430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                }
112430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            }
113ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard            if (cacheBitmap != source) {
114ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard                environment.cache(source);
115ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard            }
116430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            return cacheBitmap;
117430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        }
1188e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard    }
1198e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
1208e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard    public Bitmap process(Bitmap originalBitmap,
1218e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard                          Vector<FilterRepresentation> filters,
1228e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard                          FilterEnvironment environment) {
1238f442fae60e0154867d2a6927eb9a35bcb7014e6nicolasroard
1248f442fae60e0154867d2a6927eb9a35bcb7014e6nicolasroard        if (filters.size() == 0) {
125ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard            return environment.getBitmapCopy(originalBitmap, BitmapCache.PREVIEW_CACHE_NO_FILTERS);
1268f442fae60e0154867d2a6927eb9a35bcb7014e6nicolasroard        }
1278e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
128c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard        environment.getBimapCache().setCacheProcessing(this);
129c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard
130430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        if (DEBUG) {
131430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            displayFilters(filters);
132430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        }
133430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        Vector<CacheStep> steps = CacheStep.buildSteps(filters);
1348e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        // New set of filters, let's clear the cache and rebuild it.
135430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        if (steps.size() != mSteps.size()) {
136430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            mSteps = steps;
1378e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
1388e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
1398e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        if (DEBUG) {
140430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            displaySteps(mSteps);
1418e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
1428e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
1438e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        // First, let's find how similar we are in our cache
1448e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        // compared to the current list of filters
1458f442fae60e0154867d2a6927eb9a35bcb7014e6nicolasroard        int similarUpToIndex = -1;
146430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        boolean similar = true;
147430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        for (int i = 0; i < steps.size(); i++) {
148430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            CacheStep newStep = steps.elementAt(i);
149430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            CacheStep cacheStep = mSteps.elementAt(i);
150430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            if (similar) {
151430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                similar = newStep.equals(cacheStep);
152430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            }
1538e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            if (similar) {
1548e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard                similarUpToIndex = i;
1558e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            } else {
156430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                mSteps.remove(i);
157430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                mSteps.insertElementAt(newStep, i);
158c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard                environment.cache(cacheStep.cache);
1598e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            }
1608e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
1618e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        if (DEBUG) {
1628e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            Log.v(LOGTAG, "similar up to index " + similarUpToIndex);
1638e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
1648e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
1658e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        // Now, let's get the earliest cached result in our pipeline
1668f442fae60e0154867d2a6927eb9a35bcb7014e6nicolasroard        Bitmap cacheBitmap = null;
1678e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        int findBaseImageIndex = similarUpToIndex;
1688f442fae60e0154867d2a6927eb9a35bcb7014e6nicolasroard        if (findBaseImageIndex > -1) {
1698f442fae60e0154867d2a6927eb9a35bcb7014e6nicolasroard            while (findBaseImageIndex > 0
1708f442fae60e0154867d2a6927eb9a35bcb7014e6nicolasroard                    && mSteps.elementAt(findBaseImageIndex).cache == null) {
1718f442fae60e0154867d2a6927eb9a35bcb7014e6nicolasroard                findBaseImageIndex--;
1728f442fae60e0154867d2a6927eb9a35bcb7014e6nicolasroard            }
1738f442fae60e0154867d2a6927eb9a35bcb7014e6nicolasroard            cacheBitmap = mSteps.elementAt(findBaseImageIndex).cache;
1748e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
1758e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
1768e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        if (DEBUG) {
177430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            Log.v(LOGTAG, "found baseImageIndex: " + findBaseImageIndex + " max is "
178430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    + mSteps.size() + " cacheBitmap: " + cacheBitmap);
1798e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
1808e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
1819f452e09889199a28a86d9bd8f8fdaa8508ca0c1nicolasroard        Bitmap originalCopy = null;
182c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard        int lastPositionCached = -1;
183430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        for (int i = findBaseImageIndex; i < mSteps.size(); i++) {
184430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            if (i == -1 || cacheBitmap == null) {
185ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard                cacheBitmap = environment.getBitmapCopy(originalBitmap,
186ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard                        BitmapCache.PREVIEW_CACHE_NO_ROOT);
1879f452e09889199a28a86d9bd8f8fdaa8508ca0c1nicolasroard                originalCopy = cacheBitmap;
1888b9cc5f374fa8bded7f84af6ce73123be2754cccnicolasroard                if (DEBUG) {
1898b9cc5f374fa8bded7f84af6ce73123be2754cccnicolasroard                    Log.v(LOGTAG, "i: " + i + " cacheBitmap: " + cacheBitmap + " w: "
1908b9cc5f374fa8bded7f84af6ce73123be2754cccnicolasroard                            + cacheBitmap.getWidth() + " h: " + cacheBitmap.getHeight()
1918b9cc5f374fa8bded7f84af6ce73123be2754cccnicolasroard                            + " got from original Bitmap: " + originalBitmap + " w: "
1928b9cc5f374fa8bded7f84af6ce73123be2754cccnicolasroard                            + originalBitmap.getWidth() + " h: " + originalBitmap.getHeight());
1938b9cc5f374fa8bded7f84af6ce73123be2754cccnicolasroard                }
194430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                if (i == -1) {
195430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                    continue;
196430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                }
197b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk            }
198430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            CacheStep step = mSteps.elementAt(i);
199430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            if (step.cache == null) {
2008b9cc5f374fa8bded7f84af6ce73123be2754cccnicolasroard                if (DEBUG) {
2018b9cc5f374fa8bded7f84af6ce73123be2754cccnicolasroard                    Log.v(LOGTAG, "i: " + i + " get new copy for cacheBitmap "
2028b9cc5f374fa8bded7f84af6ce73123be2754cccnicolasroard                            + cacheBitmap + " apply...");
2038b9cc5f374fa8bded7f84af6ce73123be2754cccnicolasroard                }
204ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard                cacheBitmap = environment.getBitmapCopy(cacheBitmap, BitmapCache.PREVIEW_CACHE);
205430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                cacheBitmap = step.apply(environment, cacheBitmap);
206430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard                step.cache = cacheBitmap;
207c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard                lastPositionCached = i;
2088e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            }
2098e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
2109f452e09889199a28a86d9bd8f8fdaa8508ca0c1nicolasroard        environment.cache(originalCopy);
2118e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
2128e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        if (DEBUG) {
2138e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            Log.v(LOGTAG, "now let's cleanup the cache...");
2148e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            displayNbBitmapsInCache();
2158e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
2168e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
2178e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        // Let's see if we can cleanup the cache for unused bitmaps
2188e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        for (int i = 0; i < similarUpToIndex; i++) {
2198e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            CacheStep currentStep = mSteps.elementAt(i);
220ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard            Bitmap bitmap = currentStep.cache;
2218e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            currentStep.cache = null;
222ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard            environment.cache(bitmap);
2238e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
2248e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
2258e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        if (DEBUG) {
2268e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            Log.v(LOGTAG, "cleanup done...");
2278e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            displayNbBitmapsInCache();
2288e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
229c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard        if (lastPositionCached != -1) {
230ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard            Bitmap bitmap = mSteps.elementAt(lastPositionCached).cache;
231c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard            mSteps.elementAt(lastPositionCached).cache = null;
232ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard            environment.cache(bitmap);
233ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard        }
234ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard        if (contains(cacheBitmap)) {
235ec1e009a7faea0478e361bc2d48d856ab48a0209nicolasroard            return environment.getBitmapCopy(cacheBitmap, BitmapCache.PREVIEW_CACHE_NO_APPLY);
236c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard        }
2378e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        return cacheBitmap;
2388e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard    }
2398e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
240c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard    public boolean contains(Bitmap bitmap) {
241c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard        for (int i = 0; i < mSteps.size(); i++) {
242c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard            if (mSteps.elementAt(i).cache == bitmap) {
243c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard                return true;
244c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard            }
245c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard        }
246c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard        return false;
247c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard    }
248c3d21101b14cdc1abf8a055e056019af57c4c7benicolasroard
2498e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard    private void displayFilters(Vector<FilterRepresentation> filters) {
250430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        Log.v(LOGTAG, "------>>> Filters received");
251430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        for (int i = 0; i < filters.size(); i++) {
252430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            FilterRepresentation filter = filters.elementAt(i);
253430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            Log.v(LOGTAG, "[" + i + "] - " + filter.getName());
254430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        }
255430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard        Log.v(LOGTAG, "<<<------");
256430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard    }
257430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard
258430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard    private void displaySteps(Vector<CacheStep> filters) {
2598e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        Log.v(LOGTAG, "------>>>");
2608e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        for (int i = 0; i < filters.size(); i++) {
261430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            CacheStep newStep = filters.elementAt(i);
2628e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            CacheStep step = mSteps.elementAt(i);
263430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            boolean similar = step.equals(newStep);
264430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard            Log.v(LOGTAG, "[" + i + "] - " + step.getName()
2658e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard                    + " similar rep ? " + (similar ? "YES" : "NO")
2668e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard                    + " -- bitmap: " + step.cache);
2678e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
2688e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        Log.v(LOGTAG, "<<<------");
2698e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard    }
2708e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
2718e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard    private void displayNbBitmapsInCache() {
2728e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        int nbBitmapsCached = 0;
2738e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        for (int i = 0; i < mSteps.size(); i++) {
2748e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            CacheStep step = mSteps.elementAt(i);
2758e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            if (step.cache != null) {
2768e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard                nbBitmapsCached++;
2778e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard            }
2788e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        }
2798e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard        Log.v(LOGTAG, "nb bitmaps in cache: " + nbBitmapsCached + " / " + mSteps.size());
2808e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard    }
2818e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard
2828e33c2b402983070eb0cc9ace16ecfa4b9728447nicolasroard}
283