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 Wenimport android.os.Parcel;
20f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wenimport android.os.Parcelable;
21f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wenimport android.util.DisplayMetrics;
22f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
23f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wenimport java.io.OutputStream;
24f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wenimport java.nio.Buffer;
25f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wenimport java.nio.ByteBuffer;
26f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wenimport java.nio.IntBuffer;
27f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wenimport java.nio.ShortBuffer;
28f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
29f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen/**
30f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * LargeBitmap can be used to decode a rectangle region from an image.
31f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * LargeBimap is particularly useful when an original image is large and
32f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * you only need parts of the image.
33f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen *
34f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * To create a LargeBitmap, call BitmapFactory.createLargeBitmap().
35f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * Given a LargeBitmap, users can call decodeRegion() repeatedly
36f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * to get a decoded Bitmap of the specified region.
37f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen * @hide
38f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen */
39f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wenpublic final class LargeBitmap {
40f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    private int mNativeLargeBitmap;
41f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    private boolean mRecycled;
42f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
43f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /*  Private constructor that must received an already allocated native
44f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        large bitmap int (pointer).
45f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
46f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        This can be called from JNI code.
47f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    */
48f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    private LargeBitmap(int lbm) {
49f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        mNativeLargeBitmap = lbm;
50f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        mRecycled = false;
51f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
52f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
53f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /**
54f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * Decodes a rectangle region in the image specified by rect.
55f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     *
56f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * @param rect The rectangle that specified the region to be decode.
57f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * @param opts null-ok; Options that control downsampling.
58f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     *             inPurgeable is not supported.
59f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * @return The decoded bitmap, or null if the image data could not be
60f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     *         decoded.
61f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     */
62f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) {
63f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        checkRecycled("decodeRegion called on recycled large bitmap");
64f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        if (rect.left < 0 || rect.top < 0 || rect.right > getWidth() || rect.bottom > getHeight())
65f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            throw new IllegalArgumentException("rectangle is not inside the image");
66f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        return nativeDecodeRegion(mNativeLargeBitmap, rect.left, rect.top,
67f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen                rect.right - rect.left, rect.bottom - rect.top, options);
68f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
69f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
70f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /** Returns the original image's width */
71f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    public int getWidth() {
72f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        checkRecycled("getWidth called on recycled large bitmap");
73f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        return nativeGetWidth(mNativeLargeBitmap);
74f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
75f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
76f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /** Returns the original image's height */
77f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    public int getHeight() {
78f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        checkRecycled("getHeight called on recycled large bitmap");
79f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        return nativeGetHeight(mNativeLargeBitmap);
80f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
81f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
82f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /**
83f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * Frees up the memory associated with this large bitmap, and mark the
84f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * large bitmap as "dead", meaning it will throw an exception if decodeRegion(),
85f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * getWidth() or getHeight() is called.
86f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * This operation cannot be reversed, so it should only be called if you are
87f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * sure there are no further uses for the large bitmap. This is an advanced call,
88f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * and normally need not be called, since the normal GC process will free up this
89f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * memory when there are no more references to this bitmap.
90f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     */
91f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    public void recycle() {
92f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        if (!mRecycled) {
93f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            nativeClean(mNativeLargeBitmap);
94f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            mRecycled = true;
95f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        }
96f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
97f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
98f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /**
99f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * Returns true if this large bitmap has been recycled.
100f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * If so, then it is an error to try use its method.
101f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     *
102f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * @return true if the large bitmap has been recycled
103f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     */
104f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    public final boolean isRecycled() {
105f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        return mRecycled;
106f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
107f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
108f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    /**
109f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * Called by methods that want to throw an exception if the bitmap
110f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     * has already been recycled.
111f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen     */
112f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    private void checkRecycled(String errorMessage) {
113f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        if (mRecycled) {
114f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            throw new IllegalStateException(errorMessage);
115f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        }
116f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
117f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
118f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    protected void finalize() {
119f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen        recycle();
120f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    }
121f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
122f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    private static native Bitmap nativeDecodeRegion(int lbm,
123f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            int start_x, int start_y, int width, int height,
124f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen            BitmapFactory.Options options);
125f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    private static native int nativeGetWidth(int lbm);
126f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    private static native int nativeGetHeight(int lbm);
127f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    private static native void nativeClean(int lbm);
128f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen}
129