1 /*
2  * Copyright (C) 2013 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.bitmap;
18 
19 import android.graphics.Bitmap;
20 
21 /**
22  * A simple bitmap wrapper. Currently supports reference counting and logical width/height
23  * (which may differ from a bitmap's reported width/height due to bitmap reuse).
24  */
25 public class ReusableBitmap implements Poolable {
26 
27     public final Bitmap bmp;
28     private int mWidth;
29     private int mHeight;
30     private int mOrientation;
31 
32     private int mRefCount = 0;
33     private final boolean mReusable;
34 
ReusableBitmap(final Bitmap bitmap)35     public ReusableBitmap(final Bitmap bitmap) {
36         this(bitmap, true /* reusable */);
37     }
38 
ReusableBitmap(final Bitmap bitmap, final boolean reusable)39     public ReusableBitmap(final Bitmap bitmap, final boolean reusable) {
40         bmp = bitmap;
41         mReusable = reusable;
42     }
43 
44     @Override
isEligibleForPooling()45     public boolean isEligibleForPooling() {
46         return mReusable;
47     }
48 
setLogicalWidth(int w)49     public void setLogicalWidth(int w) {
50         mWidth = w;
51     }
52 
setLogicalHeight(int h)53     public void setLogicalHeight(int h) {
54         mHeight = h;
55     }
56 
getLogicalWidth()57     public int getLogicalWidth() {
58         return mWidth;
59     }
60 
getLogicalHeight()61     public int getLogicalHeight() {
62         return mHeight;
63     }
64 
getOrientation()65     public int getOrientation() {
66         return mOrientation;
67     }
68 
setOrientation(final int orientation)69     public void setOrientation(final int orientation) {
70         mOrientation = orientation;
71     }
72 
getByteCount()73     public int getByteCount() {
74         return bmp.getByteCount();
75     }
76 
77     @Override
acquireReference()78     public void acquireReference() {
79         mRefCount++;
80     }
81 
82     @Override
releaseReference()83     public void releaseReference() {
84         if (mRefCount == 0) {
85             throw new IllegalStateException();
86         }
87         mRefCount--;
88     }
89 
90     @Override
getRefCount()91     public int getRefCount() {
92         return mRefCount;
93     }
94 
95     @Override
toString()96     public String toString() {
97         final StringBuilder sb = new StringBuilder("[");
98         sb.append(super.toString());
99         sb.append(" refCount=");
100         sb.append(mRefCount);
101         sb.append(" mReusable=");
102         sb.append(mReusable);
103         sb.append(" bmp=");
104         sb.append(bmp);
105         sb.append(" logicalW/H=");
106         sb.append(mWidth);
107         sb.append("/");
108         sb.append(mHeight);
109         if (bmp != null) {
110             sb.append(" sz=");
111             sb.append(bmp.getByteCount() >> 10);
112             sb.append("KB");
113         }
114         sb.append("]");
115         return sb.toString();
116     }
117 
118     /**
119      * Singleton class to represent a null Bitmap. We don't want to just use a regular
120      * ReusableBitmap with a null bmp field because that will render that ReusableBitmap useless
121      * and unable to be used by another decode process.
122      */
123     public final static class NullReusableBitmap extends ReusableBitmap {
124         private static NullReusableBitmap sInstance;
125 
126         /**
127          * Get a singleton.
128          */
getInstance()129         public static NullReusableBitmap getInstance() {
130             if (sInstance == null) {
131                 sInstance = new NullReusableBitmap();
132             }
133             return sInstance;
134         }
135 
NullReusableBitmap()136         private NullReusableBitmap() {
137             super(null /* bmp */, false /* reusable */);
138         }
139 
140         @Override
getByteCount()141         public int getByteCount() {
142             return 0;
143         }
144 
145         @Override
releaseReference()146         public void releaseReference() { }
147 
148         @Override
acquireReference()149         public void acquireReference() { }
150     }
151 }
152