BitmapPool.java revision cafd30f96355ad446943d60cd2595d08423944e2
1// Copyright 2012 Google Inc. All Rights Reserved.
2
3package com.android.gallery3d.data;
4
5import android.graphics.Bitmap;
6import android.graphics.BitmapFactory;
7import android.graphics.BitmapFactory.Options;
8
9import com.android.gallery3d.ui.Log;
10import com.android.gallery3d.util.ThreadPool.JobContext;
11
12import java.io.FileDescriptor;
13import java.util.ArrayList;
14
15public class BitmapPool {
16    private static final String TAG = "BitmapPool";
17
18    private static final int POOL_SIZE = 16;
19    private final ArrayList<Bitmap> mPool = new ArrayList<Bitmap>(POOL_SIZE);
20
21    private final int mWidth;
22    private final int mHeight;
23
24    public BitmapPool(int width, int height) {
25        mWidth = width;
26        mHeight = height;
27    }
28
29    public synchronized Bitmap getBitmap() {
30        int size = mPool.size();
31        return size > 0 ? mPool.remove(size - 1) : null;
32    }
33
34    public void recycle(Bitmap bitmap) {
35        if (bitmap == null) return;
36        if ((bitmap.getWidth() != mWidth) || (bitmap.getHeight() != mHeight)) {
37            bitmap.recycle();
38            return;
39        }
40        synchronized (this) {
41            if (mPool.size() < POOL_SIZE) mPool.add(bitmap);
42        }
43    }
44
45    public synchronized void clear() {
46        mPool.clear();
47    }
48
49    public Bitmap decode(JobContext jc,
50            byte[] data, int offset, int length, BitmapFactory.Options options) {
51        if (options == null) options = new BitmapFactory.Options();
52        if (options.inSampleSize < 1) options.inSampleSize = 1;
53        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
54        options.inBitmap = (options.inSampleSize == 1) ? getBitmap() : null;
55        try {
56            Bitmap bitmap = DecodeUtils.decode(jc, data, offset, length, options);
57            if (options.inBitmap != null && options.inBitmap != bitmap) {
58                recycle(options.inBitmap);
59                options.inBitmap = null;
60            }
61            return bitmap;
62        } catch (IllegalArgumentException e) {
63            if (options.inBitmap == null) throw e;
64
65            Log.w(TAG, "decode fail with a given bitmap, try decode to a new bitmap");
66            recycle(options.inBitmap);
67            options.inBitmap = null;
68            return DecodeUtils.decode(jc, data, offset, length, options);
69        }
70    }
71
72    // This is the same as the method above except the source data comes
73    // from a file descriptor instead of a byte array.
74    public Bitmap decode(JobContext jc,
75            FileDescriptor fileDescriptor, Options options) {
76        if (options == null) options = new BitmapFactory.Options();
77        if (options.inSampleSize < 1) options.inSampleSize = 1;
78        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
79        options.inBitmap = (options.inSampleSize == 1) ? getBitmap() : null;
80        try {
81            Bitmap bitmap = DecodeUtils.decode(jc, fileDescriptor, options);
82            if (options.inBitmap != null&& options.inBitmap != bitmap) {
83                recycle(options.inBitmap);
84                options.inBitmap = null;
85            }
86            return bitmap;
87        } catch (IllegalArgumentException e) {
88            if (options.inBitmap == null) throw e;
89
90            Log.w(TAG, "decode fail with a given bitmap, try decode to a new bitmap");
91            recycle(options.inBitmap);
92            options.inBitmap = null;
93            return DecodeUtils.decode(jc, fileDescriptor, options);
94        }
95    }
96}
97