15de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet/*
25de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * Copyright (C) 2010 The Android Open Source Project
35de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *
45de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License");
55de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * you may not use this file except in compliance with the License.
65de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * You may obtain a copy of the License at
75de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *
85de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *      http://www.apache.org/licenses/LICENSE-2.0
95de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *
105de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * Unless required by applicable law or agreed to in writing, software
115de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS,
125de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * See the License for the specific language governing permissions and
145de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * limitations under the License.
155de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet */
165de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
175de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetpackage android.graphics;
185de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
19918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohetimport com.android.ide.common.rendering.api.LayoutLog;
20b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohetimport com.android.layoutlib.bridge.Bridge;
21c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport com.android.layoutlib.bridge.impl.DelegateManager;
2216584225125acba18b74920b902c798dfead0328Xavier Ducrohetimport com.android.resources.Density;
239a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohetimport com.android.tools.layoutlib.annotations.LayoutlibDelegate;
245de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
255de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetimport android.graphics.Bitmap.Config;
265de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetimport android.os.Parcel;
275de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
285de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetimport java.awt.Graphics2D;
295de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetimport java.awt.image.BufferedImage;
305de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetimport java.io.File;
315de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetimport java.io.IOException;
325de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetimport java.io.InputStream;
335de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetimport java.io.OutputStream;
345de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetimport java.nio.Buffer;
35b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohetimport java.util.Arrays;
36490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Guptaimport java.util.EnumSet;
37490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Guptaimport java.util.Set;
385de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
395de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetimport javax.imageio.ImageIO;
405de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
415de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet/**
425de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * Delegate implementing the native methods of android.graphics.Bitmap
435de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *
445de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced
455de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * by calls to methods of the same name in this delegate class.
465de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *
475de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * This class behaves like the original native implementation, but in Java, keeping previously
485de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * native data into its own objects and mapping them to int that are sent back and forth between
495de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * it and the original Bitmap class.
505de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *
515de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * @see DelegateManager
525de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *
535de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet */
54d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetpublic final class Bitmap_Delegate {
555de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
56490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    public enum BitmapCreateFlags {
57490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        PREMULTIPLIED, MUTABLE
58490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    }
59490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta
605de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- delegate manager ----
615de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    private static final DelegateManager<Bitmap_Delegate> sManager =
62f0a53435f14d23d9555fc46014352ee6a7baa647Xavier Ducrohet            new DelegateManager<Bitmap_Delegate>(Bitmap_Delegate.class);
635de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
645de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- delegate helper data ----
655de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
665de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- delegate data ----
6763fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet    private final Config mConfig;
685de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    private BufferedImage mImage;
695de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    private boolean mHasAlpha = true;
70279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta    private boolean mHasMipMap = false;      // TODO: check the default.
71b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    private int mGenerationId = 0;
725de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
7363fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet
745de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- Public Helper methods ----
755de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
765de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /**
779f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     * Returns the native delegate associated to a given {@link Bitmap_Delegate} object.
789f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     */
799f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    public static Bitmap_Delegate getDelegate(Bitmap bitmap) {
809f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet        return sManager.getDelegate(bitmap.mNativeBitmap);
819f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    }
829f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet
839f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    /**
849f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object.
859f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     */
869f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    public static Bitmap_Delegate getDelegate(int native_bitmap) {
879f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet        return sManager.getDelegate(native_bitmap);
889f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    }
899f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet
909f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    /**
915de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     * Creates and returns a {@link Bitmap} initialized with the given file content.
922d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
932d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param input the file from which to read the bitmap content
942d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param isMutable whether the bitmap is mutable
952d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param density the density associated with the bitmap
962d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
972d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#isMutable()
982d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#getDensity()
995de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     */
10016584225125acba18b74920b902c798dfead0328Xavier Ducrohet    public static Bitmap createBitmap(File input, boolean isMutable, Density density)
1012d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet            throws IOException {
102490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
103490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    }
104490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta
105490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    /**
106490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * Creates and returns a {@link Bitmap} initialized with the given file content.
107490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     *
108490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @param input the file from which to read the bitmap content
109490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @param density the density associated with the bitmap
110490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     *
111490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @see Bitmap#isPremultiplied()
112490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @see Bitmap#isMutable()
113490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @see Bitmap#getDensity()
114490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     */
115490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    public static Bitmap createBitmap(File input, Set<BitmapCreateFlags> createFlags,
116490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta            Density density) throws IOException {
1175de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // create a delegate with the content of the file.
11863fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
1195de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
120490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        return createBitmap(delegate, createFlags, density.getDpiValue());
1215de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
1225de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
1235de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /**
1245de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     * Creates and returns a {@link Bitmap} initialized with the given stream content.
1252d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
1262d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param input the stream from which to read the bitmap content
1272d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param isMutable whether the bitmap is mutable
1282d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param density the density associated with the bitmap
1292d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
1302d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#isMutable()
1312d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#getDensity()
1325de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     */
13316584225125acba18b74920b902c798dfead0328Xavier Ducrohet    public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density)
1342d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet            throws IOException {
135490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
136490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    }
137490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta
138490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    /**
139490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * Creates and returns a {@link Bitmap} initialized with the given stream content.
140490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     *
141490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @param input the stream from which to read the bitmap content
142490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @param createFlags
143490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @param density the density associated with the bitmap
144490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     *
145490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @see Bitmap#isPremultiplied()
146490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @see Bitmap#isMutable()
147490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @see Bitmap#getDensity()
148490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     */
149490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    public static Bitmap createBitmap(InputStream input, Set<BitmapCreateFlags> createFlags,
150490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta            Density density) throws IOException {
1515de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // create a delegate with the content of the stream.
15263fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
1535de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
154490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        return createBitmap(delegate, createFlags, density.getDpiValue());
1555de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
1565de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
1575de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /**
1585de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
1592d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
1602d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param image the bitmap content
1612d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param isMutable whether the bitmap is mutable
1622d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param density the density associated with the bitmap
1632d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
1642d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#isMutable()
1652d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#getDensity()
1665de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     */
167ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet    public static Bitmap createBitmap(BufferedImage image, boolean isMutable,
16816584225125acba18b74920b902c798dfead0328Xavier Ducrohet            Density density) throws IOException {
169490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density);
170490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    }
171490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta
172490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    /**
173490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
174490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     *
175490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @param image the bitmap content
176490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @param createFlags
177490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @param density the density associated with the bitmap
178490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     *
179490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @see Bitmap#isPremultiplied()
180490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @see Bitmap#isMutable()
181490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     * @see Bitmap#getDensity()
182490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta     */
183490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags,
184490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta            Density density) throws IOException {
1855de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // create a delegate with the given image.
18663fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
1875de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
188490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        return createBitmap(delegate, createFlags, density.getDpiValue());
1895de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
1905de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
1915de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /**
1925de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
1935de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     */
1945de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    public static BufferedImage getImage(Bitmap bitmap) {
1955de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
1965de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(bitmap.mNativeBitmap);
1975de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
1985de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return null;
1995de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
2005de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2015de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return delegate.mImage;
2025de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
2035de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2045de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    public static int getBufferedImageType(int nativeBitmapConfig) {
2057f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet        switch (Config.nativeToConfig(nativeBitmapConfig)) {
2065de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            case ALPHA_8:
2075de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet                return BufferedImage.TYPE_INT_ARGB;
2085de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            case RGB_565:
2095de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet                return BufferedImage.TYPE_INT_ARGB;
2105de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            case ARGB_4444:
2115de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet                return BufferedImage.TYPE_INT_ARGB;
2125de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            case ARGB_8888:
2135de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet                return BufferedImage.TYPE_INT_ARGB;
2145de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
2155de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2165de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return BufferedImage.TYPE_INT_ARGB;
2175de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
2185de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2199f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    /**
2209f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
2219f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     */
2229f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    public BufferedImage getImage() {
2239f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet        return mImage;
2249f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    }
2259f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet
22663fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet    /**
22763fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet     * Returns the Android bitmap config. Note that this not the config of the underlying
22863fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet     * Java2D bitmap.
22963fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet     */
23063fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet    public Config getConfig() {
23163fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        return mConfig;
23263fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet    }
23363fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet
234b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    /**
235b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * Returns the hasAlpha rendering hint
236b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @return true if the bitmap alpha should be used at render time
237b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     */
238b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    public boolean hasAlpha() {
239b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return mHasAlpha && mConfig != Config.RGB_565;
240b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    }
241b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
242279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta    public boolean hasMipMap() {
243279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        // TODO: check if more checks are required as in hasAlpha.
244279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        return mHasMipMap;
245279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta    }
246b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    /**
247b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * Update the generationId.
248b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     *
249b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @see Bitmap#getGenerationId()
250b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     */
251b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    public void change() {
252b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        mGenerationId++;
253b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    }
25463fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet
2555de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- native methods ----
2565de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2579a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
2585de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
259490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta            int height, int nativeConfig, boolean isMutable) {
2605de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        int imageType = getBufferedImageType(nativeConfig);
2615de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2625de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // create the image
2635de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        BufferedImage image = new BufferedImage(width, height, imageType);
2645de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
265b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (colors != null) {
266b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            image.setRGB(0, 0, width, height, colors, offset, stride);
267b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
2685de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2695de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // create a delegate with the content of the stream.
2707f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
2715de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
272490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
273490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta                            Bitmap.getDefaultDensity());
2745de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
2755de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2769a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
2775de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static Bitmap nativeCopy(int srcBitmap, int nativeConfig, boolean isMutable) {
278b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(srcBitmap);
279b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (srcBmpDelegate == null) {
280b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return null;
281b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
282b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
283b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage srcImage = srcBmpDelegate.getImage();
284b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
285b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int width = srcImage.getWidth();
286b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int height = srcImage.getHeight();
287b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
288b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int imageType = getBufferedImageType(nativeConfig);
289b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
290b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // create the image
291b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage image = new BufferedImage(width, height, imageType);
292b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
293b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // copy the source image into the image.
294b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int[] argb = new int[width * height];
295b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        srcImage.getRGB(0, 0, width, height, argb, 0, width);
296b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        image.setRGB(0, 0, width, height, argb, 0, width);
297b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
298b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // create a delegate with the content of the stream.
2997f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
300b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
301490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
302490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta                Bitmap.getDefaultDensity());
3035de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3045de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3059a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3065de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeDestructor(int nativeBitmap) {
307cc4977d0fdaf657907912fd6cc2f9426dc8d2e36Xavier Ducrohet        sManager.removeJavaReferenceFor(nativeBitmap);
3085de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3095de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3109a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
31178cfdf31b7c48589ea3a148ec1d6d573235bc06bDeepanshu Gupta    /*package*/ static boolean nativeRecycle(int nativeBitmap) {
312cc4977d0fdaf657907912fd6cc2f9426dc8d2e36Xavier Ducrohet        sManager.removeJavaReferenceFor(nativeBitmap);
31378cfdf31b7c48589ea3a148ec1d6d573235bc06bDeepanshu Gupta        return true;
3145de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3155de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3169a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
31724541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta    /*package*/ static void nativeReconfigure(int nativeBitmap, int width, int height,
31824541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta            int config, int allocSize) {
31924541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
32024541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta                "Bitmap.reconfigure() is not supported", null /*data*/);
32124541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta    }
32224541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta
32324541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta    @LayoutlibDelegate
3245de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static boolean nativeCompress(int nativeBitmap, int format, int quality,
3255de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            OutputStream stream, byte[] tempStorage) {
326918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
32751a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                "Bitmap.compress() is not supported", null /*data*/);
328b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return true;
3295de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3305de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3319a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3325de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeErase(int nativeBitmap, int color) {
3335de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
3345de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
3355de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
3365de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return;
3375de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
3385de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3395de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        BufferedImage image = delegate.mImage;
3405de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3415de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Graphics2D g = image.createGraphics();
3425de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        try {
343b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            g.setColor(new java.awt.Color(color, true));
3445de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3455de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            g.fillRect(0, 0, image.getWidth(), image.getHeight());
3465de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        } finally {
3475de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            g.dispose();
3485de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
3495de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3505de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3519a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3525de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static int nativeRowBytes(int nativeBitmap) {
3535de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
3545de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
3555de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
3565de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return 0;
3575de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
3585de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3595de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return delegate.mImage.getWidth();
3605de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3615de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3629a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3635de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static int nativeConfig(int nativeBitmap) {
36463fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        // get the delegate from the native int.
36563fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
36663fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        if (delegate == null) {
36763fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet            return 0;
36863fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        }
36963fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet
37063fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        return delegate.mConfig.nativeInt;
3715de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3725de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3739a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3745de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static boolean nativeHasAlpha(int nativeBitmap) {
3755de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
3765de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
3775de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
3785de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return true;
3795de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
3805de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3815de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return delegate.mHasAlpha;
3825de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3835de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3849a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
385279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta    /*package*/ static boolean nativeHasMipMap(int nativeBitmap) {
386279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        // get the delegate from the native int.
387279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
388279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        if (delegate == null) {
389279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta            return true;
390279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        }
391279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta
392279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        return delegate.mHasMipMap;
393279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta    }
394279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta
395279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta    @LayoutlibDelegate
39624541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta    /*package*/ static int nativeGetPixel(int nativeBitmap, int x, int y,
39724541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta            boolean isPremultiplied) {
3985de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
3995de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
4005de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
4015de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return 0;
4025de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
4035de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
40424541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta        // TODO: Support isPremultiplied.
4055de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return delegate.mImage.getRGB(x, y);
4065de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4075de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4089a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4095de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeGetPixels(int nativeBitmap, int[] pixels, int offset,
41024541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta            int stride, int x, int y, int width, int height, boolean isPremultiplied) {
411b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
412b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate == null) {
413b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return;
414b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
415b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
416b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        delegate.getImage().getRGB(x, y, width, height, pixels, offset, stride);
4175de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4185de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4195de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4209a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
42124541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta    /*package*/ static void nativeSetPixel(int nativeBitmap, int x, int y, int color,
42224541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta            boolean isPremultiplied) {
423b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
424b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate == null) {
425b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return;
426b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
427b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
428b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        delegate.getImage().setRGB(x, y, color);
4295de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4305de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4319a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4325de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeSetPixels(int nativeBitmap, int[] colors, int offset,
43324541255c312ee34f9bf17eb5852cdffd4807065Deepanshu Gupta            int stride, int x, int y, int width, int height, boolean isPremultiplied) {
434b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
435b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate == null) {
436b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return;
437b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
438b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
439b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        delegate.getImage().setRGB(x, y, width, height, colors, offset, stride);
4405de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4415de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4429a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4435de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeCopyPixelsToBuffer(int nativeBitmap, Buffer dst) {
4445de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // FIXME implement native delegate
4458a80a8555238cc564f445f902aff5231993a8f96Xavier Ducrohet        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
4468a80a8555238cc564f445f902aff5231993a8f96Xavier Ducrohet                "Bitmap.copyPixelsToBuffer is not supported.", null, null /*data*/);
4475de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4485de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4499a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4505de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeCopyPixelsFromBuffer(int nb, Buffer src) {
4515de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // FIXME implement native delegate
4528a80a8555238cc564f445f902aff5231993a8f96Xavier Ducrohet        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
4538a80a8555238cc564f445f902aff5231993a8f96Xavier Ducrohet                "Bitmap.copyPixelsFromBuffer is not supported.", null, null /*data*/);
4545de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4555de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4569a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4575de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static int nativeGenerationId(int nativeBitmap) {
458b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
459b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate == null) {
460b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return 0;
461b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
462b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
463b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return delegate.mGenerationId;
4645de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4655de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4669a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4675de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) {
468b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only
469b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // used during aidl call so really this should not be called.
470918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
47151a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.",
47251a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                null /*data*/);
473b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return null;
4745de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4755de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4769a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4775de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static boolean nativeWriteToParcel(int nativeBitmap, boolean isMutable,
4785de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            int density, Parcel p) {
479b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // This is only called when sending a bitmap through aidl, so really this should not
480b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // be called.
481918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
48251a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.",
48351a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                null /*data*/);
484b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return false;
4855de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4865de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4879a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4885de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static Bitmap nativeExtractAlpha(int nativeBitmap, int nativePaint,
4895de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            int[] offsetXY) {
490b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate bitmap = sManager.getDelegate(nativeBitmap);
491b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (bitmap == null) {
492b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return null;
493b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
494b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
495d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        // get the paint which can be null if nativePaint is 0.
496d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
497b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
498d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        if (paint != null && paint.getMaskFilter() != null) {
499918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
500b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                    "MaskFilter not supported in Bitmap.extractAlpha",
50151a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                    null, null /*data*/);
502b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
5035de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
504b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int alpha = paint != null ? paint.getAlpha() : 0xFF;
505b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage image = createCopy(bitmap.getImage(), BufferedImage.TYPE_INT_ARGB, alpha);
506b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
507b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // create the delegate. The actual Bitmap config is only an alpha channel
508b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8);
509b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
510b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // the density doesn't matter, it's set by the Java method.
511490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE),
51216584225125acba18b74920b902c798dfead0328Xavier Ducrohet                Density.DEFAULT_DENSITY /*density*/);
513b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    }
5145de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
5159a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
5165de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativePrepareToDraw(int nativeBitmap) {
517b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // nothing to be done here.
5185de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
5195de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
5209a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
5215de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeSetHasAlpha(int nativeBitmap, boolean hasAlpha) {
5225de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
5235de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
5245de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
5255de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return;
5265de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
5275de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
5285de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        delegate.mHasAlpha = hasAlpha;
5295de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
5305de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
5319a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
532279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta    /*package*/ static void nativeSetHasMipMap(int nativeBitmap, boolean hasMipMap) {
533279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        // get the delegate from the native int.
534279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
535279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        if (delegate == null) {
536279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta            return;
537279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        }
538279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta
539279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta        delegate.mHasMipMap = hasMipMap;
540279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta    }
541279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta
542279c00e8e0abb20f7e10577c77937c058da080bfDeepanshu Gupta    @LayoutlibDelegate
5435de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static boolean nativeSameAs(int nb0, int nb1) {
544b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate1 = sManager.getDelegate(nb0);
545b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate1 == null) {
546b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return false;
547b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
548b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
549b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate2 = sManager.getDelegate(nb1);
550b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate2 == null) {
551b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return false;
552b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
553b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
554b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage image1 = delegate1.getImage();
555b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage image2 = delegate2.getImage();
556b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate1.mConfig != delegate2.mConfig ||
557b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                image1.getWidth() != image2.getWidth() ||
558b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                image1.getHeight() != image2.getHeight()) {
559b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return false;
560b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
561b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
562b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // get the internal data
563b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int w = image1.getWidth();
564b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int h = image2.getHeight();
565b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int[] argb1 = new int[w*h];
566b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int[] argb2 = new int[w*h];
567b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
568b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        image1.getRGB(0, 0, w, h, argb1, 0, w);
569b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        image2.getRGB(0, 0, w, h, argb2, 0, w);
570b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
571b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // compares
572b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate1.mConfig == Config.ALPHA_8) {
573b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            // in this case we have to manually compare the alpha channel as the rest is garbage.
574b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            final int length = w*h;
575b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            for (int i = 0 ; i < length ; i++) {
576b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                if ((argb1[i] & 0xFF000000) != (argb2[i] & 0xFF000000)) {
577b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                    return false;
578b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                }
579b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            }
580b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return true;
581b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
582b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
583b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return Arrays.equals(argb1, argb2);
5845de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
5855de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
5865de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- Private delegate/helper methods ----
5875de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
58863fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet    private Bitmap_Delegate(BufferedImage image, Config config) {
5895de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        mImage = image;
59063fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        mConfig = config;
5915de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
5925de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
593490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    private static Bitmap createBitmap(Bitmap_Delegate delegate,
594490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta            Set<BitmapCreateFlags> createFlags, int density) {
5955de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get its native_int
596cc4977d0fdaf657907912fd6cc2f9426dc8d2e36Xavier Ducrohet        int nativeInt = sManager.addNewDelegate(delegate);
5975de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
598490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        int width = delegate.mImage.getWidth();
599490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        int height = delegate.mImage.getHeight();
600490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        boolean isMutable = createFlags.contains(BitmapCreateFlags.MUTABLE);
601490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        boolean isPremultiplied = createFlags.contains(BitmapCreateFlags.PREMULTIPLIED);
602490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta
6035de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // and create/return a new Bitmap with it
604490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        return new Bitmap(nativeInt, null /* buffer */, width, height, density, isMutable,
605490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta                          isPremultiplied, null /*ninePatchChunk*/, null /* layoutBounds */);
606490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    }
607490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta
608490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta    private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) {
609490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        Set<BitmapCreateFlags> createFlags = EnumSet.of(BitmapCreateFlags.PREMULTIPLIED);
610490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        if (isMutable) {
611490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta            createFlags.add(BitmapCreateFlags.MUTABLE);
612490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        }
613490efa8bc4360e7dea3fe247f4fe434dd77763d7Deepanshu Gupta        return createFlags;
6145de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
615b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
616b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    /**
617b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * Creates and returns a copy of a given BufferedImage.
618b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * <p/>
619b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * if alpha is different than 255, then it is applied to the alpha channel of each pixel.
620b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     *
621b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @param image the image to copy
622b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @param imageType the type of the new image
623b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @param alpha an optional alpha modifier
624b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @return a new BufferedImage
625b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     */
626b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    /*package*/ static BufferedImage createCopy(BufferedImage image, int imageType, int alpha) {
627b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int w = image.getWidth();
628b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int h = image.getHeight();
629b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
630b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage result = new BufferedImage(w, h, imageType);
631b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
632b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int[] argb = new int[w * h];
633b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
634b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
635b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (alpha != 255) {
636b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            final int length = argb.length;
637b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            for (int i = 0 ; i < length; i++) {
638b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                int a = (argb[i] >>> 24 * alpha) / 255;
639b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                argb[i] = (a << 24) | (argb[i] & 0x00FFFFFF);
640b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            }
641b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
642b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
643b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        result.setRGB(0, 0, w, h, argb, 0, w);
644b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
645b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return result;
646b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    }
647b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
6485de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet}
649