Bitmap.java revision ec4a50428d5f26a22df3edaf7e5b08f41d5cb54b
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasaniimport android.os.Debug;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
218cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chenimport android.os.Parcelable;
222784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackbornimport android.util.DisplayMetrics;
23ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasaniimport android.util.Log;
24ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani
258cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chenimport java.io.OutputStream;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.nio.Buffer;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.nio.ByteBuffer;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.nio.IntBuffer;
298cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chenimport java.nio.ShortBuffer;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class Bitmap implements Parcelable {
32e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates that the bitmap was created for an unknown pixel density.
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see Bitmap#getDensity()
3711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see Bitmap#setDensity(int)
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public static final int DENSITY_NONE = 0;
4011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
41ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    /**
42ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     * Note:  mNativeBitmap is used by FaceDetector_jni.cpp
43ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     * Don't change/rename without updating FaceDetector_jni.cpp
44ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     *
45ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     * @hide
46ce0537b80087a6225273040a987414b1dd081aa0Romain Guy     */
47ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    public final int mNativeBitmap;
488cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
49e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy    /**
50e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy     * Backing buffer for the Bitmap.
51e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy     * Made public for quick access from drawing methods -- do NOT modify
52e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy     * from outside this class.
53e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy     *
54e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy     * @hide
55e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy     */
56e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy    public byte[] mBuffer;
57e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy
582361098da3b9d9c3eeed410dc72ba62c0e9177cfRomain Guy    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
59e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy    private final BitmapFinalizer mFinalizer;
60e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final boolean mIsMutable;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private byte[] mNinePatchChunk;   // may be null
63ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    private int[] mLayoutBounds;   // may be null
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mWidth = -1;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mHeight = -1;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mRecycled;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    // Package-scoped for fast access.
6996e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    /*package*/ int mDensity = sDefaultDensity = getDefaultDensity();
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    private static volatile Matrix sScaleMatrix;
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7396e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    private static volatile int sDefaultDensity = -1;
7402890fd0f98b3b8d98baf0bda1ea906afd723d8bRomain Guy
7596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    /**
7696e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * For backwards compatibility, allows the app layer to change the default
7796e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * density when running old apps.
7896e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * @hide
7996e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     */
8096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    public static void setDefaultDensity(int density) {
8196e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        sDefaultDensity = density;
8296e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    }
8396e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn
8496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    /*package*/ static int getDefaultDensity() {
8596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        if (sDefaultDensity >= 0) {
8696e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn            return sDefaultDensity;
8796e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        }
8896e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        sDefaultDensity = DisplayMetrics.DENSITY_DEVICE;
8996e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        return sDefaultDensity;
9096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    }
9196e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @noinspection UnusedDeclaration
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*  Private constructor that must received an already allocated native
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bitmap int (pointer).
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        This can be called from JNI code.
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    */
1007f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet    /*package*/ Bitmap(int nativeBitmap, byte[] buffer, boolean isMutable, byte[] ninePatchChunk,
101e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy            int density) {
102ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani        this(nativeBitmap, buffer, isMutable, ninePatchChunk, null, density);
103ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    }
104ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani
105ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    /**
106ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     * @noinspection UnusedDeclaration
107ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     */
108ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    /*  Private constructor that must received an already allocated native
109ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani        bitmap int (pointer).
110ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani
111ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani        This can be called from JNI code.
112ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    */
113ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    /*package*/ Bitmap(int nativeBitmap, byte[] buffer, boolean isMutable, byte[] ninePatchChunk,
114ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani            int[] layoutBounds, int density) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (nativeBitmap == 0) {
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("internal error: native bitmap is 0");
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1188cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
119e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        mBuffer = buffer;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // we delete this in our finalizer
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNativeBitmap = nativeBitmap;
122e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        mFinalizer = new BitmapFinalizer(nativeBitmap);
123e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsMutable = isMutable;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNinePatchChunk = ninePatchChunk;
126ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani        mLayoutBounds = layoutBounds;
127de0dfb7b65a02d4dd74c271b558adee0973fc267Dianne Hackborn        if (density >= 0) {
128de0dfb7b65a02d4dd74c271b558adee0973fc267Dianne Hackborn            mDensity = density;
129de0dfb7b65a02d4dd74c271b558adee0973fc267Dianne Hackborn        }
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * <p>Returns the density for this bitmap.</p>
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * <p>The default density is the same density as the current display,
13696e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * unless the current application does not support different screen
13796e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * densities in which case it is
13896e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * {@link android.util.DisplayMetrics#DENSITY_DEFAULT}.  Note that
13996e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * compatibility mode is determined by the application that was initially
14096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * loaded into a process -- applications that share the same process should
14196e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * all have the same compatibility, or ensure they explicitly set the
14296e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * density of their bitmaps appropriately.</p>
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
14496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * @return A scaling factor of the default density or {@link #DENSITY_NONE}
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         if the scaling factor is unknown.
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
14711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see #setDensity(int)
148a53b828635fce8b6b2d3e3377d74d72070056623Dianne Hackborn     * @see android.util.DisplayMetrics#DENSITY_DEFAULT
14911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see android.util.DisplayMetrics#densityDpi
15011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see #DENSITY_NONE
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getDensity() {
15311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return mDensity;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * <p>Specifies the density for this bitmap.  When the bitmap is
15811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * drawn to a Canvas that also has a density, it will be scaled
15911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * appropriately.</p>
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @param density The density scaling factor to use with this bitmap or
16211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     *        {@link #DENSITY_NONE} if the density is unknown.
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see #getDensity()
165a53b828635fce8b6b2d3e3377d74d72070056623Dianne Hackborn     * @see android.util.DisplayMetrics#DENSITY_DEFAULT
16611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see android.util.DisplayMetrics#densityDpi
16711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see #DENSITY_NONE
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public void setDensity(int density) {
17011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        mDensity = density;
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the nine patch chunk.
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param chunk The definition of the nine patch
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setNinePatchChunk(byte[] chunk) {
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNinePatchChunk = chunk;
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1838cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
185ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     * Sets the layout bounds as an array of left, top, right, bottom integers
186ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     * @param padding the array containing the padding values
187ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     *
188ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     * @hide
189ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     */
190ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    public void setLayoutBounds(int[] bounds) {
191ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani        mLayoutBounds = bounds;
192ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    }
193ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani
194ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    /**
195a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * Free the native object associated with this bitmap, and clear the
196a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * reference to the pixel data. This will not free the pixel data synchronously;
197a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * it simply allows it to be garbage collected if there are no other references.
198a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * The bitmap is marked as "dead", meaning it will throw an exception if
199a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * getPixels() or setPixels() is called, and will draw nothing. This operation
200a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * cannot be reversed, so it should only be called if you are sure there are no
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * further uses for the bitmap. This is an advanced call, and normally need
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not be called, since the normal GC process will free up this memory when
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * there are no more references to this bitmap.
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void recycle() {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mRecycled) {
207e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy            mBuffer = null;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nativeRecycle(mNativeBitmap);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mNinePatchChunk = null;
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRecycled = true;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns true if this bitmap has been recycled. If so, then it is an error
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to try to access its pixels, and the bitmap will not draw.
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the bitmap has been recycled
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean isRecycled() {
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mRecycled;
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2238cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2250bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy     * Returns the generation ID of this bitmap. The generation ID changes
2260bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy     * whenever the bitmap is modified. This can be used as an efficient way to
2270bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy     * check if a bitmap has changed.
2280bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy     *
2290bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy     * @return The current generation ID for this bitmap.
2300bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy     */
2310bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy    public int getGenerationId() {
2320bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy        return nativeGenerationId(mNativeBitmap);
2330bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy    }
2340bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy
2350bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy    /**
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called by methods that want to throw an exception if the bitmap
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * has already been recycled.
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void checkRecycled(String errorMessage) {
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mRecycled) {
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException(errorMessage);
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2448cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Common code for checking that x and y are >= 0
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x x coordinate to ensure is >= 0
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y y coordinate to ensure is >= 0
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void checkXYSign(int x, int y) {
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (x < 0) {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("x must be >= 0");
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (y < 0) {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("y must be >= 0");
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Common code for checking that width and height are > 0
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width  width to ensure is > 0
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height height to ensure is > 0
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void checkWidthHeight(int width, int height) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width <= 0) {
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("width must be > 0");
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height <= 0) {
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("height must be > 0");
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
275676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy    /**
276676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy     * Possible bitmap configurations. A bitmap configuration describes
277676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy     * how pixels are stored. This affects the quality (color depth) as
278676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy     * well as the ability to display transparent/translucent colors.
279676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy     */
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum Config {
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // these native values must match up with the enum in SkBitmap.h
282676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy
283676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        /**
284676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * Each pixel is stored as a single translucency (alpha) channel.
285676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * This is very useful to efficiently store masks for instance.
286676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * No color information is stored.
287676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * With this configuration, each pixel requires 1 byte of memory.
288676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         */
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALPHA_8     (2),
290676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy
291676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        /**
292676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * Each pixel is stored on 2 bytes and only the RGB channels are
293676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * encoded: red is stored with 5 bits of precision (32 possible
294676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * values), green is stored with 6 bits of precision (64 possible
295676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * values) and blue is stored with 5 bits of precision.
296676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         *
297676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * This configuration can produce slight visual artifacts depending
298676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * on the configuration of the source. For instance, without
299676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * dithering, the result might show a greenish tint. To get better
300676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * results dithering should be applied.
301676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         *
302676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * This configuration may be useful when using opaque bitmaps
303676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * that do not require high color fidelity.
304676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         */
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RGB_565     (4),
306676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy
307676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        /**
308676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * Each pixel is stored on 2 bytes. The three RGB color channels
309676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * and the alpha channel (translucency) are stored with a 4 bits
310676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * precision (16 possible values.)
311676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         *
312676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * This configuration is mostly useful if the application needs
313676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * to store translucency information but also needs to save
314676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * memory.
315676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         *
316676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * It is recommended to use {@link #ARGB_8888} instead of this
317676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * configuration.
318676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         *
319676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * @deprecated Because of the poor quality of this configuration,
320676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         *             it is advised to use {@link #ARGB_8888} instead.
321676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         */
322676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        @Deprecated
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ARGB_4444   (5),
324676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy
325676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        /**
326676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * Each pixel is stored on 4 bytes. Each channel (RGB and alpha
327676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * for translucency) is stored with 8 bits of precision (256
328676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * possible values.)
329676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         *
330676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * This configuration is very flexible and offers the best
331676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * quality. It should be used whenever possible.
332676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         */
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ARGB_8888   (6);
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
335676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        final int nativeInt;
336676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy
337676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        @SuppressWarnings({"deprecation"})
338676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        private static Config sConfigs[] = {
339676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy            null, null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888
340676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        };
341676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Config(int ni) {
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.nativeInt = ni;
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3458cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
346676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        static Config nativeToConfig(int ni) {
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return sConfigs[ni];
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3508cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Copy the bitmap's pixels into the specified buffer (allocated by the
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * caller). An exception is thrown if the buffer is not large enough to
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * hold all of the pixels (taking into account the number of bytes per
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pixel) or if the Buffer subclass is not one of the support types
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (ByteBuffer, ShortBuffer, IntBuffer).
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void copyPixelsToBuffer(Buffer dst) {
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int elements = dst.remaining();
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int shift;
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dst instanceof ByteBuffer) {
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 0;
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (dst instanceof ShortBuffer) {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 1;
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (dst instanceof IntBuffer) {
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 2;
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("unsupported Buffer subclass");
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3708cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long bufferSize = (long)elements << shift;
372f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson        long pixelSize = getByteCount();
3738cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bufferSize < pixelSize) {
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("Buffer not large enough for pixels");
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3778cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nativeCopyPixelsToBuffer(mNativeBitmap, dst);
3798cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // now update the buffer's position
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int position = dst.position();
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        position += pixelSize >> shift;
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dst.position(position);
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Copy the pixels from the buffer, beginning at the current position,
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * overwriting the bitmap's pixels. The data in the buffer is not changed
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in any way (unlike setPixels(), which converts from unpremultipled 32bit
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to whatever the bitmap's native format is.
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void copyPixelsFromBuffer(Buffer src) {
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("copyPixelsFromBuffer called on recycled bitmap");
3948cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int elements = src.remaining();
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int shift;
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (src instanceof ByteBuffer) {
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 0;
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (src instanceof ShortBuffer) {
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 1;
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (src instanceof IntBuffer) {
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 2;
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("unsupported Buffer subclass");
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4068cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long bufferBytes = (long)elements << shift;
408f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson        long bitmapBytes = getByteCount();
4098cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bufferBytes < bitmapBytes) {
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("Buffer not large enough for pixels");
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4138cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nativeCopyPixelsFromBuffer(mNativeBitmap, src);
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4168cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Tries to make a new bitmap based on the dimensions of this bitmap,
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * setting the new bitmap's config to the one specified, and then copying
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this bitmap's pixels into the new bitmap. If the conversion is not
42196e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * supported, or the allocator fails, then this returns NULL.  The returned
42296e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * bitmap initially has the same density as the original.
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param config    The desired config for the resulting bitmap
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param isMutable True if the resulting bitmap should be mutable (i.e.
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                  its pixels can be modified)
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the new bitmap, or null if the copy could not be made.
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Bitmap copy(Config config, boolean isMutable) {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't copy a recycled bitmap");
43196e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        Bitmap b = nativeCopy(mNativeBitmap, config.nativeInt, isMutable);
43296e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        if (b != null) {
43396e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn            b.mDensity = mDensity;
43496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        }
43596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        return b;
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
43802d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick    /**
439f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * Creates a new bitmap, scaled from an existing bitmap, when possible. If the
440f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * specified width and height are the same as the current width and height of
441f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * the source btimap, the source bitmap is returned and now new bitmap is
442f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * created.
44302d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     *
44402d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     * @param src       The source bitmap.
44502d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     * @param dstWidth  The new bitmap's desired width.
44602d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     * @param dstHeight The new bitmap's desired height.
44702d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     * @param filter    true if the source should be filtered.
448f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * @return The new scaled bitmap or the source bitmap if no scaling is required.
44902d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     */
450f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy    public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight,
451f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy            boolean filter) {
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Matrix m;
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (Bitmap.class) {
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // small pool of just 1 matrix
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            m = sScaleMatrix;
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sScaleMatrix = null;
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (m == null) {
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            m = new Matrix();
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4628cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int width = src.getWidth();
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int height = src.getHeight();
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final float sx = dstWidth  / (float)width;
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final float sy = dstHeight / (float)height;
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        m.setScale(sx, sy);
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bitmap b = Bitmap.createBitmap(src, 0, 0, width, height, m, filter);
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (Bitmap.class) {
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // do we need to check for null? why not just assign everytime?
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (sScaleMatrix == null) {
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sScaleMatrix = m;
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4778cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen        return b;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4798cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an immutable bitmap from the source bitmap. The new bitmap may
48296e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * be the same object as source, or a copy may have been made.  It is
48396e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * initialized with the same density as the original bitmap.
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap createBitmap(Bitmap src) {
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return createBitmap(src, 0, 0, src.getWidth(), src.getHeight());
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an immutable bitmap from the specified subset of the source
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * bitmap. The new bitmap may be the same object as source, or a copy may
492f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * have been made. It is initialized with the same density as the original
493f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * bitmap.
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param source   The bitmap we are subsetting
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x        The x coordinate of the first pixel in source
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y        The y coordinate of the first pixel in source
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The number of pixels in each row
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The number of rows
500f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * @return A copy of a subset of the source bitmap or the source bitmap itself.
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height) {
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return createBitmap(source, x, y, width, height, null, false);
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5058cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an immutable bitmap from subset of the source bitmap,
508f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * transformed by the optional matrix. The new bitmap may be the
509f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * same object as source, or a copy may have been made. It is
51096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * initialized with the same density as the original bitmap.
511f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     *
512f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * If the source bitmap is immutable and the requested subset is the
513f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * same as the source bitmap itself, then the source bitmap is
514f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * returned and no new bitmap is created.
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param source   The bitmap we are subsetting
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x        The x coordinate of the first pixel in source
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y        The y coordinate of the first pixel in source
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The number of pixels in each row
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The number of rows
52160b88edea7132ddce90f2dced07c6706f1502270Ken Shirriff     * @param m        Optional matrix to be applied to the pixels
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param filter   true if the source should be filtered.
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   Only applies if the matrix contains more than just
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   translation.
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return A bitmap that represents the specified subset of source
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if the x, y, width, height values are
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         outside of the dimensions of the source bitmap.
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Matrix m, boolean filter) {
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkXYSign(x, y);
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkWidthHeight(width, height);
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (x + width > source.getWidth()) {
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("x + width must be <= bitmap.width()");
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (y + height > source.getHeight()) {
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("y + height must be <= bitmap.height()");
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // check if we can just return our argument unchanged
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                height == source.getHeight() && (m == null || m.isIdentity())) {
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return source;
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5468cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int neww = width;
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int newh = height;
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Canvas canvas = new Canvas();
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bitmap bitmap;
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint paint;
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Rect srcR = new Rect(x, y, x + width, y + height);
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RectF dstR = new RectF(0, 0, width, height);
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
556feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy        Config newConfig = Config.ARGB_8888;
557feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy        final Config config = source.getConfig();
558feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy        // GIF files generate null configs, assume ARGB_8888
559feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy        if (config != null) {
560feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy            switch (config) {
561feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                case RGB_565:
562feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    newConfig = Config.RGB_565;
563feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    break;
564feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                case ALPHA_8:
565feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    newConfig = Config.ALPHA_8;
566feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    break;
567676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy                //noinspection deprecation
568feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                case ARGB_4444:
569feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                case ARGB_8888:
570feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                default:
571feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    newConfig = Config.ARGB_8888;
572feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    break;
573feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy            }
574feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy        }
575d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (m == null || m.isIdentity()) {
577d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy            bitmap = createBitmap(neww, newh, newConfig, source.hasAlpha());
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            paint = null;   // not needed
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
580d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy            final boolean transformed = !m.rectStaysRect();
581d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            RectF deviceR = new RectF();
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            m.mapRect(deviceR, dstR);
584d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            neww = Math.round(deviceR.width());
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            newh = Math.round(deviceR.height());
587d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
588d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy            bitmap = createBitmap(neww, newh, transformed ? Config.ARGB_8888 : newConfig,
589d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy                    transformed || source.hasAlpha());
590d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas.translate(-deviceR.left, -deviceR.top);
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas.concat(m);
593d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            paint = new Paint();
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            paint.setFilterBitmap(filter);
596d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy            if (transformed) {
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                paint.setAntiAlias(true);
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
60096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The new bitmap was created from a known bitmap source so assume that
60211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        // they use the same density
60311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        bitmap.mDensity = source.mDensity;
60496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn
60596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        canvas.setBitmap(bitmap);
60696e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        canvas.drawBitmap(source, srcR, dstR, paint);
6076311d0a079702b29984c0d31937345be105e1a5eDianne Hackborn        canvas.setBitmap(null);
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bitmap;
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6118cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
61396e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * Returns a mutable bitmap with the specified width and height.  Its
61496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * initial density is as per {@link #getDensity}.
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The width of the bitmap
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The height of the bitmap
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param config   The bitmap config to create.
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if the width or height are <= 0
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap createBitmap(int width, int height, Config config) {
622d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy        return createBitmap(width, height, config, true);
623d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy    }
624d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
625d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy    /**
626d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     * Returns a mutable bitmap with the specified width and height.  Its
627d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     * initial density is as per {@link #getDensity}.
628d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     *
629d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     * @param width    The width of the bitmap
630d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     * @param height   The height of the bitmap
631d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     * @param config   The bitmap config to create.
632d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     * @param hasAlpha If the bitmap is ARGB_8888 this flag can be used to mark the
633d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     *                 bitmap as opaque. Doing so will clear the bitmap in black
634d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     *                 instead of transparent.
635d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     *
636d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     * @throws IllegalArgumentException if the width or height are <= 0
637d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     */
638d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy    private static Bitmap createBitmap(int width, int height, Config config, boolean hasAlpha) {
639e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        if (width <= 0 || height <= 0) {
640e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy            throw new IllegalArgumentException("width and height must be > 0");
641e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        }
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true);
643d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy        if (config == Config.ARGB_8888 && !hasAlpha) {
6441373a8eb581fe3c8e9a036e69042015f98a7e346Christopher Tate            nativeErase(bm.mNativeBitmap, 0xff000000);
645d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy            nativeSetHasAlpha(bm.mNativeBitmap, hasAlpha);
646d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy        } else {
6471373a8eb581fe3c8e9a036e69042015f98a7e346Christopher Tate            // No need to initialize it to zeroes; it is backed by a VM byte array
6481373a8eb581fe3c8e9a036e69042015f98a7e346Christopher Tate            // which is by definition preinitialized to all zeroes.
6491373a8eb581fe3c8e9a036e69042015f98a7e346Christopher Tate            //
6501373a8eb581fe3c8e9a036e69042015f98a7e346Christopher Tate            //nativeErase(bm.mNativeBitmap, 0);
651d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy        }
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bm;
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6548cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a immutable bitmap with the specified width and height, with each
65796e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * pixel value set to the corresponding value in the colors array.  Its
65896e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * initial density is as per {@link #getDensity}.
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param colors   Array of {@link Color} used to initialize the pixels.
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset   Number of values to skip before the first color in the
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 array of colors.
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stride   Number of colors in the array between rows (must be >=
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 width or <= -width).
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The width of the bitmap
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The height of the bitmap
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param config   The bitmap config to create. If the config does not
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 support per-pixel alpha (e.g. RGB_565), then the alpha
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 bytes in the colors[] will be ignored (assumed to be FF)
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if the width or height are <= 0, or if
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         the color array's length is less than the number of pixels.
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap createBitmap(int colors[], int offset, int stride,
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int width, int height, Config config) {
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkWidthHeight(width, height);
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Math.abs(stride) < width) {
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("abs(stride) must be >= width");
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int lastScanline = offset + (height - 1) * stride;
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int length = colors.length;
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (offset < 0 || (offset + width > length) || lastScanline < 0 ||
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (lastScanline + width > length)) {
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayIndexOutOfBoundsException();
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
686e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        if (width <= 0 || height <= 0) {
687e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy            throw new IllegalArgumentException("width and height must be > 0");
688e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        }
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return nativeCreate(colors, offset, stride, width, height,
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            config.nativeInt, false);
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a immutable bitmap with the specified width and height, with each
69596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * pixel value set to the corresponding value in the colors array.  Its
69696e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * initial density is as per {@link #getDensity}.
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param colors   Array of {@link Color} used to initialize the pixels.
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 This array must be at least as large as width * height.
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The width of the bitmap
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The height of the bitmap
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param config   The bitmap config to create. If the config does not
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 support per-pixel alpha (e.g. RGB_565), then the alpha
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 bytes in the colors[] will be ignored (assumed to be FF)
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if the width or height are <= 0, or if
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         the color array's length is less than the number of pixels.
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Bitmap createBitmap(int colors[], int width, int height, Config config) {
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return createBitmap(colors, 0, width, width, height, config);
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an optional array of private data, used by the UI system for
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * some bitmaps. Not intended to be called by applications.
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public byte[] getNinePatchChunk() {
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mNinePatchChunk;
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
721ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     * @hide
722ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     * @return the layout padding [left, right, top, bottom]
723ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     */
724ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    public int[] getLayoutBounds() {
725ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani        return mLayoutBounds;
726ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    }
727ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani
728ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    /**
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specifies the known formats a bitmap can be compressed into
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum CompressFormat {
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        JPEG    (0),
7332305ac9e4a262ed09fd034ae417e9b1dda4c0ccbVikas Arora        PNG     (1),
7342305ac9e4a262ed09fd034ae417e9b1dda4c0ccbVikas Arora        WEBP    (2);
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CompressFormat(int nativeInt) {
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.nativeInt = nativeInt;
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int nativeInt;
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Number of bytes of temp storage we use for communicating between the
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * native compressor and the java OutputStream.
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final static int WORKING_COMPRESS_STORAGE = 4096;
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Write a compressed version of the bitmap to the specified outputstream.
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If this returns true, the bitmap can be reconstructed by passing a
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corresponding inputstream to BitmapFactory.decodeStream(). Note: not
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * all Formats support all bitmap configs directly, so it is possible that
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the returned bitmap from BitmapFactory could be in a different bitdepth,
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and/or may have lost per-pixel alpha (e.g. JPEG only supports opaque
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pixels).
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param format   The format of the compressed image
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param quality  Hint to the compressor, 0-100. 0 meaning compress for
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 small size, 100 meaning compress for max quality. Some
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 formats, like PNG which is lossless, will ignore the
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 quality setting
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stream   The outputstream to write the compressed data.
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if successfully compressed to the specified stream.
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean compress(CompressFormat format, int quality, OutputStream stream) {
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't compress a recycled bitmap");
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // do explicit check before calling the native method
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (stream == null) {
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new NullPointerException();
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (quality < 0 || quality > 100) {
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("quality must be 0..100");
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return nativeCompress(mNativeBitmap, format.nativeInt, quality,
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              stream, new byte[WORKING_COMPRESS_STORAGE]);
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7778cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns true if the bitmap is marked as mutable (i.e. can be drawn into)
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean isMutable() {
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsMutable;
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Returns the bitmap's width */
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final int getWidth() {
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWidth == -1 ? mWidth = nativeWidth(mNativeBitmap) : mWidth;
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Returns the bitmap's height */
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final int getHeight() {
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mHeight == -1 ? mHeight = nativeHeight(mNativeBitmap) : mHeight;
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7948cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
79611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Convenience for calling {@link #getScaledWidth(int)} with the target
79711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * density of the given {@link Canvas}.
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7992784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    public int getScaledWidth(Canvas canvas) {
80011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getWidth(), mDensity, canvas.mDensity);
8012784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    }
8022784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn
8032784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    /**
80411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Convenience for calling {@link #getScaledHeight(int)} with the target
80511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * density of the given {@link Canvas}.
8062784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     */
8072784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    public int getScaledHeight(Canvas canvas) {
80811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getHeight(), mDensity, canvas.mDensity);
80911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    }
81011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
81111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    /**
81211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Convenience for calling {@link #getScaledWidth(int)} with the target
81311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * density of the given {@link DisplayMetrics}.
81411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     */
81511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getScaledWidth(DisplayMetrics metrics) {
81611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getWidth(), mDensity, metrics.densityDpi);
81711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    }
81811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
81911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    /**
82011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Convenience for calling {@link #getScaledHeight(int)} with the target
82111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * density of the given {@link DisplayMetrics}.
82211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     */
82311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getScaledHeight(DisplayMetrics metrics) {
82411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getHeight(), mDensity, metrics.densityDpi);
8252784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    }
8262784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn
8272784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    /**
8282784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     * Convenience method that returns the width of this bitmap divided
8292784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     * by the density scale factor.
8302784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     *
83111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @param targetDensity The density of the target canvas of the bitmap.
8322784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     * @return The scaled width of this bitmap, according to the density scale factor.
8332784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     */
83411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getScaledWidth(int targetDensity) {
83511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getWidth(), mDensity, targetDensity);
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Convenience method that returns the height of this bitmap divided
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the density scale factor.
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
84211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @param targetDensity The density of the target canvas of the bitmap.
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The scaled height of this bitmap, according to the density scale factor.
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
84511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getScaledHeight(int targetDensity) {
84611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getHeight(), mDensity, targetDensity);
84711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    }
84811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
84911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    /**
85011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @hide
85111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     */
85211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    static public int scaleFromDensity(int size, int sdensity, int tdensity) {
85311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        if (sdensity == DENSITY_NONE || sdensity == tdensity) {
85411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            return size;
8552784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn        }
85611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
85711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        // Scale by tdensity / sdensity, rounding up.
858366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy        return ((size * tdensity) + (sdensity >> 1)) / sdensity;
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
86011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the number of bytes between rows in the bitmap's pixels. Note that
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this refers to the pixels as stored natively by the bitmap. If you call
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * getPixels() or setPixels(), then the pixels are uniformly treated as
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * 32bit values, packed according to the Color class.
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return number of bytes between rows of the native bitmap pixels.
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final int getRowBytes() {
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return nativeRowBytes(mNativeBitmap);
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8728cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
874f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson     * Returns the number of bytes used to store this bitmap's pixels.
875f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson     */
876f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson    public final int getByteCount() {
877f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson        // int result permits bitmaps up to 46,340 x 46,340
878f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson        return getRowBytes() * getHeight();
879f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson    }
880f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson
881f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson    /**
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If the bitmap's internal config is in one of the public formats, return
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that config, otherwise return null.
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Config getConfig() {
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return Config.nativeToConfig(nativeConfig(mNativeBitmap));
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed    /** Returns true if the bitmap's config supports per-pixel alpha, and
890a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * if the pixels may contain non-opaque alpha values. For some configs,
891a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * this is always false (e.g. RGB_565), since they do not support per-pixel
892a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * alpha. However, for configs that do, the bitmap may be flagged to be
893a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * known that all of its pixels are opaque. In this case hasAlpha() will
894a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * also return false. If a config such as ARGB_8888 is not so flagged,
895a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * it will return true by default.
896a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     */
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean hasAlpha() {
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return nativeHasAlpha(mNativeBitmap);
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
902a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * Tell the bitmap if all of the pixels are known to be opaque (false)
903a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * or if some of the pixels may contain non-opaque alpha values (true).
904366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy     * Note, for some configs (e.g. RGB_565) this call is ignored, since it
905366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy     * does not support per-pixel alpha values.
906a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     *
907a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * This is meant as a drawing hint, as in some cases a bitmap that is known
908a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * to be opaque can take a faster drawing case than one that may have
909a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * non-opaque per-pixel alpha values.
910a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     */
911a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed    public void setHasAlpha(boolean hasAlpha) {
912a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed        nativeSetHasAlpha(mNativeBitmap, hasAlpha);
913a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed    }
914a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed
915a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed    /**
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Fills the bitmap's pixels with the specified {@link Color}.
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalStateException if the bitmap is not mutable.
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void eraseColor(int c) {
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't erase a recycled bitmap");
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isMutable()) {
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("cannot erase immutable bitmaps");
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nativeErase(mNativeBitmap, c);
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the {@link Color} at the specified location. Throws an exception
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if x or y are out of bounds (negative or >= to the width or height
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * respectively).
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x    The x coordinate (0...width-1) of the pixel to return
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y    The y coordinate (0...height-1) of the pixel to return
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return     The argb {@link Color} at the specified coordinate
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if x, y exceed the bitmap's bounds
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getPixel(int x, int y) {
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't call getPixel() on a recycled bitmap");
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPixelAccess(x, y);
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return nativeGetPixel(mNativeBitmap, x, y);
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9438cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns in pixels[] a copy of the data in the bitmap. Each value is
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a packed int representing a {@link Color}. The stride parameter allows
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the caller to allow for gaps in the returned pixels array between
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * rows. For normal packed results, just pass width for the stride value.
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pixels   The array to receive the bitmap's colors
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset   The first index to write into pixels[]
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stride   The number of entries in pixels[] to skip between
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 rows (must be >= bitmap's width). Can be negative.
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x        The x coordinate of the first pixel to read from
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the bitmap
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y        The y coordinate of the first pixel to read from
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the bitmap
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The number of pixels to read from each row
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The number of rows to read
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if x, y, width, height exceed the
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         bounds of the bitmap, or if abs(stride) < width.
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws ArrayIndexOutOfBoundsException if the pixels array is too small
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         to receive the specified number of pixels.
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void getPixels(int[] pixels, int offset, int stride,
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          int x, int y, int width, int height) {
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't call getPixels() on a recycled bitmap");
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width == 0 || height == 0) {
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return; // nothing to do
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPixelsAccess(x, y, width, height, offset, stride, pixels);
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nativeGetPixels(mNativeBitmap, pixels, offset, stride,
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x, y, width, height);
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9758cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shared code to check for illegal arguments passed to getPixel()
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or setPixel()
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x x coordinate of the pixel
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y y coordinate of the pixel
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void checkPixelAccess(int x, int y) {
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkXYSign(x, y);
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (x >= getWidth()) {
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("x must be < bitmap.width()");
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (y >= getHeight()) {
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("y must be < bitmap.height()");
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shared code to check for illegal arguments passed to getPixels()
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or setPixels()
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x left edge of the area of pixels to access
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y top edge of the area of pixels to access
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width width of the area of pixels to access
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height height of the area of pixels to access
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset offset into pixels[] array
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stride number of elements in pixels[] between each logical row
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pixels array to hold the area of pixels being accessed
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    */
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void checkPixelsAccess(int x, int y, int width, int height,
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   int offset, int stride, int pixels[]) {
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkXYSign(x, y);
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width < 0) {
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("width must be >= 0");
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height < 0) {
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("height must be >= 0");
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (x + width > getWidth()) {
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "x + width must be <= bitmap.width()");
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (y + height > getHeight()) {
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "y + height must be <= bitmap.height()");
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Math.abs(stride) < width) {
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("abs(stride) must be >= width");
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int lastScanline = offset + (height - 1) * stride;
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int length = pixels.length;
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (offset < 0 || (offset + width > length)
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || lastScanline < 0
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || (lastScanline + width > length)) {
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayIndexOutOfBoundsException();
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10328cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Write the specified {@link Color} into the bitmap (assuming it is
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * mutable) at the x,y coordinate.
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x     The x coordinate of the pixel to replace (0...width-1)
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y     The y coordinate of the pixel to replace (0...height-1)
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param color The {@link Color} to write into the bitmap
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalStateException if the bitmap is not mutable
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if x, y are outside of the bitmap's
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         bounds.
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setPixel(int x, int y, int color) {
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't call setPixel() on a recycled bitmap");
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isMutable()) {
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException();
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPixelAccess(x, y);
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nativeSetPixel(mNativeBitmap, x, y, color);
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10528cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Replace pixels in the bitmap with the colors in the array. Each element
10558cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     * in the array is a packed int prepresenting a {@link Color}
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pixels   The colors to write to the bitmap
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset   The index of the first color to read from pixels[]
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stride   The number of colors in pixels[] to skip between rows.
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 Normally this value will be the same as the width of
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the bitmap, but it can be larger (or negative).
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x        The x coordinate of the first pixel to write to in
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the bitmap.
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y        The y coordinate of the first pixel to write to in
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the bitmap.
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The number of colors to copy from pixels[] per row
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The number of rows to write to the bitmap
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalStateException if the bitmap is not mutable
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if x, y, width, height are outside of
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         the bitmap's bounds.
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws ArrayIndexOutOfBoundsException if the pixels array is too small
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         to receive the specified number of pixels.
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setPixels(int[] pixels, int offset, int stride,
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          int x, int y, int width, int height) {
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't call setPixels() on a recycled bitmap");
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isMutable()) {
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException();
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width == 0 || height == 0) {
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return; // nothing to do
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPixelsAccess(x, y, width, height, offset, stride, pixels);
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nativeSetPixels(mNativeBitmap, pixels, offset, stride,
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        x, y, width, height);
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10878cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final Parcelable.Creator<Bitmap> CREATOR
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            = new Parcelable.Creator<Bitmap>() {
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Rebuilds a bitmap previously stored with writeToParcel().
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param p    Parcel object to read the bitmap from
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return a new bitmap created from the data in the parcel
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Bitmap createFromParcel(Parcel p) {
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Bitmap bm = nativeCreateFromParcel(p);
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (bm == null) {
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new RuntimeException("Failed to unparcel Bitmap");
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return bm;
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Bitmap[] newArray(int size) {
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new Bitmap[size];
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * No special parcel contents.
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int describeContents() {
1112b6377170960d40e66858d8b4d335a95eac773762Bart Sears        return 0;
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Write the bitmap and its pixels to the parcel. The bitmap can be
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * rebuilt from the parcel by calling CREATOR.createFromParcel().
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p    Parcel object to write the bitmap data into
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void writeToParcel(Parcel p, int flags) {
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't parcel a recycled bitmap");
1122de0dfb7b65a02d4dd74c271b558adee0973fc267Dianne Hackborn        if (!nativeWriteToParcel(mNativeBitmap, mIsMutable, mDensity, p)) {
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("native writeToParcel failed");
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a new bitmap that captures the alpha values of the original.
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This may be drawn with Canvas.drawBitmap(), where the color(s) will be
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * taken from the paint that is passed to the draw call.
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return new bitmap containing the alpha channel of the original bitmap.
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Bitmap extractAlpha() {
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return extractAlpha(null, null);
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11378cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a new bitmap that captures the alpha values of the original.
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * These values may be affected by the optional Paint parameter, which
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can contain its own alpha, and may also contain a MaskFilter which
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * could change the actual dimensions of the resulting bitmap (e.g.
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a blur maskfilter might enlarge the resulting bitmap). If offsetXY
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is not null, it returns the amount to offset the returned bitmap so
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that it will logically align with the original. For example, if the
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * paint contains a blur of radius 2, then offsetXY[] would contains
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * -2, -2, so that drawing the alpha bitmap offset by (-2, -2) and then
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * drawing the original would result in the blur visually aligning with
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the original.
115096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     *
115196e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * <p>The initial density of the returned bitmap is the same as the original's.
115296e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     *
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint Optional paint used to modify the alpha values in the
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              resulting bitmap. Pass null for default behavior.
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offsetXY Optional array that returns the X (index 0) and Y
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 (index 1) offset needed to position the returned bitmap
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 so that it visually lines up with the original.
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return new bitmap containing the (optionally modified by paint) alpha
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         channel of the original bitmap. This may be drawn with
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         Canvas.drawBitmap(), where the color(s) will be taken from the
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         paint that is passed to the draw call.
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Bitmap extractAlpha(Paint paint, int[] offsetXY) {
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't extractAlpha on a recycled bitmap");
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int nativePaint = paint != null ? paint.mNativePaint : 0;
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bitmap bm = nativeExtractAlpha(mNativeBitmap, nativePaint, offsetXY);
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bm == null) {
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("Failed to extractAlpha on Bitmap");
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
117096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        bm.mDensity = mDensity;
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bm;
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11748cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen    /**
117576d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed     *  Given another bitmap, return true if it has the same dimensions, config,
117676d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed     *  and pixel data as this bitmap. If any of those differ, return false.
117776d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed     *  If other is null, return false.
117876d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed     */
117976d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed    public boolean sameAs(Bitmap other) {
1180366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy        return this == other || (other != null && nativeSameAs(mNativeBitmap, other.mNativeBitmap));
118176d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed    }
118276d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed
118376d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed    /**
11848cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     * Rebuilds any caches associated with the bitmap that are used for
11858cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     * drawing it. In the case of purgeable bitmaps, this call will attempt to
11868cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     * ensure that the pixels have been decoded.
11878cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     * If this is called on more than one bitmap in sequence, the priority is
11888cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     * given in LRU order (i.e. the last bitmap called will be given highest
11898cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     * priority).
11908cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     *
11918cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     * For bitmaps with no associated caches, this call is effectively a no-op,
11928cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     * and therefore is harmless.
11938cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     */
11948cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen    public void prepareToDraw() {
11958cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen        nativePrepareToDraw(mNativeBitmap);
11968cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen    }
11978cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
1198e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy    private static class BitmapFinalizer {
1199e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        private final int mNativeBitmap;
120002890fd0f98b3b8d98baf0bda1ea906afd723d8bRomain Guy
1201e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        BitmapFinalizer(int nativeBitmap) {
1202e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy            mNativeBitmap = nativeBitmap;
120302890fd0f98b3b8d98baf0bda1ea906afd723d8bRomain Guy        }
120402890fd0f98b3b8d98baf0bda1ea906afd723d8bRomain Guy
120502890fd0f98b3b8d98baf0bda1ea906afd723d8bRomain Guy        @Override
1206e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        public void finalize() {
1207366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy            try {
1208366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy                super.finalize();
1209366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy            } catch (Throwable t) {
1210366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy                // Ignore
1211366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy            } finally {
1212366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy                nativeDestructor(mNativeBitmap);
1213366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy            }
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12168cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //////////// native methods
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeCreate(int[] colors, int offset,
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                              int stride, int width, int height,
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            int nativeConfig, boolean mutable);
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeCopy(int srcBitmap, int nativeConfig,
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            boolean isMutable);
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeDestructor(int nativeBitmap);
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeRecycle(int nativeBitmap);
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native boolean nativeCompress(int nativeBitmap, int format,
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            int quality, OutputStream stream,
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            byte[] tempStorage);
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeErase(int nativeBitmap, int color);
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native int nativeWidth(int nativeBitmap);
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native int nativeHeight(int nativeBitmap);
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native int nativeRowBytes(int nativeBitmap);
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native int nativeConfig(int nativeBitmap);
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native boolean nativeHasAlpha(int nativeBitmap);
12368cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native int nativeGetPixel(int nativeBitmap, int x, int y);
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeGetPixels(int nativeBitmap, int[] pixels,
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               int offset, int stride, int x,
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               int y, int width, int height);
12418cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeSetPixel(int nativeBitmap, int x, int y,
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                              int color);
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeSetPixels(int nativeBitmap, int[] colors,
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               int offset, int stride, int x,
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                               int y, int width, int height);
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeCopyPixelsToBuffer(int nativeBitmap,
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                        Buffer dst);
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native void nativeCopyPixelsFromBuffer(int nb, Buffer src);
12500bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy    private static native int nativeGenerationId(int nativeBitmap);
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeCreateFromParcel(Parcel p);
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // returns true on success
12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native boolean nativeWriteToParcel(int nativeBitmap,
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                      boolean isMutable,
1256de0dfb7b65a02d4dd74c271b558adee0973fc267Dianne Hackborn                                                      int density,
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                      Parcel p);
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // returns a new bitmap built from the native bitmap's alpha, and the paint
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeExtractAlpha(int nativeBitmap,
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    int nativePaint,
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    int[] offsetXY);
12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12638cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen    private static native void nativePrepareToDraw(int nativeBitmap);
1264a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed    private static native void nativeSetHasAlpha(int nBitmap, boolean hasAlpha);
126576d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed    private static native boolean nativeSameAs(int nb0, int nb1);
1266d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* package */ final int ni() {
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mNativeBitmap;
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1271