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.cache;
180d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
1981eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroardimport android.graphics.Bitmap;
200d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
210d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport com.android.gallery3d.filtershow.presets.ImagePreset;
220d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
2381eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroardimport java.nio.ByteBuffer;
240d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
250d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardpublic class BitmapCache {
260d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
270d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    private static final String LOGTAG = "BitmapCache";
280d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    static int mNbItems = 20;
2981eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    private final Bitmap[] mBitmaps = new Bitmap[mNbItems];
3081eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    private final Object[] mKeys = new Object[mNbItems];
3181eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    private final long[] mIndices = new long[mNbItems];
3281eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    private final boolean[] mBusyStatus = new boolean[mNbItems];
330d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
340d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    private Bitmap mOriginalBitmap = null;
350d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    private ByteBuffer mBuffer = null;
3681eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    private final Bitmap.Config mConfig = Bitmap.Config.ARGB_8888;
370d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    private long mIndex = 0;
380d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
390d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public void setOriginalBitmap(Bitmap original) {
400d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        if (original == null) {
410d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            return;
420d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
430d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mOriginalBitmap = original.copy(mConfig, true);
440d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        int size = 4 * original.getWidth() * original.getHeight();
450d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mBuffer = ByteBuffer.allocate(size);
460d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mOriginalBitmap.copyPixelsToBuffer(mBuffer);
470d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mBuffer.rewind();
480d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mOriginalBitmap.copyPixelsFromBuffer(mBuffer);
490d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        for (int i = 0; i < mNbItems; i++) {
500d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            mBitmaps[i] = mOriginalBitmap.copy(mConfig, true);
510d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
520d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
530d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
540d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    private int getOldestPosition() {
550d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        long minIndex = mIndices[0];
560d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        int current = 0;
570d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        for (int i = 1; i < mNbItems; i++) {
580d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            if (!mBusyStatus[i] && minIndex > mIndices[i]) {
590d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard                minIndex = mIndices[i];
600d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard                current = i;
610d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            }
620d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
630d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return current;
640d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
650d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
660d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public Bitmap put(ImagePreset preset) {
670d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        int pos = getOldestPosition();
680d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return put(preset, pos);
690d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
700d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
710d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public Bitmap put(ImagePreset preset, int pos) {
720d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mBitmaps[pos] = mOriginalBitmap.copy(mConfig, true);
730d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        Bitmap bitmap = mBitmaps[pos];
7481eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard        bitmap = preset.apply(bitmap);
750d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mKeys[pos] = preset;
760d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mIndices[pos] = mIndex++;
770d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return bitmap;
780d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
790d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
800d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public int reservePosition(ImagePreset preset) {
810d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        for (int i = 1; i < mNbItems; i++) {
820d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            if (mKeys[i] == preset && mBusyStatus[i]) {
830d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard                return -1;
840d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            }
850d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
860d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        int pos = getOldestPosition();
870d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mBusyStatus[pos] = true;
880d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mKeys[pos] = preset;
890d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return pos;
900d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
910d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
920d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public void processPosition(int pos) {
930d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        ImagePreset preset = (ImagePreset) mKeys[pos];
940d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mBitmaps[pos] = mOriginalBitmap.copy(mConfig, true);
950d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        Bitmap bitmap = mBitmaps[pos];
9681eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard        bitmap = preset.apply(bitmap);
970d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mIndices[pos] = mIndex++;
980d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
990d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
1000d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public void unlockPosition(int pos) {
1010d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        mBusyStatus[pos] = false;
1020d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
1030d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
1040d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public Bitmap get(ImagePreset preset) {
1050d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        int foundPosition = -1;
1060d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        int currentIndice = 0;
1070d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        for (int i = 0; i < mNbItems; i++) {
1080d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            if (mKeys[i] == preset && mBitmaps[i] != null) {
1090d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard                if (mIndices[i] > currentIndice) {
1100d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard                    foundPosition = i;
1110d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard                }
1120d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            }
1130d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
1140d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        if (foundPosition != -1) {
1150d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            mIndices[foundPosition] = mIndex++;
1160d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            return mBitmaps[foundPosition];
1170d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
1180d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        return null;
1190d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
1200d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard
1210d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    public void reset(ImagePreset preset) {
1220d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        for (int i = 0; i < mNbItems; i++) {
1230d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            if (mKeys[i] == preset && !mBusyStatus[i]) {
1240d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard                mBitmaps[i] = null;
1250d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard            }
1260d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard        }
1270d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard    }
1280d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard}
129