16b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen/* Copyright (C) 2010 The Android Open Source Project 26b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 36b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License"); 46b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * you may not use this file except in compliance with the License. 56b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * You may obtain a copy of the License at 66b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 76b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * http://www.apache.org/licenses/LICENSE-2.0 86b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 96b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Unless required by applicable law or agreed to in writing, software 106b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS, 116b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 126b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * See the License for the specific language governing permissions and 136b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * limitations under the License. 146b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 156b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 166b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenpackage android.graphics; 176b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 186b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenimport android.content.res.AssetManager; 196b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 206b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenimport java.io.BufferedInputStream; 216b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenimport java.io.FileDescriptor; 226b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenimport java.io.FileInputStream; 236b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenimport java.io.IOException; 246b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenimport java.io.InputStream; 256b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 266b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen/** 276b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * BitmapRegionDecoder can be used to decode a rectangle region from an image. 286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * BitmapRegionDecoder is particularly useful when an original image is large and 296b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * you only need parts of the image. 306b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 316b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * <p>To create a BitmapRegionDecoder, call newInstance(...). 326b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Given a BitmapRegionDecoder, users can call decodeRegion() repeatedly 336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * to get a decoded Bitmap of the specified region. 346b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 366b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenpublic final class BitmapRegionDecoder { 376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private int mNativeBitmapRegionDecoder; 386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private boolean mRecycled; 39cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger // ensures that the native decoder object exists and that only one decode can 40cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger // occur at a time. 41cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger private final Object mNativeLock = new Object(); 426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 446b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from the specified byte array. 4596d3b5e38301f5d4eff01de8730b6021eb167af9Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param data byte array of compressed image data. 486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param offset offset into data for where the decoder should begin 496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * parsing. 506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param length the number of bytes, beginning at offset, to parse 516b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 536b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 546b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 566b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 576b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 586b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 606b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 616b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance(byte[] data, 626b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen int offset, int length, boolean isShareable) throws IOException { 636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if ((offset | length) < 0 || data.length < offset + length) { 646b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen throw new ArrayIndexOutOfBoundsException(); 656b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 666b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance(data, offset, length, isShareable); 676b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 686b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 696b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 706b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from the file descriptor. 716b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * The position within the descriptor will not be changed when 726b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * this returns, so the descriptor can be used again as is. 7396d3b5e38301f5d4eff01de8730b6021eb167af9Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 746b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 756b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param fd The file descriptor containing the data to decode 766b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 776b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 786b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 796b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 806b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 816b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 826b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 836b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 846b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 856b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 866b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance( 876b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen FileDescriptor fd, boolean isShareable) throws IOException { 886b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance(fd, isShareable); 896b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 906b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 916b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 926b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from an input stream. 936b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * The stream's position will be where ever it was after the encoded data 946b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * was read. 9596d3b5e38301f5d4eff01de8730b6021eb167af9Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 966b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 976b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param is The input stream that holds the raw data to be decoded into a 986b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * BitmapRegionDecoder. 996b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 1006b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 1016b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 1026b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 1036b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 1046b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 1056b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 1066b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 1076b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 1086b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1096b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance(InputStream is, 1106b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen boolean isShareable) throws IOException { 1116b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // we need mark/reset to work properly in JNI 1126b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1136b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (!is.markSupported()) { 1146b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen is = new BufferedInputStream(is, 16 * 1024); 1156b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1166b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1176b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (is instanceof AssetManager.AssetInputStream) { 1186b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance( 1196b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen ((AssetManager.AssetInputStream) is).getAssetInt(), 1206b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen isShareable); 1216b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } else { 1226b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // pass some temp storage down to the native code. 1024 is made up, 1236b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // but should be large enough to avoid too many small calls back 1246b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // into is.read(...). 1256b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen byte [] tempStorage = new byte[16 * 1024]; 1266b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance(is, tempStorage, isShareable); 1276b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1296b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1306b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 1316b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from a file path. 13296d3b5e38301f5d4eff01de8730b6021eb167af9Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 1336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 1346b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param pathName complete path name for the file to be decoded. 1356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 1366b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 1376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 1386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 1396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 1406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 1416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 1426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 1436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 1446b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1456b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance(String pathName, 1466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen boolean isShareable) throws IOException { 1476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen BitmapRegionDecoder decoder = null; 1486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen InputStream stream = null; 1496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen try { 1516b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen stream = new FileInputStream(pathName); 1526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen decoder = newInstance(stream, isShareable); 1536b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } finally { 1546b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (stream != null) { 1556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen try { 1566b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen stream.close(); 1576b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } catch (IOException e) { 1586b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // do nothing here 1596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1606b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1616b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1626b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return decoder; 1636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1646b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1656b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /* Private constructor that must receive an already allocated native 1666b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen region decoder int (pointer). 1676b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1686b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen This can be called from JNI code. 1696b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1706b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private BitmapRegionDecoder(int decoder) { 1716b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen mNativeBitmapRegionDecoder = decoder; 1726b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen mRecycled = false; 1736b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1746b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1756b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 1766b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Decodes a rectangle region in the image specified by rect. 1776b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 1786b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param rect The rectangle that specified the region to be decode. 1796b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param options null-ok; Options that control downsampling. 1806b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * inPurgeable is not supported. 1816b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return The decoded bitmap, or null if the image data could not be 1826b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * decoded. 1836b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1846b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) { 185cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger synchronized (mNativeLock) { 186cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger checkRecycled("decodeRegion called on recycled region decoder"); 187cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= getWidth() 188cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger || rect.top >= getHeight()) 189cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger throw new IllegalArgumentException("rectangle is outside the image"); 190cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top, 191cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger rect.right - rect.left, rect.bottom - rect.top, options); 192cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger } 1936b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1946b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1956b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** Returns the original image's width */ 1966b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public int getWidth() { 197cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger synchronized (mNativeLock) { 198cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger checkRecycled("getWidth called on recycled region decoder"); 199cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger return nativeGetWidth(mNativeBitmapRegionDecoder); 200cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger } 2016b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2026b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2036b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** Returns the original image's height */ 2046b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public int getHeight() { 205cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger synchronized (mNativeLock) { 206cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger checkRecycled("getHeight called on recycled region decoder"); 207cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger return nativeGetHeight(mNativeBitmapRegionDecoder); 208cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger } 2096b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2106b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2116b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 2126b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Frees up the memory associated with this region decoder, and mark the 2136b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * region decoder as "dead", meaning it will throw an exception if decodeRegion(), 2146b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * getWidth() or getHeight() is called. 2156b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 2166b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * <p>This operation cannot be reversed, so it should only be called if you are 2176b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * sure there are no further uses for the region decoder. This is an advanced call, 2186b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * and normally need not be called, since the normal GC process will free up this 2196b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * memory when there are no more references to this region decoder. 2206b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 2216b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public void recycle() { 222cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger synchronized (mNativeLock) { 223cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger if (!mRecycled) { 224cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger nativeClean(mNativeBitmapRegionDecoder); 225cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger mRecycled = true; 226cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger } 2276b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2296b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2306b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 2316b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Returns true if this region decoder has been recycled. 2326b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * If so, then it is an error to try use its method. 2336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 2346b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return true if the region decoder has been recycled 2356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 2366b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public final boolean isRecycled() { 2376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return mRecycled; 2386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 2416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Called by methods that want to throw an exception if the region decoder 2426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * has already been recycled. 2436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 2446b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private void checkRecycled(String errorMessage) { 2456b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (mRecycled) { 2466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen throw new IllegalStateException(errorMessage); 2476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen @Override 2516b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen protected void finalize() throws Throwable { 2526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen try { 2536b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen recycle(); 2546b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } finally { 2556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen super.finalize(); 2566b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2576b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2586b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native Bitmap nativeDecodeRegion(int lbm, 2606b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen int start_x, int start_y, int width, int height, 2616b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen BitmapFactory.Options options); 2626b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native int nativeGetWidth(int lbm); 2636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native int nativeGetHeight(int lbm); 2646b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native void nativeClean(int lbm); 2656b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2666b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 2676b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen byte[] data, int offset, int length, boolean isShareable); 2686b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 2696b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen FileDescriptor fd, boolean isShareable); 2706b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 2716b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen InputStream is, byte[] storage, boolean isShareable); 2726b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 2736b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen int asset, boolean isShareable); 2746b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 275