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