BitmapRegionDecoder.java revision 6b849e2123be98eb2a1a25b8abf0b13a279ce952
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; 396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from the specified byte array. 426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Currently only the Jpeg format is supported. 436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 446b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param data byte array of compressed image data. 456b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param offset offset into data for where the decoder should begin 466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * parsing. 476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param length the number of bytes, beginning at offset, to parse 486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 516b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 536b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 546b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 566b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 576b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 586b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance(byte[] data, 596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen int offset, int length, boolean isShareable) throws IOException { 606b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if ((offset | length) < 0 || data.length < offset + length) { 616b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen throw new ArrayIndexOutOfBoundsException(); 626b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance(data, offset, length, isShareable); 646b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 656b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 666b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 676b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from the file descriptor. 686b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * The position within the descriptor will not be changed when 696b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * this returns, so the descriptor can be used again as is. 706b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Currently only the Jpeg format is supported. 716b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 726b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param fd The file descriptor containing the data to decode 736b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 746b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 756b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 766b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 776b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 786b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 796b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 806b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 816b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 826b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 836b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance( 846b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen FileDescriptor fd, boolean isShareable) throws IOException { 856b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance(fd, isShareable); 866b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 876b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 886b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 896b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from an input stream. 906b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * The stream's position will be where ever it was after the encoded data 916b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * was read. 926b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Currently only the Jpeg format is supported. 936b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 946b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param is The input stream that holds the raw data to be decoded into a 956b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * BitmapRegionDecoder. 966b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 976b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 986b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 996b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 1006b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 1016b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 1026b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 1036b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 1046b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 1056b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1066b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance(InputStream is, 1076b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen boolean isShareable) throws IOException { 1086b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // we need mark/reset to work properly in JNI 1096b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1106b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (!is.markSupported()) { 1116b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen is = new BufferedInputStream(is, 16 * 1024); 1126b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1136b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1146b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (is instanceof AssetManager.AssetInputStream) { 1156b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance( 1166b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen ((AssetManager.AssetInputStream) is).getAssetInt(), 1176b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen isShareable); 1186b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } else { 1196b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // pass some temp storage down to the native code. 1024 is made up, 1206b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // but should be large enough to avoid too many small calls back 1216b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // into is.read(...). 1226b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen byte [] tempStorage = new byte[16 * 1024]; 1236b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance(is, tempStorage, isShareable); 1246b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1256b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1266b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1276b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 1286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from a file path. 1296b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Currently only the Jpeg format is supported. 1306b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 1316b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param pathName complete path name for the file to be decoded. 1326b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 1336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 1346b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 1356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 1366b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 1376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 1386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 1396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 1406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 1416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance(String pathName, 1436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen boolean isShareable) throws IOException { 1446b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen BitmapRegionDecoder decoder = null; 1456b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen InputStream stream = null; 1466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen try { 1486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen stream = new FileInputStream(pathName); 1496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen decoder = newInstance(stream, isShareable); 1506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } finally { 1516b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (stream != null) { 1526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen try { 1536b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen stream.close(); 1546b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } catch (IOException e) { 1556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // do nothing here 1566b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1576b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1586b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return decoder; 1606b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1616b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1626b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /* Private constructor that must receive an already allocated native 1636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen region decoder int (pointer). 1646b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1656b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen This can be called from JNI code. 1666b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1676b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private BitmapRegionDecoder(int decoder) { 1686b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen mNativeBitmapRegionDecoder = decoder; 1696b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen mRecycled = false; 1706b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1716b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1726b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 1736b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Decodes a rectangle region in the image specified by rect. 1746b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 1756b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param rect The rectangle that specified the region to be decode. 1766b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param options null-ok; Options that control downsampling. 1776b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * inPurgeable is not supported. 1786b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return The decoded bitmap, or null if the image data could not be 1796b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * decoded. 1806b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1816b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) { 1826b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen checkRecycled("decodeRegion called on recycled region decoder"); 1836b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (rect.left < 0 || rect.top < 0 || rect.right > getWidth() 1846b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen || rect.bottom > getHeight()) 1856b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen throw new IllegalArgumentException("rectangle is not inside the image"); 1866b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top, 1876b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen rect.right - rect.left, rect.bottom - rect.top, options); 1886b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1896b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1906b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** Returns the original image's width */ 1916b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public int getWidth() { 1926b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen checkRecycled("getWidth called on recycled region decoder"); 1936b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeGetWidth(mNativeBitmapRegionDecoder); 1946b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1956b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1966b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** Returns the original image's height */ 1976b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public int getHeight() { 1986b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen checkRecycled("getHeight called on recycled region decoder"); 1996b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeGetHeight(mNativeBitmapRegionDecoder); 2006b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2016b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2026b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 2036b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Frees up the memory associated with this region decoder, and mark the 2046b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * region decoder as "dead", meaning it will throw an exception if decodeRegion(), 2056b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * getWidth() or getHeight() is called. 2066b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 2076b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * <p>This operation cannot be reversed, so it should only be called if you are 2086b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * sure there are no further uses for the region decoder. This is an advanced call, 2096b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * and normally need not be called, since the normal GC process will free up this 2106b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * memory when there are no more references to this region decoder. 2116b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 2126b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public void recycle() { 2136b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (!mRecycled) { 2146b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen nativeClean(mNativeBitmapRegionDecoder); 2156b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen mRecycled = true; 2166b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2176b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2186b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2196b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 2206b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Returns true if this region decoder has been recycled. 2216b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * If so, then it is an error to try use its method. 2226b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 2236b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return true if the region decoder has been recycled 2246b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 2256b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public final boolean isRecycled() { 2266b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return mRecycled; 2276b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2296b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 2306b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Called by methods that want to throw an exception if the region decoder 2316b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * has already been recycled. 2326b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 2336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private void checkRecycled(String errorMessage) { 2346b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (mRecycled) { 2356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen throw new IllegalStateException(errorMessage); 2366b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen @Override 2406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen protected void finalize() throws Throwable { 2416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen try { 2426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen recycle(); 2436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } finally { 2446b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen super.finalize(); 2456b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native Bitmap nativeDecodeRegion(int lbm, 2496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen int start_x, int start_y, int width, int height, 2506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen BitmapFactory.Options options); 2516b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native int nativeGetWidth(int lbm); 2526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native int nativeGetHeight(int lbm); 2536b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native void nativeClean(int lbm); 2546b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 2566b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen byte[] data, int offset, int length, boolean isShareable); 2576b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 2586b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen FileDescriptor fd, boolean isShareable); 2596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 2606b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen InputStream is, byte[] storage, boolean isShareable); 2616b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 2626b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen int asset, boolean isShareable); 2636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 264