/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.camera; import android.graphics.Bitmap; class BitmapCache implements ImageViewTouchBase.Recycler { public static class Entry { int mPos; Bitmap mBitmap; public Entry() { clear(); } public void clear() { mPos = -1; mBitmap = null; } } private final Entry[] mCache; public BitmapCache(int size) { mCache = new Entry[size]; for (int i = 0; i < mCache.length; i++) { mCache[i] = new Entry(); } } // Given the position, find the associated entry. Returns null if there is // no such entry. private Entry findEntry(int pos) { for (Entry e : mCache) { if (pos == e.mPos) { return e; } } return null; } // Returns the thumb bitmap if we have it, otherwise return null. public synchronized Bitmap getBitmap(int pos) { Entry e = findEntry(pos); if (e != null) { return e.mBitmap; } return null; } public synchronized void put(int pos, Bitmap bitmap) { // First see if we already have this entry. if (findEntry(pos) != null) { return; } // Find the best entry we should replace. // See if there is any empty entry. // Otherwise assuming sequential access, kick out the entry with the // greatest distance. Entry best = null; int maxDist = -1; for (Entry e : mCache) { if (e.mPos == -1) { best = e; break; } else { int dist = Math.abs(pos - e.mPos); if (dist > maxDist) { maxDist = dist; best = e; } } } // Recycle the image being kicked out. // This only works because our current usage is sequential, so we // do not happen to recycle the image being displayed. if (best.mBitmap != null) { best.mBitmap.recycle(); } best.mPos = pos; best.mBitmap = bitmap; } // Recycle all bitmaps in the cache and clear the cache. public synchronized void clear() { for (Entry e : mCache) { if (e.mBitmap != null) { e.mBitmap.recycle(); } e.clear(); } } // Returns whether the bitmap is in the cache. public synchronized boolean hasBitmap(int pos) { Entry e = findEntry(pos); return (e != null); } // Recycle the bitmap if it's not in the cache. // The input must be non-null. public synchronized void recycle(Bitmap b) { for (Entry e : mCache) { if (e.mPos != -1) { if (e.mBitmap == b) { return; } } } b.recycle(); } }