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.FileDescriptor; 216b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenimport java.io.FileInputStream; 226b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenimport java.io.IOException; 236b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenimport java.io.InputStream; 246b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 256b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen/** 266b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * BitmapRegionDecoder can be used to decode a rectangle region from an image. 276b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * BitmapRegionDecoder is particularly useful when an original image is large and 286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * you only need parts of the image. 296b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 306b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * <p>To create a BitmapRegionDecoder, call newInstance(...). 316b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Given a BitmapRegionDecoder, users can call decodeRegion() repeatedly 326b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * to get a decoded Bitmap of the specified region. 336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 346b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenpublic final class BitmapRegionDecoder { 36b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat private long mNativeBitmapRegionDecoder; 376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private boolean mRecycled; 38cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger // ensures that the native decoder object exists and that only one decode can 39cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger // occur at a time. 40cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger private final Object mNativeLock = new Object(); 416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from the specified byte array. 4496d3b5e38301f5d4eff01de8730b6021eb167af9Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 456b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param data byte array of compressed image data. 476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param offset offset into data for where the decoder should begin 486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * parsing. 496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param length the number of bytes, beginning at offset, to parse 506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 516b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 536b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 546b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 566b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 576b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 586b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 606b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance(byte[] data, 616b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen int offset, int length, boolean isShareable) throws IOException { 626b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if ((offset | length) < 0 || data.length < offset + length) { 636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen throw new ArrayIndexOutOfBoundsException(); 646b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 656b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance(data, offset, length, isShareable); 666b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 676b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 686b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 696b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from the file descriptor. 706b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * The position within the descriptor will not be changed when 716b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * this returns, so the descriptor can be used again as is. 7296d3b5e38301f5d4eff01de8730b6021eb167af9Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 736b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 746b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param fd The file descriptor containing the data to decode 756b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 766b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 776b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 786b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 796b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 806b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 816b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 826b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 836b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 846b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 856b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance( 866b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen FileDescriptor fd, boolean isShareable) throws IOException { 876b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance(fd, isShareable); 886b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 896b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 906b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 916b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from an input stream. 926b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * The stream's position will be where ever it was after the encoded data 936b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * was read. 9496d3b5e38301f5d4eff01de8730b6021eb167af9Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 956b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 966b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param is The input stream that holds the raw data to be decoded into a 976b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * BitmapRegionDecoder. 986b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 996b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 1006b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 1016b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 1026b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 1036b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 1046b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 1056b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 1066b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 107321bc46b3c885a806f2e7e29db8212f7ea6c8670Leon Scroggins III * 108321bc46b3c885a806f2e7e29db8212f7ea6c8670Leon Scroggins III * <p class="note">Prior to {@link android.os.Build.VERSION_CODES#KITKAT}, 109321bc46b3c885a806f2e7e29db8212f7ea6c8670Leon Scroggins III * if {@link InputStream#markSupported is.markSupported()} returns true, 110321bc46b3c885a806f2e7e29db8212f7ea6c8670Leon Scroggins III * <code>is.mark(1024)</code> would be called. As of 111321bc46b3c885a806f2e7e29db8212f7ea6c8670Leon Scroggins III * {@link android.os.Build.VERSION_CODES#KITKAT}, this is no longer the case.</p> 1126b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1136b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance(InputStream is, 1146b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen boolean isShareable) throws IOException { 1156b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (is instanceof AssetManager.AssetInputStream) { 1166b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance( 117b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat ((AssetManager.AssetInputStream) is).getNativeAsset(), 1186b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen isShareable); 1196b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } else { 1206b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // pass some temp storage down to the native code. 1024 is made up, 1216b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // but should be large enough to avoid too many small calls back 1226b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // into is.read(...). 1236b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen byte [] tempStorage = new byte[16 * 1024]; 1246b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return nativeNewInstance(is, tempStorage, isShareable); 1256b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1266b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1276b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 1296b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Create a BitmapRegionDecoder from a file path. 13096d3b5e38301f5d4eff01de8730b6021eb167af9Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 1316b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 1326b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param pathName complete path name for the file to be decoded. 1336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 1346b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * shallow reference to the input. If this is false, 1356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 1366b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 1376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * the implementation may still decide to make a deep 1386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 1396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * allowing sharing may degrade the decoding speed. 1406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 1416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 1426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public static BitmapRegionDecoder newInstance(String pathName, 1446b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen boolean isShareable) throws IOException { 1456b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen BitmapRegionDecoder decoder = null; 1466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen InputStream stream = null; 1476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen try { 1496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen stream = new FileInputStream(pathName); 1506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen decoder = newInstance(stream, isShareable); 1516b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } finally { 1526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (stream != null) { 1536b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen try { 1546b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen stream.close(); 1556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } catch (IOException e) { 1566b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen // do nothing here 1576b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1586b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1606b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return decoder; 1616b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1626b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /* Private constructor that must receive an already allocated native 1646b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen region decoder int (pointer). 1656b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1666b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen This can be called from JNI code. 1676b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 168b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat private BitmapRegionDecoder(long decoder) { 1696b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen mNativeBitmapRegionDecoder = decoder; 1706b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen mRecycled = false; 1716b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1726b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1736b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 1746b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Decodes a rectangle region in the image specified by rect. 1756b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 1766b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param rect The rectangle that specified the region to be decode. 1776b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @param options null-ok; Options that control downsampling. 1786b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * inPurgeable is not supported. 1796b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return The decoded bitmap, or null if the image data could not be 1806b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * decoded. 1816b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 1826b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) { 183cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger synchronized (mNativeLock) { 184cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger checkRecycled("decodeRegion called on recycled region decoder"); 185cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= getWidth() 186cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger || rect.top >= getHeight()) 187cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger throw new IllegalArgumentException("rectangle is outside the image"); 188cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top, 189cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger rect.right - rect.left, rect.bottom - rect.top, options); 190cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger } 1916b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 1926b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 1936b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** Returns the original image's width */ 1946b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public int getWidth() { 195cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger synchronized (mNativeLock) { 196cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger checkRecycled("getWidth called on recycled region decoder"); 197cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger return nativeGetWidth(mNativeBitmapRegionDecoder); 198cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger } 1996b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2006b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2016b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** Returns the original image's height */ 2026b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public int getHeight() { 203cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger synchronized (mNativeLock) { 204cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger checkRecycled("getHeight called on recycled region decoder"); 205cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger return nativeGetHeight(mNativeBitmapRegionDecoder); 206cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger } 2076b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2086b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2096b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 2106b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Frees up the memory associated with this region decoder, and mark the 2116b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * region decoder as "dead", meaning it will throw an exception if decodeRegion(), 2126b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * getWidth() or getHeight() is called. 2136b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 2146b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * <p>This operation cannot be reversed, so it should only be called if you are 2156b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * sure there are no further uses for the region decoder. This is an advanced call, 2166b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * and normally need not be called, since the normal GC process will free up this 2176b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * memory when there are no more references to this region decoder. 2186b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 2196b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public void recycle() { 220cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger synchronized (mNativeLock) { 221cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger if (!mRecycled) { 222cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger nativeClean(mNativeBitmapRegionDecoder); 223cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger mRecycled = true; 224cd77583ed336d10c5625933a565dcadf51705c61Derek Sollenberger } 2256b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2266b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2276b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2286b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 2296b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Returns true if this region decoder has been recycled. 2306b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * If so, then it is an error to try use its method. 2316b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * 2326b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * @return true if the region decoder has been recycled 2336b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 2346b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen public final boolean isRecycled() { 2356b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen return mRecycled; 2366b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2376b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2386b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen /** 2396b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * Called by methods that want to throw an exception if the region decoder 2406b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen * has already been recycled. 2416b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen */ 2426b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private void checkRecycled(String errorMessage) { 2436b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen if (mRecycled) { 2446b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen throw new IllegalStateException(errorMessage); 2456b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2466b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2476b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2486b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen @Override 2496b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen protected void finalize() throws Throwable { 2506b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen try { 2516b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen recycle(); 2526b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } finally { 2536b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen super.finalize(); 2546b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2556b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen } 2566b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 257b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat private static native Bitmap nativeDecodeRegion(long lbm, 2586b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen int start_x, int start_y, int width, int height, 2596b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen BitmapFactory.Options options); 260b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat private static native int nativeGetWidth(long lbm); 261b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat private static native int nativeGetHeight(long lbm); 262b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat private static native void nativeClean(long lbm); 2636b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen 2646b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 2656b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen byte[] data, int offset, int length, boolean isShareable); 2666b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 2676b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen FileDescriptor fd, boolean isShareable); 2686b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 2696b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen InputStream is, byte[] storage, boolean isShareable); 2706b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 271b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat long asset, boolean isShareable); 2726b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chen} 273