1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/* 2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project 3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License. 6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at 7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software 11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and 14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License. 15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.data; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.common.BlobCache; 20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.common.Utils; 21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.CacheManager; 22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.GalleryUtils; 23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.Context; 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.io.IOException; 27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.ByteBuffer; 28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class ImageCacheService { 30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @SuppressWarnings("unused") 31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "ImageCacheService"; 32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String IMAGE_CACHE_FILE = "imgcache"; 34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int IMAGE_CACHE_MAX_ENTRIES = 5000; 35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int IMAGE_CACHE_MAX_BYTES = 200 * 1024 * 1024; 36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int IMAGE_CACHE_VERSION = 3; 37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private BlobCache mCache; 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public ImageCacheService(Context context) { 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCache = CacheManager.getCache(context, IMAGE_CACHE_FILE, 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin IMAGE_CACHE_MAX_ENTRIES, IMAGE_CACHE_MAX_BYTES, 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin IMAGE_CACHE_VERSION); 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static class ImageData { 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public ImageData(byte[] data, int offset) { 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mData = data; 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mOffset = offset; 50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public byte[] mData; 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int mOffset; 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public ImageData getImageData(Path path, int type) { 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byte[] key = makeKey(path, type); 57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin long cacheKey = Utils.crc64Long(key); 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byte[] value = null; 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mCache) { 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin value = mCache.lookup(cacheKey); 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (value == null) return null; 64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (isSameKey(key, value)) { 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int offset = key.length; 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return new ImageData(value, offset); 67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } catch (IOException ex) { 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // ignore. 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return null; 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void putImageData(Path path, int type, byte[] value) { 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin byte[] key = makeKey(path, type); 76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin long cacheKey = Utils.crc64Long(key); 77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ByteBuffer buffer = ByteBuffer.allocate(key.length + value.length); 78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin buffer.put(key); 79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin buffer.put(value); 80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mCache) { 81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCache.insert(cacheKey, buffer.array()); 83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } catch (IOException ex) { 84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // ignore. 85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static byte[] makeKey(Path path, int type) { 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return GalleryUtils.getBytes(path.toString() + "+" + type); 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static boolean isSameKey(byte[] key, byte[] buffer) { 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int n = key.length; 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (buffer.length < n) { 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return false; 97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < n; ++i) { 99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (key[i] != buffer[i]) { 100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return false; 101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return true; 104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 106