125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen/* Copyright (C) 2010 The Android Open Source Project 225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License"); 425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * you may not use this file except in compliance with the License. 525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * You may obtain a copy of the License at 625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * http://www.apache.org/licenses/LICENSE-2.0 825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Unless required by applicable law or agreed to in writing, software 1025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS, 1125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * See the License for the specific language governing permissions and 1325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * limitations under the License. 1425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen */ 1525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 1625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chenpackage android.graphics; 1725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 1825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chenimport android.content.res.AssetManager; 1925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 2025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chenimport java.io.BufferedInputStream; 2125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chenimport java.io.FileDescriptor; 2225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chenimport java.io.FileInputStream; 2325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chenimport java.io.IOException; 2425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chenimport java.io.InputStream; 2525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 2625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen/** 2725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * BitmapRegionDecoder can be used to decode a rectangle region from an image. 2825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * BitmapRegionDecoder is particularly useful when an original image is large and 2925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * you only need parts of the image. 3025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 3125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * <p>To create a BitmapRegionDecoder, call newInstance(...). 3225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Given a BitmapRegionDecoder, users can call decodeRegion() repeatedly 3325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * to get a decoded Bitmap of the specified region. 3425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 3525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen */ 3625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chenpublic final class BitmapRegionDecoder { 3725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private int mNativeBitmapRegionDecoder; 3825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private boolean mRecycled; 3925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 4025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen /** 4125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Create a BitmapRegionDecoder from the specified byte array. 4225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 4325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 4425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param data byte array of compressed image data. 4525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param offset offset into data for where the decoder should begin 4625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * parsing. 4725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param length the number of bytes, beginning at offset, to parse 4825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 4925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * shallow reference to the input. If this is false, 5025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 5125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 5225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * the implementation may still decide to make a deep 5325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 5425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * allowing sharing may degrade the decoding speed. 5525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 5625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 5725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen */ 5825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen public static BitmapRegionDecoder newInstance(byte[] data, 5925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen int offset, int length, boolean isShareable) throws IOException { 6025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen if ((offset | length) < 0 || data.length < offset + length) { 6125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen throw new ArrayIndexOutOfBoundsException(); 6225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 6325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen return nativeNewInstance(data, offset, length, isShareable); 6425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 6525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 6625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen /** 6725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Create a BitmapRegionDecoder from the file descriptor. 6825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * The position within the descriptor will not be changed when 6925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * this returns, so the descriptor can be used again as is. 7025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 7125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 7225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param fd The file descriptor containing the data to decode 7325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 7425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * shallow reference to the input. If this is false, 7525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 7625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 7725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * the implementation may still decide to make a deep 7825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 7925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * allowing sharing may degrade the decoding speed. 8025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 8125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 8225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen */ 8325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen public static BitmapRegionDecoder newInstance( 8425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen FileDescriptor fd, boolean isShareable) throws IOException { 8525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen return nativeNewInstance(fd, isShareable); 8625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 8725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 8825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen /** 8925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Create a BitmapRegionDecoder from an input stream. 9025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * The stream's position will be where ever it was after the encoded data 9125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * was read. 9225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 9325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 9425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param is The input stream that holds the raw data to be decoded into a 9525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * BitmapRegionDecoder. 9625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 9725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * shallow reference to the input. If this is false, 9825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 9925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 10025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * the implementation may still decide to make a deep 10125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 10225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * allowing sharing may degrade the decoding speed. 10325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 10425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 10525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen */ 10625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen public static BitmapRegionDecoder newInstance(InputStream is, 10725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen boolean isShareable) throws IOException { 10825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen // we need mark/reset to work properly in JNI 10925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 11025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen if (!is.markSupported()) { 11125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen is = new BufferedInputStream(is, 16 * 1024); 11225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 11325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 11425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen if (is instanceof AssetManager.AssetInputStream) { 11525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen return nativeNewInstance( 11625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen ((AssetManager.AssetInputStream) is).getAssetInt(), 11725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen isShareable); 11825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } else { 11925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen // pass some temp storage down to the native code. 1024 is made up, 12025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen // but should be large enough to avoid too many small calls back 12125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen // into is.read(...). 12225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen byte [] tempStorage = new byte[16 * 1024]; 12325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen return nativeNewInstance(is, tempStorage, isShareable); 12425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 12525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 12625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 12725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen /** 12825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Create a BitmapRegionDecoder from a file path. 12925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Currently only the JPEG and PNG formats are supported. 13025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 13125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param pathName complete path name for the file to be decoded. 13225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param isShareable If this is true, then the BitmapRegionDecoder may keep a 13325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * shallow reference to the input. If this is false, 13425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * then the BitmapRegionDecoder will explicitly make a copy of the 13525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * input data, and keep that. Even if sharing is allowed, 13625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * the implementation may still decide to make a deep 13725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * copy of the input data. If an image is progressively encoded, 13825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * allowing sharing may degrade the decoding speed. 13925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @return BitmapRegionDecoder, or null if the image data could not be decoded. 14025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @throws IOException if the image format is not supported or can not be decoded. 14125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen */ 14225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen public static BitmapRegionDecoder newInstance(String pathName, 14325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen boolean isShareable) throws IOException { 14425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen BitmapRegionDecoder decoder = null; 14525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen InputStream stream = null; 14625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 14725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen try { 14825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen stream = new FileInputStream(pathName); 14925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen decoder = newInstance(stream, isShareable); 15025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } finally { 15125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen if (stream != null) { 15225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen try { 15325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen stream.close(); 15425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } catch (IOException e) { 15525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen // do nothing here 15625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 15725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 15825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 15925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen return decoder; 16025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 16125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 16225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen /* Private constructor that must receive an already allocated native 16325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen region decoder int (pointer). 16425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 16525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen This can be called from JNI code. 16625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen */ 16725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private BitmapRegionDecoder(int decoder) { 16825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen mNativeBitmapRegionDecoder = decoder; 16925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen mRecycled = false; 17025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 17125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 17225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen /** 17325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Decodes a rectangle region in the image specified by rect. 17425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 17525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param rect The rectangle that specified the region to be decode. 17625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @param options null-ok; Options that control downsampling. 17725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * inPurgeable is not supported. 17825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @return The decoded bitmap, or null if the image data could not be 17925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * decoded. 18025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen */ 18125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) { 18225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen checkRecycled("decodeRegion called on recycled region decoder"); 18325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen if (rect.left < 0 || rect.top < 0 || rect.right > getWidth() 18425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen || rect.bottom > getHeight()) 18525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen throw new IllegalArgumentException("rectangle is not inside the image"); 18625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top, 18725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen rect.right - rect.left, rect.bottom - rect.top, options); 18825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 18925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 19025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen /** Returns the original image's width */ 19125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen public int getWidth() { 19225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen checkRecycled("getWidth called on recycled region decoder"); 19325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen return nativeGetWidth(mNativeBitmapRegionDecoder); 19425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 19525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 19625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen /** Returns the original image's height */ 19725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen public int getHeight() { 19825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen checkRecycled("getHeight called on recycled region decoder"); 19925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen return nativeGetHeight(mNativeBitmapRegionDecoder); 20025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 20125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 20225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen /** 20325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Frees up the memory associated with this region decoder, and mark the 20425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * region decoder as "dead", meaning it will throw an exception if decodeRegion(), 20525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * getWidth() or getHeight() is called. 20625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 20725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * <p>This operation cannot be reversed, so it should only be called if you are 20825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * sure there are no further uses for the region decoder. This is an advanced call, 20925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * and normally need not be called, since the normal GC process will free up this 21025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * memory when there are no more references to this region decoder. 21125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen */ 21225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen public void recycle() { 21325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen if (!mRecycled) { 21425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen nativeClean(mNativeBitmapRegionDecoder); 21525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen mRecycled = true; 21625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 21725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 21825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 21925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen /** 22025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Returns true if this region decoder has been recycled. 22125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * If so, then it is an error to try use its method. 22225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * 22325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * @return true if the region decoder has been recycled 22425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen */ 22525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen public final boolean isRecycled() { 22625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen return mRecycled; 22725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 22825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 22925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen /** 23025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * Called by methods that want to throw an exception if the region decoder 23125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen * has already been recycled. 23225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen */ 23325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private void checkRecycled(String errorMessage) { 23425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen if (mRecycled) { 23525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen throw new IllegalStateException(errorMessage); 23625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 23725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 23825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 23925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen @Override 24025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen protected void finalize() throws Throwable { 24125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen try { 24225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen recycle(); 24325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } finally { 24425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen super.finalize(); 24525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 24625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen } 24725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 24825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private static native Bitmap nativeDecodeRegion(int lbm, 24925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen int start_x, int start_y, int width, int height, 25025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen BitmapFactory.Options options); 25125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private static native int nativeGetWidth(int lbm); 25225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private static native int nativeGetHeight(int lbm); 25325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private static native void nativeClean(int lbm); 25425bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen 25525bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 25625bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen byte[] data, int offset, int length, boolean isShareable); 25725bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 25825bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen FileDescriptor fd, boolean isShareable); 25925bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 26025bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen InputStream is, byte[] storage, boolean isShareable); 26125bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen private static native BitmapRegionDecoder nativeNewInstance( 26225bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen int asset, boolean isShareable); 26325bce3a673afef6a7858270afae4395b4ab53de3Wei-Ta Chen} 264