• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.ui;
18 
19 import android.graphics.Bitmap;
20 import android.graphics.Bitmap.Config;
21 import android.graphics.BitmapFactory;
22 import android.graphics.BitmapRegionDecoder;
23 import android.graphics.Canvas;
24 import android.graphics.Rect;
25 
26 import com.android.gallery3d.common.Utils;
27 
28 public class TileImageViewAdapter implements TileImageView.Model {
29     private static final String TAG = "TileImageViewAdapter";
30     protected BitmapRegionDecoder mRegionDecoder;
31     protected int mImageWidth;
32     protected int mImageHeight;
33     protected Bitmap mBackupImage;
34     protected int mLevelCount;
35     protected boolean mFailedToLoad;
36 
37     private final Rect mIntersectRect = new Rect();
38     private final Rect mRegionRect = new Rect();
39 
TileImageViewAdapter()40     public TileImageViewAdapter() {
41     }
42 
TileImageViewAdapter(Bitmap backup, BitmapRegionDecoder regionDecoder)43     public TileImageViewAdapter(Bitmap backup, BitmapRegionDecoder regionDecoder) {
44         mBackupImage = Utils.checkNotNull(backup);
45         mRegionDecoder = regionDecoder;
46         mImageWidth = regionDecoder.getWidth();
47         mImageHeight = regionDecoder.getHeight();
48         mLevelCount = calculateLevelCount();
49     }
50 
clear()51     public synchronized void clear() {
52         mBackupImage = null;
53         mImageWidth = 0;
54         mImageHeight = 0;
55         mLevelCount = 0;
56         mRegionDecoder = null;
57         mFailedToLoad = false;
58     }
59 
setBackupImage(Bitmap backup, int width, int height)60     public synchronized void setBackupImage(Bitmap backup, int width, int height) {
61         mBackupImage = Utils.checkNotNull(backup);
62         mImageWidth = width;
63         mImageHeight = height;
64         mRegionDecoder = null;
65         mLevelCount = 0;
66         mFailedToLoad = false;
67     }
68 
setRegionDecoder(BitmapRegionDecoder decoder)69     public synchronized void setRegionDecoder(BitmapRegionDecoder decoder) {
70         mRegionDecoder = Utils.checkNotNull(decoder);
71         mImageWidth = decoder.getWidth();
72         mImageHeight = decoder.getHeight();
73         mLevelCount = calculateLevelCount();
74         mFailedToLoad = false;
75     }
76 
calculateLevelCount()77     private int calculateLevelCount() {
78         return Math.max(0, Utils.ceilLog2(
79                 (float) mImageWidth / mBackupImage.getWidth()));
80     }
81 
82     @Override
getTile(int level, int x, int y, int length)83     public synchronized Bitmap getTile(int level, int x, int y, int length) {
84         if (mRegionDecoder == null) return null;
85 
86         Rect region = mRegionRect;
87         Rect intersectRect = mIntersectRect;
88         region.set(x, y, x + (length << level), y + (length << level));
89         intersectRect.set(0, 0, mImageWidth, mImageHeight);
90 
91         // Get the intersected rect of the requested region and the image.
92         Utils.assertTrue(intersectRect.intersect(region));
93 
94         BitmapFactory.Options options = new BitmapFactory.Options();
95         options.inPreferredConfig = Config.ARGB_8888;
96         options.inPreferQualityOverSpeed = true;
97         options.inSampleSize =  (1 << level);
98 
99         Bitmap bitmap;
100 
101         // In CropImage, we may call the decodeRegion() concurrently.
102         synchronized (mRegionDecoder) {
103             bitmap = mRegionDecoder.decodeRegion(intersectRect, options);
104         }
105 
106         // The returned region may not match with the targetLength.
107         // If so, we fill black pixels on it.
108         if (intersectRect.equals(region)) return bitmap;
109 
110         if (bitmap == null) {
111             Log.w(TAG, "fail in decoding region");
112             return null;
113         }
114 
115         Bitmap tile = Bitmap.createBitmap(length, length, Config.ARGB_8888);
116         Canvas canvas = new Canvas(tile);
117         canvas.drawBitmap(bitmap,
118                 (intersectRect.left - region.left) >> level,
119                 (intersectRect.top - region.top) >> level, null);
120         bitmap.recycle();
121         return tile;
122     }
123 
124     @Override
getBackupImage()125     public Bitmap getBackupImage() {
126         return mBackupImage;
127     }
128 
129     @Override
getImageHeight()130     public int getImageHeight() {
131         return mImageHeight;
132     }
133 
134     @Override
getImageWidth()135     public int getImageWidth() {
136         return mImageWidth;
137     }
138 
139     @Override
getLevelCount()140     public int getLevelCount() {
141         return mLevelCount;
142     }
143 
setFailedToLoad()144     public void setFailedToLoad() {
145         mFailedToLoad = true;
146     }
147 
148     @Override
isFailedToLoad()149     public boolean isFailedToLoad() {
150         return mFailedToLoad;
151     }
152 }
153