Bitmap.java revision 1480b67635cdc4c2c5e735741bf30393fd70d738
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
191c2bf03d1082fc6b7eb42cbd163c60c07cf2bcccTor Norbyeimport android.annotation.CheckResult;
2080756e38882720860db52f1fcc21fa1505a02abfTor Norbyeimport android.annotation.ColorInt;
21c054966b719c8a7255f7cf4120cca5050acb68bdAlan Viveretteimport android.annotation.NonNull;
22efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guyimport android.annotation.Nullable;
238242656f495847c50c9ceaea92839dce78218a75Romain Guyimport android.annotation.Size;
241480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onukiimport android.content.res.ResourcesImpl;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
268cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chenimport android.os.Parcelable;
279fd259c9b0878ba52fec86173d76976e70977fcdsergeyvimport android.os.StrictMode;
280df3bd5594bbbbfbf6058ecb31e9b94a1cd22f7dJohn Reckimport android.os.Trace;
292784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackbornimport android.util.DisplayMetrics;
3001a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reckimport android.util.Log;
31a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winsonimport libcore.util.NativeAllocationRegistry;
32a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson
338cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chenimport java.io.OutputStream;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.nio.Buffer;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.nio.ByteBuffer;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.nio.IntBuffer;
378cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chenimport java.nio.ShortBuffer;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class Bitmap implements Parcelable {
4001a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck    private static final String TAG = "Bitmap";
4101a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates that the bitmap was created for an unknown pixel density.
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see Bitmap#getDensity()
4611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see Bitmap#setDensity(int)
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public static final int DENSITY_NONE = 0;
49f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck
50775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler    // Estimated size of the Bitmap native allocation, not including
51775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler    // pixel data.
52775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler    private static final long NATIVE_ALLOCATION_SIZE = 32;
53775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler
54f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    // Convenience for JNI access
55f29ed28c7b878ef28058bc730715d0d32445bc57John Reck    private final long mNativePtr;
56e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final boolean mIsMutable;
581abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik
591abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik    /**
6057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III     * Represents whether the Bitmap's content is requested to be pre-multiplied.
611abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * Note that isPremultiplied() does not directly return this value, because
6257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III     * isPremultiplied() may never return true for a 565 Bitmap or a bitmap
6357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III     * without alpha.
641abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     *
651abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * setPremultiplied() does directly set the value so that setConfig() and
661abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * setPremultiplied() aren't order dependent, despite being setters.
6757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III     *
6857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III     * The native bitmap's premultiplication state is kept up to date by
6957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III     * pushing down this preference for every config change.
701abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     */
7157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    private boolean mRequestPremultiplied;
728790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III
7347cd8e921db73e894f94ec4729ade90da50996f5Chris Craik    private byte[] mNinePatchChunk; // may be null
7447cd8e921db73e894f94ec4729ade90da50996f5Chris Craik    private NinePatch.InsetStruct mNinePatchInsets; // may be null
751abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik    private int mWidth;
761abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik    private int mHeight;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mRecycled;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
79efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy    private ColorSpace mColorSpace;
80efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy
81caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    /** @hide */
82caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    public int mDensity = getDefaultDensity();
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    private static volatile int sDefaultDensity = -1;
8502890fd0f98b3b8d98baf0bda1ea906afd723d8bRomain Guy
861480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onuki    /** @hide Used only when ResourcesImpl.TRACE_FOR_DETAILED_PRELOAD is true. */
871480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onuki    public static volatile int sPreloadTracingNumInstantiatedBitmaps;
881480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onuki
891480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onuki    /** @hide Used only when ResourcesImpl.TRACE_FOR_DETAILED_PRELOAD is true. */
901480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onuki    public static volatile long sPreloadTracingTotalBitmapsSize;
911480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onuki
9296e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    /**
9396e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * For backwards compatibility, allows the app layer to change the default
9496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * density when running old apps.
9596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * @hide
9696e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     */
9796e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    public static void setDefaultDensity(int density) {
9896e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        sDefaultDensity = density;
9996e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    }
1003849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy
101f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck    @SuppressWarnings("deprecation")
1023849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy    static int getDefaultDensity() {
10396e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        if (sDefaultDensity >= 0) {
10496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn            return sDefaultDensity;
10596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        }
10696e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        sDefaultDensity = DisplayMetrics.DENSITY_DEVICE;
10796e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        return sDefaultDensity;
10896e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn    }
109dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1119f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     * Private constructor that must received an already allocated native bitmap
1129f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     * int (pointer).
113ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     */
114f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck    // called from JNI
1154508218850faedea95371188da587b6734f5f3dasergeyv    Bitmap(long nativeBitmap, int width, int height, int density,
11657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III            boolean isMutable, boolean requestPremultiplied,
11747cd8e921db73e894f94ec4729ade90da50996f5Chris Craik            byte[] ninePatchChunk, NinePatch.InsetStruct ninePatchInsets) {
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (nativeBitmap == 0) {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("internal error: native bitmap is 0");
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1218cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
1221abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        mWidth = width;
1231abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        mHeight = height;
1241abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        mIsMutable = isMutable;
12557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III        mRequestPremultiplied = requestPremultiplied;
1264cd7dbc90f93893f521dce32d8cd25c02a185a24Chris Craik
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNinePatchChunk = ninePatchChunk;
12847cd8e921db73e894f94ec4729ade90da50996f5Chris Craik        mNinePatchInsets = ninePatchInsets;
129de0dfb7b65a02d4dd74c271b558adee0973fc267Dianne Hackborn        if (density >= 0) {
130de0dfb7b65a02d4dd74c271b558adee0973fc267Dianne Hackborn            mDensity = density;
131de0dfb7b65a02d4dd74c271b558adee0973fc267Dianne Hackborn        }
1324cd7dbc90f93893f521dce32d8cd25c02a185a24Chris Craik
133f29ed28c7b878ef28058bc730715d0d32445bc57John Reck        mNativePtr = nativeBitmap;
1344508218850faedea95371188da587b6734f5f3dasergeyv        long nativeSize = NATIVE_ALLOCATION_SIZE + getAllocationByteCount();
135775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        NativeAllocationRegistry registry = new NativeAllocationRegistry(
1360ebdbb4a8470bb77f38c33a42c220ecb8a7adcc6Richard Uhler            Bitmap.class.getClassLoader(), nativeGetNativeFinalizer(), nativeSize);
137775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        registry.registerNativeAllocation(this, nativeBitmap);
1381480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onuki
1391480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onuki        if (ResourcesImpl.TRACE_FOR_DETAILED_PRELOAD) {
1401480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onuki            sPreloadTracingNumInstantiatedBitmaps++;
1411480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onuki            sPreloadTracingTotalBitmapsSize += nativeSize;
1421480b67635cdc4c2c5e735741bf30393fd70d738Makoto Onuki        }
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1464c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger     * Return the pointer to the native object.
147caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck     * @hide
1484c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger     */
149caa08ff5e9ee004634a95776fc72bb769f1286deJohn Reck    public long getNativeInstance() {
1504c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger        return mNativePtr;
1514c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    }
1524c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger
1534c5efe9290543b723b76a8bd48518da1ae1dcb26Derek Sollenberger    /**
1541abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * Native bitmap has been reconfigured, so set premult and cached
1551abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * width/height values
1569f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     */
1579505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    @SuppressWarnings("unused") // called from JNI
15857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    void reinit(int width, int height, boolean requestPremultiplied) {
1591abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        mWidth = width;
1601abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        mHeight = height;
16157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III        mRequestPremultiplied = requestPremultiplied;
1625acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy        mColorSpace = null;
1639f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik    }
1649f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik
1659f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik    /**
16611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * <p>Returns the density for this bitmap.</p>
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16896e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * <p>The default density is the same density as the current display,
16996e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * unless the current application does not support different screen
17096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * densities in which case it is
17196e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * {@link android.util.DisplayMetrics#DENSITY_DEFAULT}.  Note that
17296e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * compatibility mode is determined by the application that was initially
17396e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * loaded into a process -- applications that share the same process should
17496e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * all have the same compatibility, or ensure they explicitly set the
17596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * density of their bitmaps appropriately.</p>
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
17796e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * @return A scaling factor of the default density or {@link #DENSITY_NONE}
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         if the scaling factor is unknown.
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see #setDensity(int)
181a53b828635fce8b6b2d3e3377d74d72070056623Dianne Hackborn     * @see android.util.DisplayMetrics#DENSITY_DEFAULT
18211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see android.util.DisplayMetrics#densityDpi
18311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see #DENSITY_NONE
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getDensity() {
18601a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        if (mRecycled) {
18701a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck            Log.w(TAG, "Called getDensity() on a recycle()'d bitmap! This is undefined behavior!");
18801a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        }
18911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return mDensity;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * <p>Specifies the density for this bitmap.  When the bitmap is
19411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * drawn to a Canvas that also has a density, it will be scaled
19511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * appropriately.</p>
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
19711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @param density The density scaling factor to use with this bitmap or
19811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     *        {@link #DENSITY_NONE} if the density is unknown.
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
20011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see #getDensity()
201a53b828635fce8b6b2d3e3377d74d72070056623Dianne Hackborn     * @see android.util.DisplayMetrics#DENSITY_DEFAULT
20211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see android.util.DisplayMetrics#densityDpi
20311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @see #DENSITY_NONE
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public void setDensity(int density) {
20611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        mDensity = density;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
208c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik
209c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    /**
210c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * <p>Modifies the bitmap to have a specified width, height, and {@link
211c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * Config}, without affecting the underlying allocation backing the bitmap.
212c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * Bitmap pixel data is not re-initialized for the new configuration.</p>
213c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     *
214c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * <p>This method can be used to avoid allocating a new bitmap, instead
215c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * reusing an existing bitmap's allocation for a new configuration of equal
216c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * or lesser size. If the Bitmap's allocation isn't large enough to support
217c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * the new configuration, an IllegalArgumentException will be thrown and the
218c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * bitmap will not be modified.</p>
219c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     *
220c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * <p>The result of {@link #getByteCount()} will reflect the new configuration,
221c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * while {@link #getAllocationByteCount()} will reflect that of the initial
222c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * configuration.</p>
223c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     *
22417a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III     * <p>Note: This may change this result of hasAlpha(). When converting to 565,
22517a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III     * the new bitmap will always be considered opaque. When converting from 565,
22617a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III     * the new bitmap will be considered non-opaque, and will respect the value
22717a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III     * set by setPremultiplied().</p>
22817a8bfc38a565ae96f43d36b223779be840bb50cLeon Scroggins III     *
2296d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * <p>WARNING: This method should NOT be called on a bitmap currently in use
2306d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * by the view system, Canvas, or the AndroidBitmap NDK API. It does not
2316d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * make guarantees about how the underlying pixel buffer is remapped to the
2326d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * new config, just that the allocation is reused. Additionally, the view
2336d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * system does not account for bitmap properties being modifying during use,
2346d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * e.g. while attached to drawables.</p>
2356d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     *
2366d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * <p>In order to safely ensure that a Bitmap is no longer in use by the
2376d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * View system it is necessary to wait for a draw pass to occur after
2386d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * invalidate()'ing any view that had previously drawn the Bitmap in the last
2396d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * draw pass due to hardware acceleration's caching of draw commands. As
2406d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * an example, here is how this can be done for an ImageView:
2416d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * <pre class="prettyprint">
2426d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     *      ImageView myImageView = ...;
2436d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     *      final Bitmap myBitmap = ...;
2446d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     *      myImageView.setImageDrawable(null);
2456d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     *      myImageView.post(new Runnable() {
2466d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     *          public void run() {
2476d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     *              // myBitmap is now no longer in use by the ImageView
2486d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     *              // and can be safely reconfigured.
2496d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     *              myBitmap.reconfigure(...);
2506d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     *          }
2516d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     *      });
2526d86e57bdadd56be160eb3e543cc53622cae46f2John Reck     * </pre></p>
253c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     *
254c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #setWidth(int)
255c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #setHeight(int)
256c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #setConfig(Config)
257c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     */
258c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    public void reconfigure(int width, int height, Config config) {
259c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik        checkRecycled("Can't call reconfigure() on a recycled bitmap");
260c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik        if (width <= 0 || height <= 0) {
261c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik            throw new IllegalArgumentException("width and height must be > 0");
262c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik        }
263c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik        if (!isMutable()) {
2649c2cde0583d02ba7551877dbe7a5ecaee6defb56Chris Craik            throw new IllegalStateException("only mutable bitmaps may be reconfigured");
265c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik        }
266c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik
2674508218850faedea95371188da587b6734f5f3dasergeyv        nativeReconfigure(mNativePtr, width, height, config.nativeInt, mRequestPremultiplied);
268c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik        mWidth = width;
269c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik        mHeight = height;
2705acc476878bce8b72c0059e05cbbd5b43ffee5d5Romain Guy        mColorSpace = null;
271c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    }
272c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik
273c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    /**
274c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
275c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * with the current height and config.</p>
276c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     *
277c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * <p>WARNING: this method should not be used on bitmaps currently used by
278c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * the view system, see {@link #reconfigure(int, int, Config)} for more
279c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * details.</p>
280c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     *
281c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #reconfigure(int, int, Config)
282c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #setHeight(int)
283c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #setConfig(Config)
284c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     */
285c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    public void setWidth(int width) {
286c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik        reconfigure(width, getHeight(), getConfig());
287c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    }
288c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik
289c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    /**
290c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
291c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * with the current width and config.</p>
292c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     *
293c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * <p>WARNING: this method should not be used on bitmaps currently used by
294c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * the view system, see {@link #reconfigure(int, int, Config)} for more
295c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * details.</p>
296c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     *
297c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #reconfigure(int, int, Config)
298c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #setWidth(int)
299c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #setConfig(Config)
300c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     */
301c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    public void setHeight(int height) {
302c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik        reconfigure(getWidth(), height, getConfig());
303c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    }
304c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik
305c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    /**
306c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
307c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * with the current height and width.</p>
308c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     *
309c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * <p>WARNING: this method should not be used on bitmaps currently used by
310c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * the view system, see {@link #reconfigure(int, int, Config)} for more
311c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * details.</p>
312c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     *
313c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #reconfigure(int, int, Config)
314c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #setWidth(int)
315c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #setHeight(int)
316c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     */
317c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    public void setConfig(Config config) {
318c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik        reconfigure(getWidth(), getHeight(), config);
319c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik    }
320c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the nine patch chunk.
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param chunk The definition of the nine patch
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setNinePatchChunk(byte[] chunk) {
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNinePatchChunk = chunk;
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3318cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
333a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * Free the native object associated with this bitmap, and clear the
334a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * reference to the pixel data. This will not free the pixel data synchronously;
335a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * it simply allows it to be garbage collected if there are no other references.
336a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * The bitmap is marked as "dead", meaning it will throw an exception if
337a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * getPixels() or setPixels() is called, and will draw nothing. This operation
338a383b3f646cbc1fd870f2694d4fac24340834916Patrick Dubroy     * cannot be reversed, so it should only be called if you are sure there are no
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * further uses for the bitmap. This is an advanced call, and normally need
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not be called, since the normal GC process will free up this memory when
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * there are no more references to this bitmap.
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void recycle() {
344775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        if (!mRecycled && mNativePtr != 0) {
345775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler            if (nativeRecycle(mNativePtr)) {
346547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase                // return value indicates whether native pixel object was actually recycled.
347547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase                // false indicates that it is still in use at the native level and these
348547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase                // objects should not be collected now. They will be collected later when the
349547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase                // Bitmap itself is collected.
350547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase                mNinePatchChunk = null;
351547e66531d521eb1eadac87edb0f79f8c2f1bbe0Chet Haase            }
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRecycled = true;
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns true if this bitmap has been recycled. If so, then it is an error
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to try to access its pixels, and the bitmap will not draw.
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the bitmap has been recycled
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean isRecycled() {
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mRecycled;
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3658cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3670bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy     * Returns the generation ID of this bitmap. The generation ID changes
3680bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy     * whenever the bitmap is modified. This can be used as an efficient way to
3690bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy     * check if a bitmap has changed.
370f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
3710bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy     * @return The current generation ID for this bitmap.
3720bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy     */
3730bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy    public int getGenerationId() {
37401a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        if (mRecycled) {
37501a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck            Log.w(TAG, "Called getGenerationId() on a recycle()'d bitmap! This is undefined behavior!");
37601a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        }
377775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        return nativeGenerationId(mNativePtr);
3780bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy    }
379f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck
3800bbae0836426ba2704e38e7f90a9d0ca502ab71dRomain Guy    /**
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called by methods that want to throw an exception if the bitmap
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * has already been recycled.
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void checkRecycled(String errorMessage) {
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mRecycled) {
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException(errorMessage);
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3898cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
391980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv     * This is called by methods that want to throw an exception if the bitmap
392980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv     * is {@link Config#HARDWARE}.
393980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv     */
394980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv    private void checkHardware(String errorMessage) {
395980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv        if (getConfig() == Config.HARDWARE) {
396980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv            throw new IllegalStateException(errorMessage);
397980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv        }
398980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv    }
399980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv
400980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv    /**
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Common code for checking that x and y are >= 0
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x x coordinate to ensure is >= 0
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y y coordinate to ensure is >= 0
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void checkXYSign(int x, int y) {
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (x < 0) {
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("x must be >= 0");
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (y < 0) {
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("y must be >= 0");
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Common code for checking that width and height are > 0
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width  width to ensure is > 0
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height height to ensure is > 0
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void checkWidthHeight(int width, int height) {
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width <= 0) {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("width must be > 0");
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height <= 0) {
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("height must be > 0");
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
430676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy    /**
431676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy     * Possible bitmap configurations. A bitmap configuration describes
432676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy     * how pixels are stored. This affects the quality (color depth) as
433676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy     * well as the ability to display transparent/translucent colors.
434676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy     */
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum Config {
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // these native values must match up with the enum in SkBitmap.h
437676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy
438676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        /**
439676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * Each pixel is stored as a single translucency (alpha) channel.
440676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * This is very useful to efficiently store masks for instance.
441676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * No color information is stored.
442676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * With this configuration, each pixel requires 1 byte of memory.
443676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         */
444b644a3b84521e2155a5af985a4d4ed305474e567Derek Sollenberger        ALPHA_8     (1),
445676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy
446676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        /**
447676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * Each pixel is stored on 2 bytes and only the RGB channels are
448676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * encoded: red is stored with 5 bits of precision (32 possible
449676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * values), green is stored with 6 bits of precision (64 possible
450676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * values) and blue is stored with 5 bits of precision.
451f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck         *
452676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * This configuration can produce slight visual artifacts depending
453676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * on the configuration of the source. For instance, without
454676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * dithering, the result might show a greenish tint. To get better
455676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * results dithering should be applied.
456f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck         *
457676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * This configuration may be useful when using opaque bitmaps
458676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * that do not require high color fidelity.
459676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         */
460b644a3b84521e2155a5af985a4d4ed305474e567Derek Sollenberger        RGB_565     (3),
461676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy
462676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        /**
463676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * Each pixel is stored on 2 bytes. The three RGB color channels
464676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * and the alpha channel (translucency) are stored with a 4 bits
465676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * precision (16 possible values.)
466f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck         *
467676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * This configuration is mostly useful if the application needs
468676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * to store translucency information but also needs to save
469676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * memory.
470f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck         *
471676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * It is recommended to use {@link #ARGB_8888} instead of this
472676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * configuration.
47325ba1c86945a441428194d9ebcabbf31be75a45aRomain Guy         *
474e8222dddaf2e3da14380101e818d4254899e0c0dChet Haase         * Note: as of {@link android.os.Build.VERSION_CODES#KITKAT},
47525ba1c86945a441428194d9ebcabbf31be75a45aRomain Guy         * any bitmap created with this configuration will be created
47625ba1c86945a441428194d9ebcabbf31be75a45aRomain Guy         * using {@link #ARGB_8888} instead.
477f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck         *
478676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * @deprecated Because of the poor quality of this configuration,
479676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         *             it is advised to use {@link #ARGB_8888} instead.
480676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         */
481676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        @Deprecated
482b644a3b84521e2155a5af985a4d4ed305474e567Derek Sollenberger        ARGB_4444   (4),
483676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy
484676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        /**
485676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * Each pixel is stored on 4 bytes. Each channel (RGB and alpha
486676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * for translucency) is stored with 8 bits of precision (256
487676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * possible values.)
488f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck         *
489676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * This configuration is very flexible and offers the best
490676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         * quality. It should be used whenever possible.
491676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy         */
492da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv        ARGB_8888   (5),
493da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv
4949505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        /**
4959505a6552764461c22ce48f1ac13d025d23e1579Romain Guy         * Each pixels is stored on 8 bytes. Each channel (RGB and alpha
4969505a6552764461c22ce48f1ac13d025d23e1579Romain Guy         * for translucency) is stored as a
4979505a6552764461c22ce48f1ac13d025d23e1579Romain Guy         * {@link android.util.Half half-precision floating point value}.
4989505a6552764461c22ce48f1ac13d025d23e1579Romain Guy         *
4999505a6552764461c22ce48f1ac13d025d23e1579Romain Guy         * This configuration is particularly suited for wide-gamut and
5009505a6552764461c22ce48f1ac13d025d23e1579Romain Guy         * HDR content.
5019505a6552764461c22ce48f1ac13d025d23e1579Romain Guy         */
5029505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        RGBA_F16    (6),
503da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv
504da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv        /**
5059fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv         * Special configuration, when bitmap is stored only in graphic memory.
5069fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv         * Bitmaps in this configuration are always immutable.
5079fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv         *
5089fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv         * It is optimal for cases, when the only operation with the bitmap is to draw it on a
5099fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv         * screen.
510da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv         */
5119505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        HARDWARE    (7);
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
513676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        final int nativeInt;
514676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy
515676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        private static Config sConfigs[] = {
5169505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888, RGBA_F16, HARDWARE
517676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        };
518f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Config(int ni) {
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.nativeInt = ni;
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5228cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
523676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy        static Config nativeToConfig(int ni) {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return sConfigs[ni];
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5278cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5293849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * <p>Copy the bitmap's pixels into the specified buffer (allocated by the
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * caller). An exception is thrown if the buffer is not large enough to
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * hold all of the pixels (taking into account the number of bytes per
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pixel) or if the Buffer subclass is not one of the support types
5333849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * (ByteBuffer, ShortBuffer, IntBuffer).</p>
5343849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * <p>The content of the bitmap is copied into the buffer as-is. This means
5353849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * that if this bitmap stores its pixels pre-multiplied
5363849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * (see {@link #isPremultiplied()}, the values in the buffer will also be
537ce217faddb4b40c1b3e698944da1951027080427Romain Guy     * pre-multiplied. The pixels remain in the color space of the bitmap.</p>
5381f58497e7dbab1b16e97c73b65559b852d0c2803Romain Guy     * <p>After this method returns, the current position of the buffer is
5391f58497e7dbab1b16e97c73b65559b852d0c2803Romain Guy     * updated: the position is incremented by the number of elements written
5401f58497e7dbab1b16e97c73b65559b852d0c2803Romain Guy     * in the buffer.</p>
541980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv     * @throws IllegalStateException if the bitmap's config is {@link Config#HARDWARE}
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void copyPixelsToBuffer(Buffer dst) {
544980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv        checkHardware("unable to copyPixelsToBuffer, "
545980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv                + "pixel access is not supported on Config#HARDWARE bitmaps");
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int elements = dst.remaining();
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int shift;
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dst instanceof ByteBuffer) {
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 0;
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (dst instanceof ShortBuffer) {
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 1;
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (dst instanceof IntBuffer) {
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 2;
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("unsupported Buffer subclass");
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5578cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long bufferSize = (long)elements << shift;
559f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson        long pixelSize = getByteCount();
5608cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bufferSize < pixelSize) {
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("Buffer not large enough for pixels");
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5648cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
565775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        nativeCopyPixelsToBuffer(mNativePtr, dst);
5668cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // now update the buffer's position
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int position = dst.position();
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        position += pixelSize >> shift;
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dst.position(position);
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5743849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * <p>Copy the pixels from the buffer, beginning at the current position,
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * overwriting the bitmap's pixels. The data in the buffer is not changed
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in any way (unlike setPixels(), which converts from unpremultipled 32bit
577ce217faddb4b40c1b3e698944da1951027080427Romain Guy     * to whatever the bitmap's native format is. The pixels in the source
578ce217faddb4b40c1b3e698944da1951027080427Romain Guy     * buffer are assumed to be in the bitmap's color space.</p>
5791f58497e7dbab1b16e97c73b65559b852d0c2803Romain Guy     * <p>After this method returns, the current position of the buffer is
5801f58497e7dbab1b16e97c73b65559b852d0c2803Romain Guy     * updated: the position is incremented by the number of elements read from
5811f58497e7dbab1b16e97c73b65559b852d0c2803Romain Guy     * the buffer. If you need to read the bitmap from the buffer again you must
5821f58497e7dbab1b16e97c73b65559b852d0c2803Romain Guy     * first rewind the buffer.</p>
583980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv     * @throws IllegalStateException if the bitmap's config is {@link Config#HARDWARE}
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void copyPixelsFromBuffer(Buffer src) {
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("copyPixelsFromBuffer called on recycled bitmap");
587980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv        checkHardware("unable to copyPixelsFromBuffer, Config#HARDWARE bitmaps are immutable");
5888cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int elements = src.remaining();
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int shift;
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (src instanceof ByteBuffer) {
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 0;
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (src instanceof ShortBuffer) {
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 1;
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (src instanceof IntBuffer) {
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            shift = 2;
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("unsupported Buffer subclass");
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6008cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
6013849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy        long bufferBytes = (long) elements << shift;
602f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson        long bitmapBytes = getByteCount();
6038cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bufferBytes < bitmapBytes) {
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("Buffer not large enough for pixels");
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6078cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
608775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        nativeCopyPixelsFromBuffer(mNativePtr, src);
60955adc145d460be4b21de0d77be1f6076c3591e3cMarco Nelissen
61055adc145d460be4b21de0d77be1f6076c3591e3cMarco Nelissen        // now update the buffer's position
61155adc145d460be4b21de0d77be1f6076c3591e3cMarco Nelissen        int position = src.position();
61255adc145d460be4b21de0d77be1f6076c3591e3cMarco Nelissen        position += bitmapBytes >> shift;
61355adc145d460be4b21de0d77be1f6076c3591e3cMarco Nelissen        src.position(position);
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6158cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
6169fd259c9b0878ba52fec86173d76976e70977fcdsergeyv    private void noteHardwareBitmapSlowCall() {
6179fd259c9b0878ba52fec86173d76976e70977fcdsergeyv        if (getConfig() == Config.HARDWARE) {
6189fd259c9b0878ba52fec86173d76976e70977fcdsergeyv            StrictMode.noteSlowCall("Warning: attempt to read pixels from hardware "
6199fd259c9b0878ba52fec86173d76976e70977fcdsergeyv                    + "bitmap, which is very slow operation");
6209fd259c9b0878ba52fec86173d76976e70977fcdsergeyv        }
6219fd259c9b0878ba52fec86173d76976e70977fcdsergeyv    }
6229fd259c9b0878ba52fec86173d76976e70977fcdsergeyv
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Tries to make a new bitmap based on the dimensions of this bitmap,
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * setting the new bitmap's config to the one specified, and then copying
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this bitmap's pixels into the new bitmap. If the conversion is not
62796e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * supported, or the allocator fails, then this returns NULL.  The returned
6288242656f495847c50c9ceaea92839dce78218a75Romain Guy     * bitmap has the same density and color space as the original.
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param config    The desired config for the resulting bitmap
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param isMutable True if the resulting bitmap should be mutable (i.e.
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                  its pixels can be modified)
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the new bitmap, or null if the copy could not be made.
63405126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv     * @throws IllegalArgumentException if config is {@link Config#HARDWARE} and isMutable is true
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Bitmap copy(Config config, boolean isMutable) {
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't copy a recycled bitmap");
63805126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv        if (config == Config.HARDWARE && isMutable) {
63905126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv            throw new IllegalArgumentException("Hardware bitmaps are always immutable");
64005126d151eb3caa85bd3a039cffb6e37940c3fa4sergeyv        }
6419fd259c9b0878ba52fec86173d76976e70977fcdsergeyv        noteHardwareBitmapSlowCall();
642775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        Bitmap b = nativeCopy(mNativePtr, config.nativeInt, isMutable);
64396e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        if (b != null) {
64457ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III            b.setPremultiplied(mRequestPremultiplied);
64596e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn            b.mDensity = mDensity;
64696e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        }
64796e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        return b;
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
65002d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick    /**
651721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews     * Creates a new immutable bitmap backed by ashmem which can efficiently
6528242656f495847c50c9ceaea92839dce78218a75Romain Guy     * be passed between processes. The bitmap is assumed to be in the sRGB
6538242656f495847c50c9ceaea92839dce78218a75Romain Guy     * color space.
654721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews     *
655721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews     * @hide
656721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews     */
657721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews    public Bitmap createAshmemBitmap() {
658721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews        checkRecycled("Can't copy a recycled bitmap");
6599fd259c9b0878ba52fec86173d76976e70977fcdsergeyv        noteHardwareBitmapSlowCall();
660775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        Bitmap b = nativeCopyAshmem(mNativePtr);
661721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews        if (b != null) {
662721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews            b.setPremultiplied(mRequestPremultiplied);
663721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews            b.mDensity = mDensity;
664721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews        }
665721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews        return b;
666721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews    }
667721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews
668721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews    /**
669a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson     * Creates a new immutable bitmap backed by ashmem which can efficiently
6708242656f495847c50c9ceaea92839dce78218a75Romain Guy     * be passed between processes. The bitmap is assumed to be in the sRGB
6718242656f495847c50c9ceaea92839dce78218a75Romain Guy     * color space.
672a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson     *
673a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson     * @hide
674a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson     */
675a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson    public Bitmap createAshmemBitmap(Config config) {
676a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson        checkRecycled("Can't copy a recycled bitmap");
6779fd259c9b0878ba52fec86173d76976e70977fcdsergeyv        noteHardwareBitmapSlowCall();
678a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson        Bitmap b = nativeCopyAshmemConfig(mNativePtr, config.nativeInt);
679a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson        if (b != null) {
680a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson            b.setPremultiplied(mRequestPremultiplied);
681a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson            b.mDensity = mDensity;
682a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson        }
683a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson        return b;
684a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson    }
685a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson
686a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson    /**
6870a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv     * Create hardware bitmap backed GraphicBuffer.
6880a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv     *
6890a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv     * @return Bitmap or null if this GraphicBuffer has unsupported PixelFormat.
6900a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv     *         currently PIXEL_FORMAT_RGBA_8888 is the only supported format
6910a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv     * @hide
6920a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv     */
6938242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createHardwareBitmap(@NonNull GraphicBuffer graphicBuffer) {
6940a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv        return nativeCreateHardwareBitmap(graphicBuffer);
6950a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv    }
6960a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv
6970a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv    /**
698f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * Creates a new bitmap, scaled from an existing bitmap, when possible. If the
699f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     * specified width and height are the same as the current width and height of
7009f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     * the source bitmap, the source bitmap is returned and no new bitmap is
701f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * created.
70202d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     *
70302d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     * @param src       The source bitmap.
70402d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     * @param dstWidth  The new bitmap's desired width.
70502d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     * @param dstHeight The new bitmap's desired height.
70602d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     * @param filter    true if the source should be filtered.
707f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * @return The new scaled bitmap or the source bitmap if no scaling is required.
708790552b240c05d58407f7c14acba656b2e85c523Romain Guy     * @throws IllegalArgumentException if width is <= 0, or height is <= 0
70902d9102b3bdebac6989c2b7d12c080fb7c1f8e2bBrad Fitzpatrick     */
7108242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createScaledBitmap(@NonNull Bitmap src, int dstWidth, int dstHeight,
711f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy            boolean filter) {
7128242656f495847c50c9ceaea92839dce78218a75Romain Guy        Matrix m = new Matrix();
7138cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int width = src.getWidth();
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int height = src.getHeight();
7168242656f495847c50c9ceaea92839dce78218a75Romain Guy        if (width != dstWidth || height != dstHeight) {
7178242656f495847c50c9ceaea92839dce78218a75Romain Guy            final float sx = dstWidth / (float) width;
7188242656f495847c50c9ceaea92839dce78218a75Romain Guy            final float sy = dstHeight / (float) height;
7198242656f495847c50c9ceaea92839dce78218a75Romain Guy            m.setScale(sx, sy);
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7218242656f495847c50c9ceaea92839dce78218a75Romain Guy        return Bitmap.createBitmap(src, 0, 0, width, height, m, filter);
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7238cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an immutable bitmap from the source bitmap. The new bitmap may
72696e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * be the same object as source, or a copy may have been made.  It is
7278242656f495847c50c9ceaea92839dce78218a75Romain Guy     * initialized with the same density and color space as the original bitmap.
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7298242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(@NonNull Bitmap src) {
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return createBitmap(src, 0, 0, src.getWidth(), src.getHeight());
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an immutable bitmap from the specified subset of the source
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * bitmap. The new bitmap may be the same object as source, or a copy may
7368242656f495847c50c9ceaea92839dce78218a75Romain Guy     * have been made. It is initialized with the same density and color space
7378242656f495847c50c9ceaea92839dce78218a75Romain Guy     * as the original bitmap.
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param source   The bitmap we are subsetting
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x        The x coordinate of the first pixel in source
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y        The y coordinate of the first pixel in source
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The number of pixels in each row
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The number of rows
744f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * @return A copy of a subset of the source bitmap or the source bitmap itself.
745790552b240c05d58407f7c14acba656b2e85c523Romain Guy     * @throws IllegalArgumentException if the x, y, width, height values are
746790552b240c05d58407f7c14acba656b2e85c523Romain Guy     *         outside of the dimensions of the source bitmap, or width is <= 0,
747790552b240c05d58407f7c14acba656b2e85c523Romain Guy     *         or height is <= 0
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7498242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(@NonNull Bitmap source, int x, int y, int width, int height) {
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return createBitmap(source, x, y, width, height, null, false);
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7528cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an immutable bitmap from subset of the source bitmap,
755f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * transformed by the optional matrix. The new bitmap may be the
756f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * same object as source, or a copy may have been made. It is
7578242656f495847c50c9ceaea92839dce78218a75Romain Guy     * initialized with the same density and color space as the original
7588242656f495847c50c9ceaea92839dce78218a75Romain Guy     * bitmap.
759f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
760f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * If the source bitmap is immutable and the requested subset is the
761f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * same as the source bitmap itself, then the source bitmap is
762f12f6f058f169ead83a546a1c3a51e49452a30b3Romain Guy     * returned and no new bitmap is created.
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param source   The bitmap we are subsetting
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x        The x coordinate of the first pixel in source
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y        The y coordinate of the first pixel in source
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The number of pixels in each row
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The number of rows
76960b88edea7132ddce90f2dced07c6706f1502270Ken Shirriff     * @param m        Optional matrix to be applied to the pixels
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param filter   true if the source should be filtered.
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   Only applies if the matrix contains more than just
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   translation.
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return A bitmap that represents the specified subset of source
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if the x, y, width, height values are
775790552b240c05d58407f7c14acba656b2e85c523Romain Guy     *         outside of the dimensions of the source bitmap, or width is <= 0,
776790552b240c05d58407f7c14acba656b2e85c523Romain Guy     *         or height is <= 0
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7788242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(@NonNull Bitmap source, int x, int y, int width, int height,
7798242656f495847c50c9ceaea92839dce78218a75Romain Guy            @Nullable Matrix m, boolean filter) {
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkXYSign(x, y);
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkWidthHeight(width, height);
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (x + width > source.getWidth()) {
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("x + width must be <= bitmap.width()");
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (y + height > source.getHeight()) {
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("y + height must be <= bitmap.height()");
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // check if we can just return our argument unchanged
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                height == source.getHeight() && (m == null || m.isIdentity())) {
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return source;
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7958cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
79681f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv        boolean isHardware = source.getConfig() == Config.HARDWARE;
79781f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv        if (isHardware) {
7989fd259c9b0878ba52fec86173d76976e70977fcdsergeyv            source.noteHardwareBitmapSlowCall();
79981f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv            source = nativeCopyPreserveInternalConfig(source.mNativePtr);
80081f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv        }
80181f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int neww = width;
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int newh = height;
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bitmap bitmap;
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Paint paint;
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Rect srcR = new Rect(x, y, x + width, y + height);
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RectF dstR = new RectF(0, 0, width, height);
80929cd3e922612afff4cd5fa9694013e5e8ae93661Derek Sollenberger        RectF deviceR = new RectF();
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
811feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy        Config newConfig = Config.ARGB_8888;
812feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy        final Config config = source.getConfig();
813feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy        // GIF files generate null configs, assume ARGB_8888
814feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy        if (config != null) {
815feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy            switch (config) {
816feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                case RGB_565:
817feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    newConfig = Config.RGB_565;
818feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    break;
819feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                case ALPHA_8:
820feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    newConfig = Config.ALPHA_8;
821feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    break;
8229505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                case RGBA_F16:
8239505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                    newConfig = Config.RGBA_F16;
8249505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                    break;
825676b17391fb6583e5df944c36b1bd4c1be835689Romain Guy                //noinspection deprecation
826feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                case ARGB_4444:
827feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                case ARGB_8888:
828feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                default:
829feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    newConfig = Config.ARGB_8888;
830feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy                    break;
831feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy            }
832feeea8f07c854e6b0ae2fec3aa2d239c17f32b5bRomain Guy        }
833d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (m == null || m.isIdentity()) {
835d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy            bitmap = createBitmap(neww, newh, newConfig, source.hasAlpha());
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            paint = null;   // not needed
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
838d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy            final boolean transformed = !m.rectStaysRect();
839d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            m.mapRect(deviceR, dstR);
841d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            neww = Math.round(deviceR.width());
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            newh = Math.round(deviceR.height());
844d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
8459505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            Config transformedConfig = newConfig;
8469505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            if (transformed) {
8479505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                if (transformedConfig != Config.ARGB_8888 && transformedConfig != Config.RGBA_F16) {
8489505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                    transformedConfig = Config.ARGB_8888;
8499505a6552764461c22ce48f1ac13d025d23e1579Romain Guy                }
8509505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            }
8519505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            bitmap = createBitmap(neww, newh, transformedConfig, transformed || source.hasAlpha());
852d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            paint = new Paint();
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            paint.setFilterBitmap(filter);
855d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy            if (transformed) {
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                paint.setAntiAlias(true);
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8598790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III
8608242656f495847c50c9ceaea92839dce78218a75Romain Guy        nativeCopyColorSpace(source.mNativePtr, bitmap.mNativePtr);
8618242656f495847c50c9ceaea92839dce78218a75Romain Guy
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The new bitmap was created from a known bitmap source so assume that
86311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        // they use the same density
86411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        bitmap.mDensity = source.mDensity;
86557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III        bitmap.setHasAlpha(source.hasAlpha());
86657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III        bitmap.setPremultiplied(source.mRequestPremultiplied);
8678790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III
86829cd3e922612afff4cd5fa9694013e5e8ae93661Derek Sollenberger        Canvas canvas = new Canvas(bitmap);
86929cd3e922612afff4cd5fa9694013e5e8ae93661Derek Sollenberger        canvas.translate(-deviceR.left, -deviceR.top);
87029cd3e922612afff4cd5fa9694013e5e8ae93661Derek Sollenberger        canvas.concat(m);
87196e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        canvas.drawBitmap(source, srcR, dstR, paint);
8726311d0a079702b29984c0d31937345be105e1a5eDianne Hackborn        canvas.setBitmap(null);
87381f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv        if (isHardware) {
87481f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv            return bitmap.copy(Config.HARDWARE, false);
87581f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv        }
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bitmap;
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8788cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
88096e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * Returns a mutable bitmap with the specified width and height.  Its
8818242656f495847c50c9ceaea92839dce78218a75Romain Guy     * initial density is as per {@link #getDensity}. The newly created
8828242656f495847c50c9ceaea92839dce78218a75Romain Guy     * bitmap is in the {@link ColorSpace.Named#SRGB sRGB} color space.
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The width of the bitmap
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The height of the bitmap
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param config   The bitmap config to create.
8879fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv     * @throws IllegalArgumentException if the width or height are <= 0, or if
8889fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv     *         Config is Config.HARDWARE, because hardware bitmaps are always immutable
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8908242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(int width, int height, @NonNull Config config) {
891d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy        return createBitmap(width, height, config, true);
892d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy    }
893d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy
894d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy    /**
895d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     * Returns a mutable bitmap with the specified width and height.  Its
896dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * initial density is determined from the given {@link DisplayMetrics}.
8978242656f495847c50c9ceaea92839dce78218a75Romain Guy     * The newly created bitmap is in the {@link ColorSpace.Named#SRGB sRGB}
8988242656f495847c50c9ceaea92839dce78218a75Romain Guy     * color space.
899dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *
900dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param display  Display metrics for the display this bitmap will be
901dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *                 drawn on.
902dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param width    The width of the bitmap
903dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param height   The height of the bitmap
904dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param config   The bitmap config to create.
9059fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv     * @throws IllegalArgumentException if the width or height are <= 0, or if
9069fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv     *         Config is Config.HARDWARE, because hardware bitmaps are always immutable
907dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     */
9088242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(@Nullable DisplayMetrics display, int width,
9098242656f495847c50c9ceaea92839dce78218a75Romain Guy            int height, @NonNull Config config) {
910dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn        return createBitmap(display, width, height, config, true);
911dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn    }
912dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn
913dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn    /**
914dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * Returns a mutable bitmap with the specified width and height.  Its
9158242656f495847c50c9ceaea92839dce78218a75Romain Guy     * initial density is as per {@link #getDensity}. The newly created
9168242656f495847c50c9ceaea92839dce78218a75Romain Guy     * bitmap is in the {@link ColorSpace.Named#SRGB sRGB} color space.
917d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     *
918d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     * @param width    The width of the bitmap
919d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     * @param height   The height of the bitmap
920d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     * @param config   The bitmap config to create.
9219505a6552764461c22ce48f1ac13d025d23e1579Romain Guy     * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
9229505a6552764461c22ce48f1ac13d025d23e1579Romain Guy     *                 mark the bitmap as opaque. Doing so will clear the bitmap in black
923f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *                 instead of transparent.
924f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
9259fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv     * @throws IllegalArgumentException if the width or height are <= 0, or if
9269fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv     *         Config is Config.HARDWARE, because hardware bitmaps are always immutable
927d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy     */
9288242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(int width, int height,
9298242656f495847c50c9ceaea92839dce78218a75Romain Guy            @NonNull Config config, boolean hasAlpha) {
930dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn        return createBitmap(null, width, height, config, hasAlpha);
931dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn    }
932dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn
933dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn    /**
934dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * Returns a mutable bitmap with the specified width and height.  Its
9358242656f495847c50c9ceaea92839dce78218a75Romain Guy     * initial density is as per {@link #getDensity}.
9368242656f495847c50c9ceaea92839dce78218a75Romain Guy     *
9378242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param width    The width of the bitmap
9388242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param height   The height of the bitmap
9398242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param config   The bitmap config to create.
9408242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
9418242656f495847c50c9ceaea92839dce78218a75Romain Guy     *                 mark the bitmap as opaque. Doing so will clear the bitmap in black
9428242656f495847c50c9ceaea92839dce78218a75Romain Guy     *                 instead of transparent.
9431fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     * @param colorSpace The color space of the bitmap. If the config is {@link Config#RGBA_F16},
9441fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *                   {@link ColorSpace.Named#EXTENDED_SRGB scRGB} is assumed, and if the
9451fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *                   config is not {@link Config#ARGB_8888}, {@link ColorSpace.Named#SRGB sRGB}
9461fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *                   is assumed.
9478242656f495847c50c9ceaea92839dce78218a75Romain Guy     *
9488242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @throws IllegalArgumentException if the width or height are <= 0, if
9498242656f495847c50c9ceaea92839dce78218a75Romain Guy     *         Config is Config.HARDWARE (because hardware bitmaps are always
9508242656f495847c50c9ceaea92839dce78218a75Romain Guy     *         immutable), if the specified color space is not {@link ColorSpace.Model#RGB RGB},
9511fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *         if the specified color space's transfer function is not an
9521fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *         {@link ColorSpace.Rgb.TransferParameters ICC parametric curve}, or if
9531fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *         the color space is null
9548242656f495847c50c9ceaea92839dce78218a75Romain Guy     */
9558242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(int width, int height, @NonNull Config config,
9561fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy            boolean hasAlpha, @NonNull ColorSpace colorSpace) {
9578242656f495847c50c9ceaea92839dce78218a75Romain Guy        return createBitmap(null, width, height, config, hasAlpha, colorSpace);
9588242656f495847c50c9ceaea92839dce78218a75Romain Guy    }
9598242656f495847c50c9ceaea92839dce78218a75Romain Guy
9608242656f495847c50c9ceaea92839dce78218a75Romain Guy    /**
9618242656f495847c50c9ceaea92839dce78218a75Romain Guy     * Returns a mutable bitmap with the specified width and height.  Its
962dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * initial density is determined from the given {@link DisplayMetrics}.
9638242656f495847c50c9ceaea92839dce78218a75Romain Guy     * The newly created bitmap is in the {@link ColorSpace.Named#SRGB sRGB}
9648242656f495847c50c9ceaea92839dce78218a75Romain Guy     * color space.
965dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *
966dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param display  Display metrics for the display this bitmap will be
967dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *                 drawn on.
968dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param width    The width of the bitmap
969dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param height   The height of the bitmap
970dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param config   The bitmap config to create.
9719505a6552764461c22ce48f1ac13d025d23e1579Romain Guy     * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
9729505a6552764461c22ce48f1ac13d025d23e1579Romain Guy     *                 mark the bitmap as opaque. Doing so will clear the bitmap in black
973f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *                 instead of transparent.
974f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
9759fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv     * @throws IllegalArgumentException if the width or height are <= 0, or if
9769fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv     *         Config is Config.HARDWARE, because hardware bitmaps are always immutable
977dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     */
9788242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(@Nullable DisplayMetrics display, int width, int height,
9798242656f495847c50c9ceaea92839dce78218a75Romain Guy            @NonNull Config config, boolean hasAlpha) {
9801fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy        return createBitmap(display, width, height, config, hasAlpha,
9811fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy                ColorSpace.get(ColorSpace.Named.SRGB));
9828242656f495847c50c9ceaea92839dce78218a75Romain Guy    }
9838242656f495847c50c9ceaea92839dce78218a75Romain Guy
9848242656f495847c50c9ceaea92839dce78218a75Romain Guy    /**
9858242656f495847c50c9ceaea92839dce78218a75Romain Guy     * Returns a mutable bitmap with the specified width and height.  Its
9868242656f495847c50c9ceaea92839dce78218a75Romain Guy     * initial density is determined from the given {@link DisplayMetrics}.
9878242656f495847c50c9ceaea92839dce78218a75Romain Guy     * The newly created bitmap is in the {@link ColorSpace.Named#SRGB sRGB}
9888242656f495847c50c9ceaea92839dce78218a75Romain Guy     * color space.
9898242656f495847c50c9ceaea92839dce78218a75Romain Guy     *
9908242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param display  Display metrics for the display this bitmap will be
9918242656f495847c50c9ceaea92839dce78218a75Romain Guy     *                 drawn on.
9928242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param width    The width of the bitmap
9938242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param height   The height of the bitmap
9948242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param config   The bitmap config to create.
9958242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
9968242656f495847c50c9ceaea92839dce78218a75Romain Guy     *                 mark the bitmap as opaque. Doing so will clear the bitmap in black
9978242656f495847c50c9ceaea92839dce78218a75Romain Guy     *                 instead of transparent.
9981fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     * @param colorSpace The color space of the bitmap. If the config is {@link Config#RGBA_F16},
9991fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *                   {@link ColorSpace.Named#EXTENDED_SRGB scRGB} is assumed, and if the
10001fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *                   config is not {@link Config#ARGB_8888}, {@link ColorSpace.Named#SRGB sRGB}
10011fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *                   is assumed.
10028242656f495847c50c9ceaea92839dce78218a75Romain Guy     *
10038242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @throws IllegalArgumentException if the width or height are <= 0, if
10048242656f495847c50c9ceaea92839dce78218a75Romain Guy     *         Config is Config.HARDWARE (because hardware bitmaps are always
10058242656f495847c50c9ceaea92839dce78218a75Romain Guy     *         immutable), if the specified color space is not {@link ColorSpace.Model#RGB RGB},
10061fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *         if the specified color space's transfer function is not an
10071fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *         {@link ColorSpace.Rgb.TransferParameters ICC parametric curve}, or if
10081fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy     *         the color space is null
10098242656f495847c50c9ceaea92839dce78218a75Romain Guy     */
10108242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(@Nullable DisplayMetrics display, int width, int height,
10111fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy            @NonNull Config config, boolean hasAlpha, @NonNull ColorSpace colorSpace) {
1012e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        if (width <= 0 || height <= 0) {
1013e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy            throw new IllegalArgumentException("width and height must be > 0");
1014e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        }
10159fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv        if (config == Config.HARDWARE) {
10169fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv            throw new IllegalArgumentException("can't create mutable bitmap with Config.HARDWARE");
10179fbb0b5ab321d86efbc7fa8774052bfb34de9557sergeyv        }
10181fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy        if (colorSpace == null) {
10191fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy            throw new IllegalArgumentException("can't create bitmap without a color space");
10201fa9d86ea4ce1d2344deaccad002413f88317010Romain Guy        }
10218242656f495847c50c9ceaea92839dce78218a75Romain Guy
10228242656f495847c50c9ceaea92839dce78218a75Romain Guy        Bitmap bm;
102308587d45b103d749c1483ec7fae80888985b5eaaRomain Guy        // nullptr color spaces have a particular meaning in native and are interpreted as sRGB
102408587d45b103d749c1483ec7fae80888985b5eaaRomain Guy        // (we also avoid the unnecessary extra work of the else branch)
102508587d45b103d749c1483ec7fae80888985b5eaaRomain Guy        if (config != Config.ARGB_8888 || colorSpace == ColorSpace.get(ColorSpace.Named.SRGB)) {
10268242656f495847c50c9ceaea92839dce78218a75Romain Guy            bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true, null, null);
10278242656f495847c50c9ceaea92839dce78218a75Romain Guy        } else {
10288242656f495847c50c9ceaea92839dce78218a75Romain Guy            if (!(colorSpace instanceof ColorSpace.Rgb)) {
10298242656f495847c50c9ceaea92839dce78218a75Romain Guy                throw new IllegalArgumentException("colorSpace must be an RGB color space");
10308242656f495847c50c9ceaea92839dce78218a75Romain Guy            }
10318242656f495847c50c9ceaea92839dce78218a75Romain Guy            ColorSpace.Rgb rgb = (ColorSpace.Rgb) colorSpace;
10328242656f495847c50c9ceaea92839dce78218a75Romain Guy            ColorSpace.Rgb.TransferParameters parameters = rgb.getTransferParameters();
10338242656f495847c50c9ceaea92839dce78218a75Romain Guy            if (parameters == null) {
10348242656f495847c50c9ceaea92839dce78218a75Romain Guy                throw new IllegalArgumentException("colorSpace must use an ICC "
10358242656f495847c50c9ceaea92839dce78218a75Romain Guy                        + "parametric transfer function");
10368242656f495847c50c9ceaea92839dce78218a75Romain Guy            }
10378242656f495847c50c9ceaea92839dce78218a75Romain Guy
10388242656f495847c50c9ceaea92839dce78218a75Romain Guy            ColorSpace.Rgb d50 = (ColorSpace.Rgb) ColorSpace.adapt(rgb, ColorSpace.ILLUMINANT_D50);
10398242656f495847c50c9ceaea92839dce78218a75Romain Guy            bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true,
10408242656f495847c50c9ceaea92839dce78218a75Romain Guy                    d50.getTransform(), parameters);
10418242656f495847c50c9ceaea92839dce78218a75Romain Guy        }
10428242656f495847c50c9ceaea92839dce78218a75Romain Guy
1043dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn        if (display != null) {
1044dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn            bm.mDensity = display.densityDpi;
1045dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn        }
10468790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III        bm.setHasAlpha(hasAlpha);
10479505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        if ((config == Config.ARGB_8888 || config == Config.RGBA_F16) && !hasAlpha) {
1048775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler            nativeErase(bm.mNativePtr, 0xff000000);
1049d90f23e24a4d1768d5a7ed0e7072e67af6330a45Romain Guy        }
10503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        // No need to initialize the bitmap to zeroes with other configs;
10513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        // it is backed by a VM byte array which is by definition preinitialized
10523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        // to all zeroes.
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bm;
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10558cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a immutable bitmap with the specified width and height, with each
105896e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * pixel value set to the corresponding value in the colors array.  Its
10598242656f495847c50c9ceaea92839dce78218a75Romain Guy     * initial density is as per {@link #getDensity}. The newly created
10608242656f495847c50c9ceaea92839dce78218a75Romain Guy     * bitmap is in the {@link ColorSpace.Named#SRGB sRGB} color space.
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10628242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param colors   Array of sRGB {@link Color colors} used to initialize the pixels.
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset   Number of values to skip before the first color in the
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 array of colors.
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stride   Number of colors in the array between rows (must be >=
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 width or <= -width).
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The width of the bitmap
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The height of the bitmap
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param config   The bitmap config to create. If the config does not
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 support per-pixel alpha (e.g. RGB_565), then the alpha
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 bytes in the colors[] will be ignored (assumed to be FF)
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if the width or height are <= 0, or if
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         the color array's length is less than the number of pixels.
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10758242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(@NonNull @ColorInt int[] colors, int offset, int stride,
10768242656f495847c50c9ceaea92839dce78218a75Romain Guy            int width, int height, @NonNull Config config) {
1077dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn        return createBitmap(null, colors, offset, stride, width, height, config);
1078dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn    }
1079dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn
1080dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn    /**
1081dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * Returns a immutable bitmap with the specified width and height, with each
1082dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * pixel value set to the corresponding value in the colors array.  Its
1083dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * initial density is determined from the given {@link DisplayMetrics}.
10848242656f495847c50c9ceaea92839dce78218a75Romain Guy     * The newly created bitmap is in the {@link ColorSpace.Named#SRGB sRGB}
10858242656f495847c50c9ceaea92839dce78218a75Romain Guy     * color space.
1086dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *
1087dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param display  Display metrics for the display this bitmap will be
1088dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *                 drawn on.
10898242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param colors   Array of sRGB {@link Color colors} used to initialize the pixels.
1090dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param offset   Number of values to skip before the first color in the
1091dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *                 array of colors.
1092dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param stride   Number of colors in the array between rows (must be >=
1093dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *                 width or <= -width).
1094dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param width    The width of the bitmap
1095dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param height   The height of the bitmap
1096dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param config   The bitmap config to create. If the config does not
1097dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *                 support per-pixel alpha (e.g. RGB_565), then the alpha
1098dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *                 bytes in the colors[] will be ignored (assumed to be FF)
1099dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @throws IllegalArgumentException if the width or height are <= 0, or if
1100dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *         the color array's length is less than the number of pixels.
1101dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     */
11028242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(@NonNull DisplayMetrics display,
11038242656f495847c50c9ceaea92839dce78218a75Romain Guy            @NonNull @ColorInt int[] colors, int offset, int stride,
11048242656f495847c50c9ceaea92839dce78218a75Romain Guy            int width, int height, @NonNull Config config) {
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkWidthHeight(width, height);
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Math.abs(stride) < width) {
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("abs(stride) must be >= width");
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int lastScanline = offset + (height - 1) * stride;
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int length = colors.length;
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (offset < 0 || (offset + width > length) || lastScanline < 0 ||
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (lastScanline + width > length)) {
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayIndexOutOfBoundsException();
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1116e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        if (width <= 0 || height <= 0) {
1117e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy            throw new IllegalArgumentException("width and height must be > 0");
1118e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy        }
1119dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn        Bitmap bm = nativeCreate(colors, offset, stride, width, height,
11208242656f495847c50c9ceaea92839dce78218a75Romain Guy                            config.nativeInt, false, null, null);
1121dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn        if (display != null) {
1122dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn            bm.mDensity = display.densityDpi;
1123dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn        }
1124dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn        return bm;
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a immutable bitmap with the specified width and height, with each
112996e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * pixel value set to the corresponding value in the colors array.  Its
11308242656f495847c50c9ceaea92839dce78218a75Romain Guy     * initial density is as per {@link #getDensity}. The newly created
11318242656f495847c50c9ceaea92839dce78218a75Romain Guy     * bitmap is in the {@link ColorSpace.Named#SRGB sRGB} color space.
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11338242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param colors   Array of sRGB {@link Color colors} used to initialize the pixels.
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 This array must be at least as large as width * height.
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The width of the bitmap
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The height of the bitmap
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param config   The bitmap config to create. If the config does not
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 support per-pixel alpha (e.g. RGB_565), then the alpha
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 bytes in the colors[] will be ignored (assumed to be FF)
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if the width or height are <= 0, or if
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         the color array's length is less than the number of pixels.
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11438242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(@NonNull @ColorInt int[] colors,
11448242656f495847c50c9ceaea92839dce78218a75Romain Guy            int width, int height, Config config) {
1145dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn        return createBitmap(null, colors, 0, width, width, height, config);
1146dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn    }
1147dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn
1148dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn    /**
1149dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * Returns a immutable bitmap with the specified width and height, with each
1150dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * pixel value set to the corresponding value in the colors array.  Its
1151dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * initial density is determined from the given {@link DisplayMetrics}.
11528242656f495847c50c9ceaea92839dce78218a75Romain Guy     * The newly created bitmap is in the {@link ColorSpace.Named#SRGB sRGB}
11538242656f495847c50c9ceaea92839dce78218a75Romain Guy     * color space.
1154dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *
1155dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param display  Display metrics for the display this bitmap will be
1156dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *                 drawn on.
11578242656f495847c50c9ceaea92839dce78218a75Romain Guy     * @param colors   Array of sRGB {@link Color colors} used to initialize the pixels.
1158dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *                 This array must be at least as large as width * height.
1159dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param width    The width of the bitmap
1160dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param height   The height of the bitmap
1161dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @param config   The bitmap config to create. If the config does not
1162dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *                 support per-pixel alpha (e.g. RGB_565), then the alpha
1163dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *                 bytes in the colors[] will be ignored (assumed to be FF)
1164dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     * @throws IllegalArgumentException if the width or height are <= 0, or if
1165dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     *         the color array's length is less than the number of pixels.
1166dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn     */
11678242656f495847c50c9ceaea92839dce78218a75Romain Guy    public static Bitmap createBitmap(@Nullable DisplayMetrics display,
11688242656f495847c50c9ceaea92839dce78218a75Romain Guy            @NonNull @ColorInt int colors[], int width, int height, @NonNull Config config) {
1169dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn        return createBitmap(display, colors, 0, width, width, height, config);
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an optional array of private data, used by the UI system for
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * some bitmaps. Not intended to be called by applications.
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public byte[] getNinePatchChunk() {
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mNinePatchChunk;
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1181c054966b719c8a7255f7cf4120cca5050acb68bdAlan Viverette     * Populates a rectangle with the bitmap's optical insets.
1182c054966b719c8a7255f7cf4120cca5050acb68bdAlan Viverette     *
1183c054966b719c8a7255f7cf4120cca5050acb68bdAlan Viverette     * @param outInsets Rect to populate with optical insets
1184ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     * @hide
1185ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani     */
1186c054966b719c8a7255f7cf4120cca5050acb68bdAlan Viverette    public void getOpticalInsets(@NonNull Rect outInsets) {
118747cd8e921db73e894f94ec4729ade90da50996f5Chris Craik        if (mNinePatchInsets == null) {
1188c054966b719c8a7255f7cf4120cca5050acb68bdAlan Viverette            outInsets.setEmpty();
1189c054966b719c8a7255f7cf4120cca5050acb68bdAlan Viverette        } else {
119047cd8e921db73e894f94ec4729ade90da50996f5Chris Craik            outInsets.set(mNinePatchInsets.opticalRect);
1191c054966b719c8a7255f7cf4120cca5050acb68bdAlan Viverette        }
1192ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    }
1193ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani
119447cd8e921db73e894f94ec4729ade90da50996f5Chris Craik    /** @hide */
119547cd8e921db73e894f94ec4729ade90da50996f5Chris Craik    public NinePatch.InsetStruct getNinePatchInsets() {
119647cd8e921db73e894f94ec4729ade90da50996f5Chris Craik        return mNinePatchInsets;
119747cd8e921db73e894f94ec4729ade90da50996f5Chris Craik    }
119847cd8e921db73e894f94ec4729ade90da50996f5Chris Craik
1199ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani    /**
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specifies the known formats a bitmap can be compressed into
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public enum CompressFormat {
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        JPEG    (0),
12042305ac9e4a262ed09fd034ae417e9b1dda4c0ccbVikas Arora        PNG     (1),
12052305ac9e4a262ed09fd034ae417e9b1dda4c0ccbVikas Arora        WEBP    (2);
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CompressFormat(int nativeInt) {
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.nativeInt = nativeInt;
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int nativeInt;
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Number of bytes of temp storage we use for communicating between the
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * native compressor and the java OutputStream.
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final static int WORKING_COMPRESS_STORAGE = 4096;
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Write a compressed version of the bitmap to the specified outputstream.
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If this returns true, the bitmap can be reconstructed by passing a
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corresponding inputstream to BitmapFactory.decodeStream(). Note: not
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * all Formats support all bitmap configs directly, so it is possible that
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the returned bitmap from BitmapFactory could be in a different bitdepth,
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and/or may have lost per-pixel alpha (e.g. JPEG only supports opaque
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pixels).
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param format   The format of the compressed image
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param quality  Hint to the compressor, 0-100. 0 meaning compress for
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 small size, 100 meaning compress for max quality. Some
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 formats, like PNG which is lossless, will ignore the
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 quality setting
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stream   The outputstream to write the compressed data.
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if successfully compressed to the specified stream.
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean compress(CompressFormat format, int quality, OutputStream stream) {
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't compress a recycled bitmap");
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // do explicit check before calling the native method
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (stream == null) {
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new NullPointerException();
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (quality < 0 || quality > 100) {
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("quality must be 0..100");
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12459fd259c9b0878ba52fec86173d76976e70977fcdsergeyv        StrictMode.noteSlowCall("Compression of a bitmap is slow");
12460df3bd5594bbbbfbf6058ecb31e9b94a1cd22f7dJohn Reck        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "Bitmap.compress");
1247775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        boolean result = nativeCompress(mNativePtr, format.nativeInt,
1248f29ed28c7b878ef28058bc730715d0d32445bc57John Reck                quality, stream, new byte[WORKING_COMPRESS_STORAGE]);
12490df3bd5594bbbbfbf6058ecb31e9b94a1cd22f7dJohn Reck        Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
12500df3bd5594bbbbfbf6058ecb31e9b94a1cd22f7dJohn Reck        return result;
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12528cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1254ff236f5fc1a088b1210d37a67b0e88b06c0fbdb2Newton Allen     * Returns true if the bitmap is marked as mutable (i.e.&nbsp;can be drawn into)
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean isMutable() {
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsMutable;
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12603849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy    /**
12613849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * <p>Indicates whether pixels stored in this bitmaps are stored pre-multiplied.
12623849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * When a pixel is pre-multiplied, the RGB components have been multiplied by
12633849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * the alpha component. For instance, if the original color is a 50%
1264f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     * translucent red <code>(128, 255, 0, 0)</code>, the pre-multiplied form is
12653849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * <code>(128, 128, 0, 0)</code>.</p>
1266f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
12673849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * <p>This method always returns false if {@link #getConfig()} is
12684ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy     * {@link Bitmap.Config#RGB_565}.</p>
1269f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
127057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III     * <p>The return value is undefined if {@link #getConfig()} is
127157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III     * {@link Bitmap.Config#ALPHA_8}.</p>
127257ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III     *
12734ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy     * <p>This method only returns true if {@link #hasAlpha()} returns true.
12744ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy     * A bitmap with no alpha channel can be used both as a pre-multiplied and
12754ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy     * as a non pre-multiplied bitmap.</p>
12761abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     *
12771abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * <p>Only pre-multiplied bitmaps may be drawn by the view system or
12781abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * {@link Canvas}. If a non-pre-multiplied bitmap with an alpha channel is
12791abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * drawn to a Canvas, a RuntimeException will be thrown.</p>
12801abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     *
12813849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * @return true if the underlying pixels have been pre-multiplied, false
12823849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     *         otherwise
12831abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     *
12841abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * @see Bitmap#setPremultiplied(boolean)
12851abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * @see BitmapFactory.Options#inPremultiplied
12863849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     */
12873849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy    public final boolean isPremultiplied() {
128801a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        if (mRecycled) {
128901a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck            Log.w(TAG, "Called isPremultiplied() on a recycle()'d bitmap! This is undefined behavior!");
129001a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        }
1291775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        return nativeIsPremultiplied(mNativePtr);
12921abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik    }
12931abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik
12941abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik    /**
12951abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * Sets whether the bitmap should treat its data as pre-multiplied.
12961abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     *
12971abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * <p>Bitmaps are always treated as pre-multiplied by the view system and
12981abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * {@link Canvas} for performance reasons. Storing un-pre-multiplied data in
12991abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * a Bitmap (through {@link #setPixel}, {@link #setPixels}, or {@link
13001abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * BitmapFactory.Options#inPremultiplied BitmapFactory.Options.inPremultiplied})
13011abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * can lead to incorrect blending if drawn by the framework.</p>
13021abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     *
13031abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * <p>This method will not affect the behavior of a bitmap without an alpha
13041abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * channel, or if {@link #hasAlpha()} returns false.</p>
13051abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     *
1306889a1ddd00b74933d5f7daa651d98133bcb034baBen Murdoch     * <p>Calling {@link #createBitmap} or {@link #createScaledBitmap} with a source
13078790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III     * Bitmap whose colors are not pre-multiplied may result in a RuntimeException,
13088790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III     * since those functions require drawing the source, which is not supported for
13098790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III     * un-pre-multiplied Bitmaps.</p>
13108790be6de3644e332ec6a17c855da89ffc13a9bfLeon Scroggins III     *
13111abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * @see Bitmap#isPremultiplied()
13121abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     * @see BitmapFactory.Options#inPremultiplied
13131abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik     */
13141abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik    public final void setPremultiplied(boolean premultiplied) {
13153e776dee3e8af646cdcfb7a60e0e301c99f05293John Reck        checkRecycled("setPremultiplied called on a recycled bitmap");
131657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III        mRequestPremultiplied = premultiplied;
1317775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        nativeSetPremultiplied(mNativePtr, premultiplied);
13183849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy    }
13193849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Returns the bitmap's width */
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final int getWidth() {
132201a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        if (mRecycled) {
132301a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck            Log.w(TAG, "Called getWidth() on a recycle()'d bitmap! This is undefined behavior!");
132401a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        }
13251abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        return mWidth;
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Returns the bitmap's height */
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final int getHeight() {
133001a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        if (mRecycled) {
133101a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck            Log.w(TAG, "Called getHeight() on a recycle()'d bitmap! This is undefined behavior!");
133201a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        }
13331abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik        return mHeight;
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13358cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
133711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Convenience for calling {@link #getScaledWidth(int)} with the target
133811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * density of the given {@link Canvas}.
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13402784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    public int getScaledWidth(Canvas canvas) {
134111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getWidth(), mDensity, canvas.mDensity);
13422784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    }
13432784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn
13442784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    /**
134511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Convenience for calling {@link #getScaledHeight(int)} with the target
134611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * density of the given {@link Canvas}.
13472784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     */
13482784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    public int getScaledHeight(Canvas canvas) {
134911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getHeight(), mDensity, canvas.mDensity);
135011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    }
135111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
135211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    /**
135311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Convenience for calling {@link #getScaledWidth(int)} with the target
135411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * density of the given {@link DisplayMetrics}.
135511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     */
135611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getScaledWidth(DisplayMetrics metrics) {
135711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getWidth(), mDensity, metrics.densityDpi);
135811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    }
135911ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn
136011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    /**
136111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * Convenience for calling {@link #getScaledHeight(int)} with the target
136211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * density of the given {@link DisplayMetrics}.
136311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     */
136411ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getScaledHeight(DisplayMetrics metrics) {
136511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getHeight(), mDensity, metrics.densityDpi);
13662784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    }
13672784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn
13682784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn    /**
13692784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     * Convenience method that returns the width of this bitmap divided
13702784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     * by the density scale factor.
13712784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     *
137211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @param targetDensity The density of the target canvas of the bitmap.
13732784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     * @return The scaled width of this bitmap, according to the density scale factor.
13742784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn     */
137511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getScaledWidth(int targetDensity) {
137611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getWidth(), mDensity, targetDensity);
13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Convenience method that returns the height of this bitmap divided
13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the density scale factor.
13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
138311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @param targetDensity The density of the target canvas of the bitmap.
13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The scaled height of this bitmap, according to the density scale factor.
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
138611ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    public int getScaledHeight(int targetDensity) {
138711ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        return scaleFromDensity(getHeight(), mDensity, targetDensity);
138811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    }
1389f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck
139011ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    /**
139111ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     * @hide
139211ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn     */
139311ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn    static public int scaleFromDensity(int size, int sdensity, int tdensity) {
13940b68477f8287fe5ddac1beb1c9d0811ded034dadRomain Guy        if (sdensity == DENSITY_NONE || tdensity == DENSITY_NONE || sdensity == tdensity) {
139511ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn            return size;
13962784ff0af88128f66ae690b73d48fb7e4a211e68Dianne Hackborn        }
1397f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck
139811ea33471e1a14a8594f0b2cd012d86340dd3bd8Dianne Hackborn        // Scale by tdensity / sdensity, rounding up.
1399366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy        return ((size * tdensity) + (sdensity >> 1)) / sdensity;
14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1401f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the number of bytes between rows in the bitmap's pixels. Note that
14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this refers to the pixels as stored natively by the bitmap. If you call
14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * getPixels() or setPixels(), then the pixels are uniformly treated as
14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * 32bit values, packed according to the Color class.
14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1408e8222dddaf2e3da14380101e818d4254899e0c0dChet Haase     * <p>As of {@link android.os.Build.VERSION_CODES#KITKAT}, this method
14099f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     * should not be used to calculate the memory usage of the bitmap. Instead,
14109f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     * see {@link #getAllocationByteCount()}.
14119f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     *
14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return number of bytes between rows of the native bitmap pixels.
14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final int getRowBytes() {
141501a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        if (mRecycled) {
141601a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck            Log.w(TAG, "Called getRowBytes() on a recycle()'d bitmap! This is undefined behavior!");
141701a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        }
1418775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        return nativeRowBytes(mNativePtr);
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14208cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14229f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     * Returns the minimum number of bytes that can be used to store this bitmap's pixels.
14239f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     *
1424e8222dddaf2e3da14380101e818d4254899e0c0dChet Haase     * <p>As of {@link android.os.Build.VERSION_CODES#KITKAT}, the result of this method can
14259f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     * no longer be used to determine memory usage of a bitmap. See {@link
1426c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * #getAllocationByteCount()}.</p>
1427f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson     */
1428f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson    public final int getByteCount() {
14293bdecbf0fd2d4b6137477094e1ea96502c353248John Reck        if (mRecycled) {
14303bdecbf0fd2d4b6137477094e1ea96502c353248John Reck            Log.w(TAG, "Called getByteCount() on a recycle()'d bitmap! "
14313bdecbf0fd2d4b6137477094e1ea96502c353248John Reck                    + "This is undefined behavior!");
14323bdecbf0fd2d4b6137477094e1ea96502c353248John Reck            return 0;
14333bdecbf0fd2d4b6137477094e1ea96502c353248John Reck        }
1434f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson        // int result permits bitmaps up to 46,340 x 46,340
1435f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson        return getRowBytes() * getHeight();
1436f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson    }
1437f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson
1438f7f9d9c39df22ad6929f001f07588469f77e8bf5Jesse Wilson    /**
14399f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     * Returns the size of the allocated memory used to store this bitmap's pixels.
14409f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     *
14419f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     * <p>This can be larger than the result of {@link #getByteCount()} if a bitmap is reused to
1442c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * decode other bitmaps of smaller size, or by manual reconfiguration. See {@link
1443c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * #reconfigure(int, int, Config)}, {@link #setWidth(int)}, {@link #setHeight(int)}, {@link
1444c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * #setConfig(Bitmap.Config)}, and {@link BitmapFactory.Options#inBitmap
1445c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * BitmapFactory.Options.inBitmap}. If a bitmap is not modified in this way, this value will be
1446c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * the same as that returned by {@link #getByteCount()}.</p>
1447c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     *
1448c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * <p>This value will not change over the lifetime of a Bitmap.</p>
14499f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     *
1450c84d203da21c3ae3ded94c79c035d41b27809b3bChris Craik     * @see #reconfigure(int, int, Config)
14519f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik     */
14529f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik    public final int getAllocationByteCount() {
14533bdecbf0fd2d4b6137477094e1ea96502c353248John Reck        if (mRecycled) {
14543bdecbf0fd2d4b6137477094e1ea96502c353248John Reck            Log.w(TAG, "Called getAllocationByteCount() on a recycle()'d bitmap! "
14553bdecbf0fd2d4b6137477094e1ea96502c353248John Reck                    + "This is undefined behavior!");
14563bdecbf0fd2d4b6137477094e1ea96502c353248John Reck            return 0;
14573bdecbf0fd2d4b6137477094e1ea96502c353248John Reck        }
14584508218850faedea95371188da587b6734f5f3dasergeyv        return nativeGetAllocationByteCount(mNativePtr);
14599f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik    }
14609f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik
14619f58361e98be7386a4eadd3aa254e9b7d09d0a3bChris Craik    /**
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If the bitmap's internal config is in one of the public formats, return
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that config, otherwise return null.
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final Config getConfig() {
146601a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        if (mRecycled) {
146701a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck            Log.w(TAG, "Called getConfig() on a recycle()'d bitmap! This is undefined behavior!");
146801a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        }
1469775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        return Config.nativeToConfig(nativeConfig(mNativePtr));
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1472a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed    /** Returns true if the bitmap's config supports per-pixel alpha, and
1473a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * if the pixels may contain non-opaque alpha values. For some configs,
1474a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * this is always false (e.g. RGB_565), since they do not support per-pixel
1475a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * alpha. However, for configs that do, the bitmap may be flagged to be
1476a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * known that all of its pixels are opaque. In this case hasAlpha() will
1477a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * also return false. If a config such as ARGB_8888 is not so flagged,
1478a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * it will return true by default.
1479a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     */
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final boolean hasAlpha() {
148101a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        if (mRecycled) {
148201a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck            Log.w(TAG, "Called hasAlpha() on a recycle()'d bitmap! This is undefined behavior!");
148301a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        }
1484775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        return nativeHasAlpha(mNativePtr);
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1488a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * Tell the bitmap if all of the pixels are known to be opaque (false)
1489a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * or if some of the pixels may contain non-opaque alpha values (true).
1490366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy     * Note, for some configs (e.g. RGB_565) this call is ignored, since it
1491366a84056c9a695ee6702d9d30bf9f3b521ba7ccRomain Guy     * does not support per-pixel alpha values.
1492a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     *
1493a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * This is meant as a drawing hint, as in some cases a bitmap that is known
1494a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * to be opaque can take a faster drawing case than one that may have
1495a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     * non-opaque per-pixel alpha values.
1496a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed     */
1497a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed    public void setHasAlpha(boolean hasAlpha) {
14983e776dee3e8af646cdcfb7a60e0e301c99f05293John Reck        checkRecycled("setHasAlpha called on a recycled bitmap");
1499775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        nativeSetHasAlpha(mNativePtr, hasAlpha, mRequestPremultiplied);
1500a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed    }
1501a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed
1502a78b0a2d9ebb38b86ed802b3d86de07d0b301262Mike Reed    /**
1503713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * Indicates whether the renderer responsible for drawing this
1504713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * bitmap should attempt to use mipmaps when this bitmap is drawn
1505713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * scaled down.
1506f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
1507713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * If you know that you are going to draw this bitmap at less than
1508713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * 50% of its original size, you may be able to obtain a higher
1509713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * quality
1510f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
1511713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * This property is only a suggestion that can be ignored by the
1512713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * renderer. It is not guaranteed to have any effect.
1513f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
1514713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * @return true if the renderer should attempt to use mipmaps,
1515713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     *         false otherwise
1516f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
1517713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * @see #setHasMipMap(boolean)
1518713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     */
1519713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy    public final boolean hasMipMap() {
152001a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        if (mRecycled) {
152101a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck            Log.w(TAG, "Called hasMipMap() on a recycle()'d bitmap! This is undefined behavior!");
152201a0af31d7d418f400ce5d3f752eba6a35aa00e2John Reck        }
1523775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        return nativeHasMipMap(mNativePtr);
1524713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy    }
1525713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy
1526713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy    /**
1527713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * Set a hint for the renderer responsible for drawing this bitmap
1528713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * indicating that it should attempt to use mipmaps when this bitmap
1529713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * is drawn scaled down.
1530713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     *
1531713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * If you know that you are going to draw this bitmap at less than
1532713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * 50% of its original size, you may be able to obtain a higher
1533713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * quality by turning this property on.
1534f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
1535713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * Note that if the renderer respects this hint it might have to
1536713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * allocate extra memory to hold the mipmap levels for this bitmap.
1537713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     *
1538713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * This property is only a suggestion that can be ignored by the
1539713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * renderer. It is not guaranteed to have any effect.
1540713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     *
1541713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * @param hasMipMap indicates whether the renderer should attempt
1542713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     *                  to use mipmaps
1543713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     *
1544713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     * @see #hasMipMap()
1545713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy     */
1546713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy    public final void setHasMipMap(boolean hasMipMap) {
15473e776dee3e8af646cdcfb7a60e0e301c99f05293John Reck        checkRecycled("setHasMipMap called on a recycled bitmap");
1548775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        nativeSetHasMipMap(mNativePtr, hasMipMap);
1549713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy    }
1550713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy
1551713e1bb9df6bdfc21bd5c40d1a6ecf6c822a4be5Romain Guy    /**
1552efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy     * Returns the color space associated with this bitmap. If the color
1553efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy     * space is unknown, this method returns null.
1554efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy     */
1555efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy    @Nullable
1556efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy    public final ColorSpace getColorSpace() {
1557efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy        // A reconfigure can change the configuration and rgba16f is
1558efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy        // always linear scRGB at this time
1559efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy        if (getConfig() == Config.RGBA_F16) {
1560efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy            // Reset the color space for potential future reconfigurations
1561efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy            mColorSpace = null;
1562efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy            return ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB);
1563efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy        }
1564efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy
1565efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy        // Cache the color space retrieval since it can be fairly expensive
1566efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy        if (mColorSpace == null) {
1567efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy            if (nativeIsSRGB(mNativePtr)) {
1568efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                mColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
1569efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy            } else {
1570efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                float[] xyz = new float[9];
1571efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                float[] params = new float[7];
1572efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy
1573efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                boolean hasColorSpace = nativeGetColorSpace(mNativePtr, xyz, params);
1574efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                if (hasColorSpace) {
1575efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                    ColorSpace.Rgb.TransferParameters parameters =
1576efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                            new ColorSpace.Rgb.TransferParameters(
1577efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                                    params[0], params[1], params[2],
1578efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                                    params[3], params[4], params[5], params[6]);
1579efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                    ColorSpace cs = ColorSpace.match(xyz, parameters);
1580efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                    if (cs != null) {
1581efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                        mColorSpace = cs;
1582efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                    } else {
1583efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                        mColorSpace = new ColorSpace.Rgb("Unknown", xyz, parameters);
1584efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                    }
1585efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy                }
1586efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy            }
1587efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy        }
1588efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy
1589efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy        return mColorSpace;
1590efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy    }
1591efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy
1592efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy    /**
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Fills the bitmap's pixels with the specified {@link Color}.
15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalStateException if the bitmap is not mutable.
15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
159780756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void eraseColor(@ColorInt int c) {
15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't erase a recycled bitmap");
15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isMutable()) {
16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException("cannot erase immutable bitmaps");
16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1602775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        nativeErase(mNativePtr, c);
16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the {@link Color} at the specified location. Throws an exception
16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if x or y are out of bounds (negative or >= to the width or height
1608ce217faddb4b40c1b3e698944da1951027080427Romain Guy     * respectively). The returned color is a non-premultiplied ARGB value in
1609ce217faddb4b40c1b3e698944da1951027080427Romain Guy     * the {@link ColorSpace.Named#SRGB sRGB} color space.
16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x    The x coordinate (0...width-1) of the pixel to return
16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y    The y coordinate (0...height-1) of the pixel to return
16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return     The argb {@link Color} at the specified coordinate
16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if x, y exceed the bitmap's bounds
161557eafc6f90a1ce2dd97079dd82b4b2f8dcd9e00fsergeyv     * @throws IllegalStateException if the bitmap's config is {@link Config#HARDWARE}
16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
161780756e38882720860db52f1fcc21fa1505a02abfTor Norbye    @ColorInt
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getPixel(int x, int y) {
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't call getPixel() on a recycled bitmap");
1620980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv        checkHardware("unable to getPixel(), "
1621980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv                + "pixel access is not supported on Config#HARDWARE bitmaps");
16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPixelAccess(x, y);
1623775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        return nativeGetPixel(mNativePtr, x, y);
16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16258cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns in pixels[] a copy of the data in the bitmap. Each value is
16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a packed int representing a {@link Color}. The stride parameter allows
16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the caller to allow for gaps in the returned pixels array between
16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * rows. For normal packed results, just pass width for the stride value.
1631ce217faddb4b40c1b3e698944da1951027080427Romain Guy     * The returned colors are non-premultiplied ARGB values in the
1632ce217faddb4b40c1b3e698944da1951027080427Romain Guy     * {@link ColorSpace.Named#SRGB sRGB} color space.
16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pixels   The array to receive the bitmap's colors
16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset   The first index to write into pixels[]
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stride   The number of entries in pixels[] to skip between
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 rows (must be >= bitmap's width). Can be negative.
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x        The x coordinate of the first pixel to read from
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the bitmap
16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y        The y coordinate of the first pixel to read from
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the bitmap
16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The number of pixels to read from each row
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The number of rows to read
16443849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     *
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if x, y, width, height exceed the
16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         bounds of the bitmap, or if abs(stride) < width.
16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws ArrayIndexOutOfBoundsException if the pixels array is too small
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         to receive the specified number of pixels.
164957eafc6f90a1ce2dd97079dd82b4b2f8dcd9e00fsergeyv     * @throws IllegalStateException if the bitmap's config is {@link Config#HARDWARE}
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
165180756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void getPixels(@ColorInt int[] pixels, int offset, int stride,
16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          int x, int y, int width, int height) {
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't call getPixels() on a recycled bitmap");
1654980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv        checkHardware("unable to getPixels(), "
1655980bead518fc5ddb52ae8d00258f91b087c1f91asergeyv                + "pixel access is not supported on Config#HARDWARE bitmaps");
16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width == 0 || height == 0) {
16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return; // nothing to do
16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPixelsAccess(x, y, width, height, offset, stride, pixels);
1660775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        nativeGetPixels(mNativePtr, pixels, offset, stride,
166157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                        x, y, width, height);
16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16638cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shared code to check for illegal arguments passed to getPixel()
16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or setPixel()
1667f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x x coordinate of the pixel
16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y y coordinate of the pixel
16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void checkPixelAccess(int x, int y) {
16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkXYSign(x, y);
16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (x >= getWidth()) {
16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("x must be < bitmap.width()");
16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (y >= getHeight()) {
16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("y must be < bitmap.height()");
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shared code to check for illegal arguments passed to getPixels()
16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or setPixels()
16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x left edge of the area of pixels to access
16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y top edge of the area of pixels to access
16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width width of the area of pixels to access
16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height height of the area of pixels to access
16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset offset into pixels[] array
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stride number of elements in pixels[] between each logical row
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pixels array to hold the area of pixels being accessed
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    */
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void checkPixelsAccess(int x, int y, int width, int height,
16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   int offset, int stride, int pixels[]) {
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkXYSign(x, y);
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width < 0) {
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("width must be >= 0");
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height < 0) {
17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("height must be >= 0");
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (x + width > getWidth()) {
17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "x + width must be <= bitmap.width()");
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (y + height > getHeight()) {
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "y + height must be <= bitmap.height()");
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Math.abs(stride) < width) {
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("abs(stride) must be >= width");
17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int lastScanline = offset + (height - 1) * stride;
17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int length = pixels.length;
17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (offset < 0 || (offset + width > length)
17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || lastScanline < 0
17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || (lastScanline + width > length)) {
17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new ArrayIndexOutOfBoundsException();
17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17218cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17233849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * <p>Write the specified {@link Color} into the bitmap (assuming it is
17243849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * mutable) at the x,y coordinate. The color must be a
1725ce217faddb4b40c1b3e698944da1951027080427Romain Guy     * non-premultiplied ARGB value in the {@link ColorSpace.Named#SRGB sRGB}
1726ce217faddb4b40c1b3e698944da1951027080427Romain Guy     * color space.</p>
17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x     The x coordinate of the pixel to replace (0...width-1)
17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y     The y coordinate of the pixel to replace (0...height-1)
17303849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * @param color The ARGB color to write into the bitmap
17313849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     *
17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalStateException if the bitmap is not mutable
17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if x, y are outside of the bitmap's
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         bounds.
17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
173680756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void setPixel(int x, int y, @ColorInt int color) {
17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't call setPixel() on a recycled bitmap");
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isMutable()) {
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException();
17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPixelAccess(x, y);
1742775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        nativeSetPixel(mNativePtr, x, y, color);
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17448cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17463849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     * <p>Replace pixels in the bitmap with the colors in the array. Each element
17479505a6552764461c22ce48f1ac13d025d23e1579Romain Guy     * in the array is a packed int representing a non-premultiplied ARGB
1748ce217faddb4b40c1b3e698944da1951027080427Romain Guy     * {@link Color} in the {@link ColorSpace.Named#SRGB sRGB} color space.</p>
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param pixels   The colors to write to the bitmap
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offset   The index of the first color to read from pixels[]
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stride   The number of colors in pixels[] to skip between rows.
17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 Normally this value will be the same as the width of
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the bitmap, but it can be larger (or negative).
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x        The x coordinate of the first pixel to write to in
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the bitmap.
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y        The y coordinate of the first pixel to write to in
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 the bitmap.
17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width    The number of colors to copy from pixels[] per row
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height   The number of rows to write to the bitmap
17613849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy     *
17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalStateException if the bitmap is not mutable
17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IllegalArgumentException if x, y, width, height are outside of
17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         the bitmap's bounds.
17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws ArrayIndexOutOfBoundsException if the pixels array is too small
17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         to receive the specified number of pixels.
17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
176880756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void setPixels(@ColorInt int[] pixels, int offset, int stride,
17693849f93b3c2b29ca3873b602897dccac039a0b98Romain Guy            int x, int y, int width, int height) {
17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't call setPixels() on a recycled bitmap");
17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isMutable()) {
17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalStateException();
17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width == 0 || height == 0) {
17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return; // nothing to do
17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPixelsAccess(x, y, width, height, offset, stride, pixels);
1778775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        nativeSetPixels(mNativePtr, pixels, offset, stride,
177957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                        x, y, width, height);
17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17818cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final Parcelable.Creator<Bitmap> CREATOR
17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            = new Parcelable.Creator<Bitmap>() {
17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Rebuilds a bitmap previously stored with writeToParcel().
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param p    Parcel object to read the bitmap from
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return a new bitmap created from the data in the parcel
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Bitmap createFromParcel(Parcel p) {
17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Bitmap bm = nativeCreateFromParcel(p);
17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (bm == null) {
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new RuntimeException("Failed to unparcel Bitmap");
17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return bm;
17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Bitmap[] newArray(int size) {
17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new Bitmap[size];
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * No special parcel contents.
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int describeContents() {
1806b6377170960d40e66858d8b4d335a95eac773762Bart Sears        return 0;
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Write the bitmap and its pixels to the parcel. The bitmap can be
18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * rebuilt from the parcel by calling CREATOR.createFromParcel().
1812f161dce70eab5ba1011bd26226c14e31675d5955sergeyv     *
1813f161dce70eab5ba1011bd26226c14e31675d5955sergeyv     * If this bitmap is {@link Config#HARDWARE}, it may be unparceled with a different pixel
1814f161dce70eab5ba1011bd26226c14e31675d5955sergeyv     * format (e.g. 565, 8888), but the content will be preserved to the best quality permitted
1815f161dce70eab5ba1011bd26226c14e31675d5955sergeyv     * by the final pixel format
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p    Parcel object to write the bitmap data into
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void writeToParcel(Parcel p, int flags) {
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't parcel a recycled bitmap");
18209fd259c9b0878ba52fec86173d76976e70977fcdsergeyv        noteHardwareBitmapSlowCall();
1821775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        if (!nativeWriteToParcel(mNativePtr, mIsMutable, mDensity, p)) {
18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("native writeToParcel failed");
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a new bitmap that captures the alpha values of the original.
18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This may be drawn with Canvas.drawBitmap(), where the color(s) will be
18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * taken from the paint that is passed to the draw call.
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return new bitmap containing the alpha channel of the original bitmap.
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18331c2bf03d1082fc6b7eb42cbd163c60c07cf2bcccTor Norbye    @CheckResult
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Bitmap extractAlpha() {
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return extractAlpha(null, null);
18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18378cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a new bitmap that captures the alpha values of the original.
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * These values may be affected by the optional Paint parameter, which
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can contain its own alpha, and may also contain a MaskFilter which
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * could change the actual dimensions of the resulting bitmap (e.g.
18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a blur maskfilter might enlarge the resulting bitmap). If offsetXY
18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is not null, it returns the amount to offset the returned bitmap so
18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that it will logically align with the original. For example, if the
18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * paint contains a blur of radius 2, then offsetXY[] would contains
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * -2, -2, so that drawing the alpha bitmap offset by (-2, -2) and then
18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * drawing the original would result in the blur visually aligning with
18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the original.
1850f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
185196e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn     * <p>The initial density of the returned bitmap is the same as the original's.
1852f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck     *
18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param paint Optional paint used to modify the alpha values in the
18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              resulting bitmap. Pass null for default behavior.
18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param offsetXY Optional array that returns the X (index 0) and Y
18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 (index 1) offset needed to position the returned bitmap
18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                 so that it visually lines up with the original.
18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return new bitmap containing the (optionally modified by paint) alpha
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         channel of the original bitmap. This may be drawn with
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         Canvas.drawBitmap(), where the color(s) will be taken from the
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         paint that is passed to the draw call.
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18631c2bf03d1082fc6b7eb42cbd163c60c07cf2bcccTor Norbye    @CheckResult
18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Bitmap extractAlpha(Paint paint, int[] offsetXY) {
18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkRecycled("Can't extractAlpha on a recycled bitmap");
1866dfba4d3d11bbf47dff45f94d61d4d97510b3034aDerek Sollenberger        long nativePaint = paint != null ? paint.getNativeInstance() : 0;
18679fd259c9b0878ba52fec86173d76976e70977fcdsergeyv        noteHardwareBitmapSlowCall();
1868775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        Bitmap bm = nativeExtractAlpha(mNativePtr, nativePaint, offsetXY);
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bm == null) {
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("Failed to extractAlpha on Bitmap");
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
187296e240f25a97c10bba863df328ed73a82c34ff61Dianne Hackborn        bm.mDensity = mDensity;
18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return bm;
18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18768cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen    /**
187776d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed     *  Given another bitmap, return true if it has the same dimensions, config,
187876d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed     *  and pixel data as this bitmap. If any of those differ, return false.
187976d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed     *  If other is null, return false.
188076d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed     */
188176d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed    public boolean sameAs(Bitmap other) {
18829298c5414172344f2462beda70e624af5f774483John Reck        checkRecycled("Can't call sameAs on a recycled bitmap!");
18839fd259c9b0878ba52fec86173d76976e70977fcdsergeyv        noteHardwareBitmapSlowCall();
18843df4869a77bdeb72d5810bbcf7819ed1b8dd0ec7John Reck        if (this == other) return true;
18853df4869a77bdeb72d5810bbcf7819ed1b8dd0ec7John Reck        if (other == null) return false;
1886e1fc36d197639ee13194de74b2e7e42c39b12286sergeyv        other.noteHardwareBitmapSlowCall();
18879298c5414172344f2462beda70e624af5f774483John Reck        if (other.isRecycled()) {
18889298c5414172344f2462beda70e624af5f774483John Reck            throw new IllegalArgumentException("Can't compare to a recycled bitmap!");
18899298c5414172344f2462beda70e624af5f774483John Reck        }
1890775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler        return nativeSameAs(mNativePtr, other.mNativePtr);
189176d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed    }
189276d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed
189376d1e01d5e65c4631c827831e98ad4e300d99eabMike Reed    /**
1894b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * Builds caches associated with the bitmap that are used for drawing it.
1895b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     *
1896b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * <p>Starting in {@link android.os.Build.VERSION_CODES#N}, this call initiates an asynchronous
1897b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * upload to the GPU on RenderThread, if the Bitmap is not already uploaded. With Hardware
1898b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * Acceleration, Bitmaps must be uploaded to the GPU in order to be rendered. This is done by
1899b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * default the first time a Bitmap is drawn, but the process can take several milliseconds,
1900b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * depending on the size of the Bitmap. Each time a Bitmap is modified and drawn again, it must
1901b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * be re-uploaded.</p>
1902b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     *
1903b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * <p>Calling this method in advance can save time in the first frame it's used. For example, it
1904b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * is recommended to call this on an image decoding worker thread when a decoded Bitmap is about
1905b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * to be displayed. It is recommended to make any pre-draw modifications to the Bitmap before
1906b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * calling this method, so the cached, uploaded copy may be reused without re-uploading.</p>
1907b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     *
1908b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * In {@link android.os.Build.VERSION_CODES#KITKAT} and below, for purgeable bitmaps, this call
1909b1d2f0a1d0900ba5651f98021b4b7b4229ebb490Chris Craik     * would attempt to ensure that the pixels have been decoded.
19108cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen     */
19118cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen    public void prepareToDraw() {
1912ad57442fd00e7fd7f1885d23372ec5c85e176820John Reck        checkRecycled("Can't prepareToDraw on a recycled bitmap!");
19134387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck        // Kick off an update/upload of the bitmap outside of the normal
19144387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck        // draw path.
19154387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck        nativePrepareToDraw(mNativePtr);
1916f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck    }
1917f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck
19186e3658a63843096058ed444d073fbcd191fd7e1bsergeyv    /**
19196e3658a63843096058ed444d073fbcd191fd7e1bsergeyv     *
19206e3658a63843096058ed444d073fbcd191fd7e1bsergeyv     * @return {@link GraphicBuffer} which is internally used by hardware bitmap
19216e3658a63843096058ed444d073fbcd191fd7e1bsergeyv     * @hide
19226e3658a63843096058ed444d073fbcd191fd7e1bsergeyv     */
19236e3658a63843096058ed444d073fbcd191fd7e1bsergeyv    public GraphicBuffer createGraphicBufferHandle() {
19246e3658a63843096058ed444d073fbcd191fd7e1bsergeyv        return nativeCreateGraphicBufferHandle(mNativePtr);
19256e3658a63843096058ed444d073fbcd191fd7e1bsergeyv    }
19266e3658a63843096058ed444d073fbcd191fd7e1bsergeyv
19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //////////// native methods
19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeCreate(int[] colors, int offset,
19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                              int stride, int width, int height,
19318242656f495847c50c9ceaea92839dce78218a75Romain Guy                                              int nativeConfig, boolean mutable,
19328242656f495847c50c9ceaea92839dce78218a75Romain Guy                                              @Nullable @Size(9) float[] xyzD50,
19338242656f495847c50c9ceaea92839dce78218a75Romain Guy                                              @Nullable ColorSpace.Rgb.TransferParameters p);
193436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native Bitmap nativeCopy(long nativeSrcBitmap, int nativeConfig,
19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            boolean isMutable);
1936721ae5fec5f1fd4f93aa2a361a0ac298e15ce353Riley Andrews    private static native Bitmap nativeCopyAshmem(long nativeSrcBitmap);
1937a5fdde9d15fbdf1aaeb61e1cf0c128af3aeb7b67Winson    private static native Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig);
1938775873a66a946fae2b0535abb51df9817bd1b20cRichard Uhler    private static native long nativeGetNativeFinalizer();
193936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeRecycle(long nativeBitmap);
194036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeReconfigure(long nativeBitmap, int width, int height,
19414508218850faedea95371188da587b6734f5f3dasergeyv                                                 int config, boolean isPremultiplied);
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
194336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeCompress(long nativeBitmap, int format,
19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            int quality, OutputStream stream,
19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                            byte[] tempStorage);
194636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeErase(long nativeBitmap, int color);
194736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native int nativeRowBytes(long nativeBitmap);
194836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native int nativeConfig(long nativeBitmap);
19498cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
195057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    private static native int nativeGetPixel(long nativeBitmap, int x, int y);
195136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeGetPixels(long nativeBitmap, int[] pixels,
19521abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik                                               int offset, int stride, int x, int y,
195357ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                                               int width, int height);
19548cdcb12752b716d0407733fecefcf1d9e926310aWei-Ta Chen
195557ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    private static native void nativeSetPixel(long nativeBitmap, int x, int y, int color);
195636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeSetPixels(long nativeBitmap, int[] colors,
19571abf5d62429e5a9329520b2f7c2b5a5e7a8e72ecChris Craik                                               int offset, int stride, int x, int y,
195857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                                               int width, int height);
195936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeCopyPixelsToBuffer(long nativeBitmap,
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                        Buffer dst);
196136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeCopyPixelsFromBuffer(long nativeBitmap, Buffer src);
196236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native int nativeGenerationId(long nativeBitmap);
19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native Bitmap nativeCreateFromParcel(Parcel p);
19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // returns true on success
196636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeWriteToParcel(long nativeBitmap,
19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                      boolean isMutable,
1968de0dfb7b65a02d4dd74c271b558adee0973fc267Dianne Hackborn                                                      int density,
19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                      Parcel p);
19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // returns a new bitmap built from the native bitmap's alpha, and the paint
197136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native Bitmap nativeExtractAlpha(long nativeBitmap,
197236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                                    long nativePaint,
19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    int[] offsetXY);
19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
197536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeHasAlpha(long nativeBitmap);
197657ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    private static native boolean nativeIsPremultiplied(long nativeBitmap);
197757ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    private static native void nativeSetPremultiplied(long nativeBitmap,
197857ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                                                      boolean isPremul);
197957ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III    private static native void nativeSetHasAlpha(long nativeBitmap,
198057ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                                                 boolean hasAlpha,
198157ee620ced8caed1eb8651717f6a6d2d5f1f9a5bLeon Scroggins III                                                 boolean requestPremul);
198236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeHasMipMap(long nativeBitmap);
198336bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap);
198436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeSameAs(long nativeBitmap0, long nativeBitmap1);
19854387190d8ec9fe4e953fcfeb093a644b82cf85edJohn Reck    private static native void nativePrepareToDraw(long nativeBitmap);
19864508218850faedea95371188da587b6734f5f3dasergeyv    private static native int nativeGetAllocationByteCount(long nativeBitmap);
198781f97ee47ccf0d011cdc4f38b6ea5c45b70dedc0sergeyv    private static native Bitmap nativeCopyPreserveInternalConfig(long nativeBitmap);
19880a0f23163a7a62900d46c7f81d109320d73d6c6bsergeyv    private static native Bitmap nativeCreateHardwareBitmap(GraphicBuffer buffer);
19896e3658a63843096058ed444d073fbcd191fd7e1bsergeyv    private static native GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap);
1990efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy    private static native boolean nativeGetColorSpace(long nativePtr, float[] xyz, float[] params);
1991efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy    private static native boolean nativeIsSRGB(long nativePtr);
19928242656f495847c50c9ceaea92839dce78218a75Romain Guy    private static native void nativeCopyColorSpace(long srcBitmap, long dstBitmap);
19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1994