1f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen/*
2f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * Copyright (C) 2006 The Android Open Source Project
3f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen *
4f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * Licensed under the Apache License, Version 2.0 (the "License");
5f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * you may not use this file except in compliance with the License.
6f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * You may obtain a copy of the License at
7f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen *
8f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen *      http://www.apache.org/licenses/LICENSE-2.0
9f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen *
10f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * Unless required by applicable law or agreed to in writing, software
11f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * distributed under the License is distributed on an "AS IS" BASIS,
12f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * See the License for the specific language governing permissions and
14f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * limitations under the License.
15f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen */
16f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
17f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wenpackage android.graphics;
18f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
19f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen/**
20f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * LargeBitmap can be used to decode a rectangle region from an image.
21f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * LargeBimap is particularly useful when an original image is large and
22f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * you only need parts of the image.
23f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen *
24f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * To create a LargeBitmap, call BitmapFactory.createLargeBitmap().
25f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * Given a LargeBitmap, users can call decodeRegion() repeatedly
26f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * to get a decoded Bitmap of the specified region.
27f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * @hide
28f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen */
29f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wenpublic final class LargeBitmap {
3036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private long mNativeLargeBitmap;
31f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    private boolean mRecycled;
32f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
33f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /*  Private constructor that must received an already allocated native
34f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        large bitmap int (pointer).
35f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
36f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        This can be called from JNI code.
37f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    */
3836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private LargeBitmap(long nativeLbm) {
3936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        mNativeLargeBitmap = nativeLbm;
40f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        mRecycled = false;
41f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
42f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
43f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /**
44f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * Decodes a rectangle region in the image specified by rect.
45f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     *
46f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * @param rect The rectangle that specified the region to be decode.
47f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * @param opts null-ok; Options that control downsampling.
48f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     *             inPurgeable is not supported.
49f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * @return The decoded bitmap, or null if the image data could not be
50f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     *         decoded.
51f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     */
52f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) {
53f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        checkRecycled("decodeRegion called on recycled large bitmap");
54f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        if (rect.left < 0 || rect.top < 0 || rect.right > getWidth() || rect.bottom > getHeight())
55f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            throw new IllegalArgumentException("rectangle is not inside the image");
56f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        return nativeDecodeRegion(mNativeLargeBitmap, rect.left, rect.top,
57f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen                rect.right - rect.left, rect.bottom - rect.top, options);
58f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
59f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
60f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /** Returns the original image's width */
61f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    public int getWidth() {
62f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        checkRecycled("getWidth called on recycled large bitmap");
63f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        return nativeGetWidth(mNativeLargeBitmap);
64f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
65f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
66f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /** Returns the original image's height */
67f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    public int getHeight() {
68f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        checkRecycled("getHeight called on recycled large bitmap");
69f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        return nativeGetHeight(mNativeLargeBitmap);
70f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
71f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
72f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /**
73f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * Frees up the memory associated with this large bitmap, and mark the
74f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * large bitmap as "dead", meaning it will throw an exception if decodeRegion(),
75f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * getWidth() or getHeight() is called.
76f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * This operation cannot be reversed, so it should only be called if you are
77f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * sure there are no further uses for the large bitmap. This is an advanced call,
78f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * and normally need not be called, since the normal GC process will free up this
79f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * memory when there are no more references to this bitmap.
80f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     */
81f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    public void recycle() {
82f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        if (!mRecycled) {
83f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            nativeClean(mNativeLargeBitmap);
84f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            mRecycled = true;
85f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        }
86f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
87f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
88f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /**
89f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * Returns true if this large bitmap has been recycled.
90f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * If so, then it is an error to try use its method.
91f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     *
92f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * @return true if the large bitmap has been recycled
93f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     */
94f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    public final boolean isRecycled() {
95f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        return mRecycled;
96f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
97f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
98f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /**
99f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * Called by methods that want to throw an exception if the bitmap
100f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * has already been recycled.
101f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     */
102f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    private void checkRecycled(String errorMessage) {
103f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        if (mRecycled) {
104f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            throw new IllegalStateException(errorMessage);
105f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        }
106f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
107f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
108f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    protected void finalize() {
109f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        recycle();
110f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
111f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
11236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native Bitmap nativeDecodeRegion(long nativeLbm,
113f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            int start_x, int start_y, int width, int height,
114f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            BitmapFactory.Options options);
11536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native int nativeGetWidth(long nativeLbm);
11636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native int nativeGetHeight(long nativeLbm);
11736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeClean(long nativeLbm);
118f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen}
119