OSDN Git Service

Import translations. DO NOT MERGE
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / data / BitmapPool.java
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.gallery3d.data;
18
19 import android.graphics.Bitmap;
20 import android.graphics.BitmapFactory;
21 import android.graphics.BitmapFactory.Options;
22
23 import com.android.gallery3d.common.Utils;
24 import com.android.gallery3d.ui.Log;
25 import com.android.gallery3d.util.ThreadPool.JobContext;
26
27 import java.io.FileDescriptor;
28 import java.util.ArrayList;
29
30 public class BitmapPool {
31     private static final String TAG = "BitmapPool";
32
33     private final ArrayList<Bitmap> mPool;
34     private final int mPoolLimit;
35
36     // mOneSize is true if the pool can only cache Bitmap with one size.
37     private final boolean mOneSize;
38     private final int mWidth, mHeight;  // only used if mOneSize is true
39
40     // Construct a BitmapPool which caches bitmap with the specified size.
41     public BitmapPool(int width, int height, int poolLimit) {
42         mWidth = width;
43         mHeight = height;
44         mPoolLimit = poolLimit;
45         mPool = new ArrayList<Bitmap>(poolLimit);
46         mOneSize = true;
47     }
48
49     // Construct a BitmapPool which caches bitmap with any size;
50     public BitmapPool(int poolLimit) {
51         mWidth = -1;
52         mHeight = -1;
53         mPoolLimit = poolLimit;
54         mPool = new ArrayList<Bitmap>(poolLimit);
55         mOneSize = false;
56     }
57
58     // Get a Bitmap from the pool.
59     public synchronized Bitmap getBitmap() {
60         Utils.assertTrue(mOneSize);
61         int size = mPool.size();
62         return size > 0 ? mPool.remove(size - 1) : null;
63     }
64
65     // Get a Bitmap from the pool with the specified size.
66     public synchronized Bitmap getBitmap(int width, int height) {
67         Utils.assertTrue(!mOneSize);
68         for (int i = mPool.size() - 1; i >= 0; i--) {
69             Bitmap b = mPool.get(i);
70             if (b.getWidth() == width && b.getHeight() == height) {
71                 return mPool.remove(i);
72             }
73         }
74         return null;
75     }
76
77     // Put a Bitmap into the pool, if the Bitmap has a proper size. Otherwise
78     // the Bitmap will be recycled. If the pool is full, an old Bitmap will be
79     // recycled.
80     public void recycle(Bitmap bitmap) {
81         if (bitmap == null) return;
82         if (mOneSize && ((bitmap.getWidth() != mWidth) ||
83                 (bitmap.getHeight() != mHeight))) {
84             bitmap.recycle();
85             return;
86         }
87         synchronized (this) {
88             if (mPool.size() >= mPoolLimit) mPool.remove(0);
89             mPool.add(bitmap);
90         }
91     }
92
93     public synchronized void clear() {
94         mPool.clear();
95     }
96
97     private Bitmap findCachedBitmap(JobContext jc,
98             byte[] data, int offset, int length, Options options) {
99         if (mOneSize) return getBitmap();
100         DecodeUtils.decodeBounds(jc, data, offset, length, options);
101         return getBitmap(options.outWidth, options.outHeight);
102     }
103
104     private Bitmap findCachedBitmap(JobContext jc,
105             FileDescriptor fileDescriptor, Options options) {
106         if (mOneSize) return getBitmap();
107         DecodeUtils.decodeBounds(jc, fileDescriptor, options);
108         return getBitmap(options.outWidth, options.outHeight);
109     }
110
111     public Bitmap decode(JobContext jc,
112             byte[] data, int offset, int length, BitmapFactory.Options options) {
113         if (options == null) options = new BitmapFactory.Options();
114         if (options.inSampleSize < 1) options.inSampleSize = 1;
115         options.inPreferredConfig = Bitmap.Config.ARGB_8888;
116         options.inBitmap = (options.inSampleSize == 1)
117                 ? findCachedBitmap(jc, data, offset, length, options) : null;
118         try {
119             Bitmap bitmap = DecodeUtils.decode(jc, data, offset, length, options);
120             if (options.inBitmap != null && options.inBitmap != bitmap) {
121                 recycle(options.inBitmap);
122                 options.inBitmap = null;
123             }
124             return bitmap;
125         } catch (IllegalArgumentException e) {
126             if (options.inBitmap == null) throw e;
127
128             Log.w(TAG, "decode fail with a given bitmap, try decode to a new bitmap");
129             recycle(options.inBitmap);
130             options.inBitmap = null;
131             return DecodeUtils.decode(jc, data, offset, length, options);
132         }
133     }
134
135     // This is the same as the method above except the source data comes
136     // from a file descriptor instead of a byte array.
137     public Bitmap decode(JobContext jc,
138             FileDescriptor fileDescriptor, Options options) {
139         if (options == null) options = new BitmapFactory.Options();
140         if (options.inSampleSize < 1) options.inSampleSize = 1;
141         options.inPreferredConfig = Bitmap.Config.ARGB_8888;
142         options.inBitmap = (options.inSampleSize == 1)
143                 ? findCachedBitmap(jc, fileDescriptor, options) : null;
144         try {
145             Bitmap bitmap = DecodeUtils.decode(jc, fileDescriptor, options);
146             if (options.inBitmap != null&& options.inBitmap != bitmap) {
147                 recycle(options.inBitmap);
148                 options.inBitmap = null;
149             }
150             return bitmap;
151         } catch (IllegalArgumentException e) {
152             if (options.inBitmap == null) throw e;
153
154             Log.w(TAG, "decode fail with a given bitmap, try decode to a new bitmap");
155             recycle(options.inBitmap);
156             options.inBitmap = null;
157             return DecodeUtils.decode(jc, fileDescriptor, options);
158         }
159     }
160 }