Bitmap_Delegate.java revision ec4118922fa844ef31b73d16adc76f4da4c6c8e6
1ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/*
2ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Copyright (C) 2010 The Android Open Source Project
3ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
4ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * you may not use this file except in compliance with the License.
6ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * You may obtain a copy of the License at
7ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
8ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
10ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Unless required by applicable law or agreed to in writing, software
11ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * See the License for the specific language governing permissions and
14ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * limitations under the License.
15ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */
16ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
17ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskipackage android.graphics;
18ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
19ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.ide.common.rendering.api.LayoutLog;
20ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.layoutlib.bridge.Bridge;
21ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.layoutlib.bridge.impl.DelegateManager;
22ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.resources.Density;
23ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.tools.layoutlib.annotations.LayoutlibDelegate;
24ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
25ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport android.graphics.Bitmap.Config;
26ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport android.os.Parcel;
27ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
28ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.Graphics2D;
29ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.image.BufferedImage;
30ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.io.File;
31ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.io.IOException;
32ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.io.InputStream;
33ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.io.OutputStream;
34ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.nio.Buffer;
35ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.Arrays;
36835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Guptaimport java.util.EnumSet;
37835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Guptaimport java.util.Set;
38ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
39ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport javax.imageio.ImageIO;
40ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
41ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/**
42ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Delegate implementing the native methods of android.graphics.Bitmap
43ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
44ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced
45ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * by calls to methods of the same name in this delegate class.
46ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
47ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * This class behaves like the original native implementation, but in Java, keeping previously
48ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * native data into its own objects and mapping them to int that are sent back and forth between
49ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * it and the original Bitmap class.
50ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
51ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see DelegateManager
52ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
53ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */
54ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskipublic final class Bitmap_Delegate {
55ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
56835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    public enum BitmapCreateFlags {
57835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        PREMULTIPLIED, MUTABLE
58835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    }
59835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta
60ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- delegate manager ----
61ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private static final DelegateManager<Bitmap_Delegate> sManager =
62ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            new DelegateManager<Bitmap_Delegate>(Bitmap_Delegate.class);
63ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
64ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- delegate helper data ----
65ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
66ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- delegate data ----
67ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private final Config mConfig;
68ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private BufferedImage mImage;
69ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private boolean mHasAlpha = true;
70ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private boolean mHasMipMap = false;      // TODO: check the default.
71ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private int mGenerationId = 0;
72ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
73ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
74ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- Public Helper methods ----
75ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
76ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
77ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Returns the native delegate associated to a given {@link Bitmap_Delegate} object.
78ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
79ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public static Bitmap_Delegate getDelegate(Bitmap bitmap) {
80ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return sManager.getDelegate(bitmap.mNativeBitmap);
81ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
82ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
83ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
84ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object.
85ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
86ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    public static Bitmap_Delegate getDelegate(long native_bitmap) {
87ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return sManager.getDelegate(native_bitmap);
88ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
89ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
90ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
91ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Creates and returns a {@link Bitmap} initialized with the given file content.
92ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     *
93ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param input the file from which to read the bitmap content
94ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param isMutable whether the bitmap is mutable
95ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param density the density associated with the bitmap
96ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     *
97ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @see Bitmap#isMutable()
98ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @see Bitmap#getDensity()
99ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
100ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public static Bitmap createBitmap(File input, boolean isMutable, Density density)
101ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            throws IOException {
102835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
103835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    }
104835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    /**
105835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * Creates and returns a {@link Bitmap} initialized with the given file content.
106835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     *
107835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @param input the file from which to read the bitmap content
108835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @param density the density associated with the bitmap
109835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     *
110835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @see Bitmap#isPremultiplied()
111835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @see Bitmap#isMutable()
112835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @see Bitmap#getDensity()
113835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     */
114835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    public static Bitmap createBitmap(File input, Set<BitmapCreateFlags> createFlags,
115835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta            Density density) throws IOException {
116ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // create a delegate with the content of the file.
117ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
118835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta
119835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        return createBitmap(delegate, createFlags, density.getDpiValue());
120ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
121ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
122ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
123ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Creates and returns a {@link Bitmap} initialized with the given stream content.
124ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     *
125ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param input the stream from which to read the bitmap content
126ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param isMutable whether the bitmap is mutable
127ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param density the density associated with the bitmap
128ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     *
129ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @see Bitmap#isMutable()
130ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @see Bitmap#getDensity()
131ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
132ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density)
133ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            throws IOException {
134835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
135835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    }
136835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta
137835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    /**
138835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * Creates and returns a {@link Bitmap} initialized with the given stream content.
139835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     *
140835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @param input the stream from which to read the bitmap content
141835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @param createFlags
142835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @param density the density associated with the bitmap
143835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     *
144835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @see Bitmap#isPremultiplied()
145835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @see Bitmap#isMutable()
146835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @see Bitmap#getDensity()
147835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     */
148835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    public static Bitmap createBitmap(InputStream input, Set<BitmapCreateFlags> createFlags,
149835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta            Density density) throws IOException {
150ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // create a delegate with the content of the stream.
151ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
152ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
153835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        return createBitmap(delegate, createFlags, density.getDpiValue());
154ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
155ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
156ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
157ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
158ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     *
159ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param image the bitmap content
160ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param isMutable whether the bitmap is mutable
161ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param density the density associated with the bitmap
162ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     *
163ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @see Bitmap#isMutable()
164ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @see Bitmap#getDensity()
165ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
166ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public static Bitmap createBitmap(BufferedImage image, boolean isMutable,
167ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            Density density) throws IOException {
168835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density);
169835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    }
170835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta
171835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    /**
172835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
173835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     *
174835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @param image the bitmap content
175835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @param createFlags
176835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @param density the density associated with the bitmap
177835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     *
178835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @see Bitmap#isMutable()
179835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     * @see Bitmap#getDensity()
180835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta     */
181835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags,
182835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta            Density density) throws IOException {
183ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // create a delegate with the given image.
184ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
185ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
186835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        return createBitmap(delegate, createFlags, density.getDpiValue());
187ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
188ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
189ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
190ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
191ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
192ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public static BufferedImage getImage(Bitmap bitmap) {
193ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
194ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(bitmap.mNativeBitmap);
195ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
196ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return null;
197ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
198ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
199ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return delegate.mImage;
200ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
201ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
202ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public static int getBufferedImageType(int nativeBitmapConfig) {
203ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        switch (Config.nativeToConfig(nativeBitmapConfig)) {
204ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            case ALPHA_8:
205ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                return BufferedImage.TYPE_INT_ARGB;
206ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            case RGB_565:
207ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                return BufferedImage.TYPE_INT_ARGB;
208ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            case ARGB_4444:
209ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                return BufferedImage.TYPE_INT_ARGB;
210ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            case ARGB_8888:
211ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                return BufferedImage.TYPE_INT_ARGB;
212ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
213ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
214ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return BufferedImage.TYPE_INT_ARGB;
215ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
216ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
217ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
218ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
219ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
220ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public BufferedImage getImage() {
221ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return mImage;
222ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
223ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
224ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
225ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Returns the Android bitmap config. Note that this not the config of the underlying
226ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Java2D bitmap.
227ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
228ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public Config getConfig() {
229ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return mConfig;
230ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
231ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
232ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
233ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Returns the hasAlpha rendering hint
234ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @return true if the bitmap alpha should be used at render time
235ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
236ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public boolean hasAlpha() {
237ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return mHasAlpha && mConfig != Config.RGB_565;
238ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
239ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
240ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public boolean hasMipMap() {
241ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // TODO: check if more checks are required as in hasAlpha.
242ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return mHasMipMap;
243ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
244ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
245ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Update the generationId.
246ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     *
247ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @see Bitmap#getGenerationId()
248ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
249ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public void change() {
250ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        mGenerationId++;
251ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
252ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
253ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- native methods ----
254ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
255ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
256ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
257835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta            int height, int nativeConfig, boolean isMutable) {
258ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int imageType = getBufferedImageType(nativeConfig);
259ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
260ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // create the image
261ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage image = new BufferedImage(width, height, imageType);
262ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
263ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (colors != null) {
264ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            image.setRGB(0, 0, width, height, colors, offset, stride);
265ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
266ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
267ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // create a delegate with the content of the stream.
268ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
269ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
270835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
271835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta                Bitmap.getDefaultDensity());
272ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
273ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
274ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
275ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static Bitmap nativeCopy(long srcBitmap, int nativeConfig, boolean isMutable) {
276ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(srcBitmap);
277ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (srcBmpDelegate == null) {
278ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return null;
279ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
280ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
281ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage srcImage = srcBmpDelegate.getImage();
282ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
283ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int width = srcImage.getWidth();
284ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int height = srcImage.getHeight();
285ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
286ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int imageType = getBufferedImageType(nativeConfig);
287ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
288ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // create the image
289ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage image = new BufferedImage(width, height, imageType);
290ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
291ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // copy the source image into the image.
292ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int[] argb = new int[width * height];
293ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        srcImage.getRGB(0, 0, width, height, argb, 0, width);
294ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        image.setRGB(0, 0, width, height, argb, 0, width);
295ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
296ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // create a delegate with the content of the stream.
297ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
298ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
299835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
300835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta                Bitmap.getDefaultDensity());
301ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
302ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
303ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
304ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeDestructor(long nativeBitmap) {
305ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        sManager.removeJavaReferenceFor(nativeBitmap);
306ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
307ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
308ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
309ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeRecycle(long nativeBitmap) {
310ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        sManager.removeJavaReferenceFor(nativeBitmap);
311ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
312ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
313ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
314ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static boolean nativeCompress(long nativeBitmap, int format, int quality,
315ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            OutputStream stream, byte[] tempStorage) {
316ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
317ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "Bitmap.compress() is not supported", null /*data*/);
318ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return true;
319ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
320ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
321ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
322ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeErase(long nativeBitmap, int color) {
323ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
324ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
325ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
326ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
327ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
328ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
329ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage image = delegate.mImage;
330ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
331ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Graphics2D g = image.createGraphics();
332ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        try {
333ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            g.setColor(new java.awt.Color(color, true));
334ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
335ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            g.fillRect(0, 0, image.getWidth(), image.getHeight());
336ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        } finally {
337ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            g.dispose();
338ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
339ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
340ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
341ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
342ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static int nativeWidth(long nativeBitmap) {
343ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
344ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
345ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
346ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
347ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
348ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
349ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return delegate.mImage.getWidth();
350ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
351ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
352ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
353ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static int nativeHeight(long nativeBitmap) {
354ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
355ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
356ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
357ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
358ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
359ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
360ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return delegate.mImage.getHeight();
361ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
362ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
363ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
364ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static int nativeRowBytes(long nativeBitmap) {
365ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
366ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
367ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
368ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
369ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
370ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
371ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return delegate.mImage.getWidth();
372ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
373ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
374ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
375ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static int nativeConfig(long nativeBitmap) {
376ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
377ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
378ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
379ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
380ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
381ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
382ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return delegate.mConfig.nativeInt;
383ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
384ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
385ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
386ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static boolean nativeHasAlpha(long nativeBitmap) {
387ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
388ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
389ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
390ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return true;
391ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
392ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
393ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return delegate.mHasAlpha;
394ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
395ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
396ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
397ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static boolean nativeHasMipMap(long nativeBitmap) {
398ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
399ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
400ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
401ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return true;
402ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
403ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
404ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return delegate.mHasMipMap;
405ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
406ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
407ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
408ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static int nativeGetPixel(long nativeBitmap, int x, int y) {
409ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
410ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
411ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
412ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
413ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
414ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
415ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return delegate.mImage.getRGB(x, y);
416ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
417ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
418ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
419ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeGetPixels(long nativeBitmap, int[] pixels, int offset,
420ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            int stride, int x, int y, int width, int height) {
421ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
422ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
423ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
424ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
425ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
426ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        delegate.getImage().getRGB(x, y, width, height, pixels, offset, stride);
427ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
428ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
429ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
430ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
431ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeSetPixel(long nativeBitmap, int x, int y, int color) {
432ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
433ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
434ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
435ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
436ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
437ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        delegate.getImage().setRGB(x, y, color);
438ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
439ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
440ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
441ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeSetPixels(long nativeBitmap, int[] colors, int offset,
442ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            int stride, int x, int y, int width, int height) {
443ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
444ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
445ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
446ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
447ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
448ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        delegate.getImage().setRGB(x, y, width, height, colors, offset, stride);
449ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
450ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
451ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
452ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeCopyPixelsToBuffer(long nativeBitmap, Buffer dst) {
453ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // FIXME implement native delegate
454ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
455ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "Bitmap.copyPixelsToBuffer is not supported.", null, null /*data*/);
456ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
457ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
458ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
459ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeCopyPixelsFromBuffer(long nb, Buffer src) {
460ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // FIXME implement native delegate
461ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
462ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "Bitmap.copyPixelsFromBuffer is not supported.", null, null /*data*/);
463ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
464ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
465ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
466ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static int nativeGenerationId(long nativeBitmap) {
467ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
468ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
469ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
470ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
471ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
472ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return delegate.mGenerationId;
473ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
474ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
475ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
476ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) {
477ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only
478ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // used during aidl call so really this should not be called.
479ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
480ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.",
481ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                null /*data*/);
482ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return null;
483ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
484ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
485ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
486ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static boolean nativeWriteToParcel(long nativeBitmap, boolean isMutable,
487ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            int density, Parcel p) {
488ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // This is only called when sending a bitmap through aidl, so really this should not
489ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // be called.
490ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
491ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.",
492ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                null /*data*/);
493ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return false;
494ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
495ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
496ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
497ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static Bitmap nativeExtractAlpha(long nativeBitmap, long nativePaint,
498ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            int[] offsetXY) {
499ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate bitmap = sManager.getDelegate(nativeBitmap);
500ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (bitmap == null) {
501ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return null;
502ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
503ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
504ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the paint which can be null if nativePaint is 0.
505ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
506ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
507ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (paint != null && paint.getMaskFilter() != null) {
508ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
509ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    "MaskFilter not supported in Bitmap.extractAlpha",
510ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    null, null /*data*/);
511ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
512ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
513ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int alpha = paint != null ? paint.getAlpha() : 0xFF;
514ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage image = createCopy(bitmap.getImage(), BufferedImage.TYPE_INT_ARGB, alpha);
515ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
516ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // create the delegate. The actual Bitmap config is only an alpha channel
517ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8);
518ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
519ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // the density doesn't matter, it's set by the Java method.
520835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE),
521ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                Density.DEFAULT_DENSITY /*density*/);
522ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
523ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
524ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
525ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativePrepareToDraw(long nativeBitmap) {
526ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // nothing to be done here.
527ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
528ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
529ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
530ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeSetHasAlpha(long nativeBitmap, boolean hasAlpha) {
531ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
532ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
533ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
534ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
535ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
536ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
537ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        delegate.mHasAlpha = hasAlpha;
538ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
539ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
540ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
541ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap) {
542ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
543ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
544ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate == null) {
545ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
546ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
547ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
548ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        delegate.mHasMipMap = hasMipMap;
549ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
550ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
551ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
552ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static boolean nativeSameAs(long nb0, long nb1) {
553ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate1 = sManager.getDelegate(nb0);
554ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate1 == null) {
555ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return false;
556ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
557ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
558ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate delegate2 = sManager.getDelegate(nb1);
559ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate2 == null) {
560ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return false;
561ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
562ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
563ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage image1 = delegate1.getImage();
564ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage image2 = delegate2.getImage();
565ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate1.mConfig != delegate2.mConfig ||
566ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                image1.getWidth() != image2.getWidth() ||
567ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                image1.getHeight() != image2.getHeight()) {
568ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return false;
569ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
570ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
571ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the internal data
572ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int w = image1.getWidth();
573ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int h = image2.getHeight();
574ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int[] argb1 = new int[w*h];
575ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int[] argb2 = new int[w*h];
576ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
577ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        image1.getRGB(0, 0, w, h, argb1, 0, w);
578ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        image2.getRGB(0, 0, w, h, argb2, 0, w);
579ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
580ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // compares
581ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (delegate1.mConfig == Config.ALPHA_8) {
582ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            // in this case we have to manually compare the alpha channel as the rest is garbage.
583ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            final int length = w*h;
584ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            for (int i = 0 ; i < length ; i++) {
585ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                if ((argb1[i] & 0xFF000000) != (argb2[i] & 0xFF000000)) {
586ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    return false;
587ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                }
588ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            }
589ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return true;
590ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
591ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
592ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return Arrays.equals(argb1, argb2);
593ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
594ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
595ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- Private delegate/helper methods ----
596ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
597ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private Bitmap_Delegate(BufferedImage image, Config config) {
598ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        mImage = image;
599ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        mConfig = config;
600ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
601ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
602835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    private static Bitmap createBitmap(Bitmap_Delegate delegate,
603835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta            Set<BitmapCreateFlags> createFlags, int density) {
604ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get its native_int
605ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath        long nativeInt = sManager.addNewDelegate(delegate);
606ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
607835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        int width = delegate.mImage.getWidth();
608835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        int height = delegate.mImage.getHeight();
609835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        boolean isMutable = createFlags.contains(BitmapCreateFlags.MUTABLE);
610835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        boolean isPremultiplied = createFlags.contains(BitmapCreateFlags.PREMULTIPLIED);
611835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta
612ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // and create/return a new Bitmap with it
613835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        return new Bitmap(nativeInt, null /* buffer */, width, height, density, isMutable,
614835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta                          isPremultiplied, null /*ninePatchChunk*/, null /* layoutBounds */);
615ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
616ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
617835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) {
618835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        Set<BitmapCreateFlags> createFlags =  EnumSet.of(BitmapCreateFlags.PREMULTIPLIED);
619835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        if (isMutable) {
620835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta            createFlags.add(BitmapCreateFlags.MUTABLE);
621835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        }
622835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta        return createFlags;
623835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta    }
624ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
625ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Creates and returns a copy of a given BufferedImage.
626ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * <p/>
627ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * if alpha is different than 255, then it is applied to the alpha channel of each pixel.
628ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     *
629ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param image the image to copy
630ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param imageType the type of the new image
631ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param alpha an optional alpha modifier
632ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @return a new BufferedImage
633ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
634ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /*package*/ static BufferedImage createCopy(BufferedImage image, int imageType, int alpha) {
635ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int w = image.getWidth();
636ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int h = image.getHeight();
637ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
638ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage result = new BufferedImage(w, h, imageType);
639ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
640ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int[] argb = new int[w * h];
641ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
642ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
643ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (alpha != 255) {
644ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            final int length = argb.length;
645ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            for (int i = 0 ; i < length; i++) {
646ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                int a = (argb[i] >>> 24 * alpha) / 255;
647ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                argb[i] = (a << 24) | (argb[i] & 0x00FFFFFF);
648ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            }
649ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
650ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
651ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        result.setRGB(0, 0, w, h, argb, 0, w);
652ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
653ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return result;
654ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
655ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
656ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski}
657