Bitmap_Delegate.java revision 88a8364c386c694f7ad56662ef89713dbf7c9d63
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*
2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2010 The Android Open Source Project
3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License.
6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at
7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software
11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and
14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License.
15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage android.graphics;
18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.LayoutLog;
20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.Bridge;
21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.impl.DelegateManager;
22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.resources.Density;
23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.tools.layoutlib.annotations.LayoutlibDelegate;
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.Bitmap.Config;
26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.os.Parcel;
27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.awt.Graphics2D;
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.awt.image.BufferedImage;
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.File;
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.IOException;
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.InputStream;
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.OutputStream;
34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.nio.Buffer;
35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Arrays;
3670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Guptaimport java.util.EnumSet;
3770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Guptaimport java.util.Set;
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport javax.imageio.ImageIO;
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/**
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Delegate implementing the native methods of android.graphics.Bitmap
43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * by calls to methods of the same name in this delegate class.
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This class behaves like the original native implementation, but in Java, keeping previously
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * native data into its own objects and mapping them to int that are sent back and forth between
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * it and the original Bitmap class.
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see DelegateManager
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic final class Bitmap_Delegate {
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
5670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    public enum BitmapCreateFlags {
5770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        PREMULTIPLIED, MUTABLE
5870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    }
5970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // ---- delegate manager ----
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private static final DelegateManager<Bitmap_Delegate> sManager =
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            new DelegateManager<Bitmap_Delegate>(Bitmap_Delegate.class);
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // ---- delegate helper data ----
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // ---- delegate data ----
67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private final Config mConfig;
68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private BufferedImage mImage;
69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private boolean mHasAlpha = true;
70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private boolean mHasMipMap = false;      // TODO: check the default.
71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private int mGenerationId = 0;
72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // ---- Public Helper methods ----
75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Returns the native delegate associated to a given {@link Bitmap_Delegate} object.
78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public static Bitmap_Delegate getDelegate(Bitmap bitmap) {
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return sManager.getDelegate(bitmap.mNativeBitmap);
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object.
85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
8688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    public static Bitmap_Delegate getDelegate(long native_bitmap) {
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return sManager.getDelegate(native_bitmap);
88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Creates and returns a {@link Bitmap} initialized with the given file content.
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     *
93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param input the file from which to read the bitmap content
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param isMutable whether the bitmap is mutable
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param density the density associated with the bitmap
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     *
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @see Bitmap#isMutable()
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @see Bitmap#getDensity()
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public static Bitmap createBitmap(File input, boolean isMutable, Density density)
101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throws IOException {
10270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
10370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    }
10470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    /**
10570f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * Creates and returns a {@link Bitmap} initialized with the given file content.
10670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     *
10770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @param input the file from which to read the bitmap content
10870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @param density the density associated with the bitmap
10970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     *
11070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @see Bitmap#isPremultiplied()
11170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @see Bitmap#isMutable()
11270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @see Bitmap#getDensity()
11370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     */
11470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    public static Bitmap createBitmap(File input, Set<BitmapCreateFlags> createFlags,
11570f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta            Density density) throws IOException {
116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // create a delegate with the content of the file.
117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
11870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta
11970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        return createBitmap(delegate, createFlags, density.getDpiValue());
120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Creates and returns a {@link Bitmap} initialized with the given stream content.
124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     *
125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param input the stream from which to read the bitmap content
126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param isMutable whether the bitmap is mutable
127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param density the density associated with the bitmap
128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     *
129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @see Bitmap#isMutable()
130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @see Bitmap#getDensity()
131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density)
133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throws IOException {
13470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density);
13570f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    }
13670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta
13770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    /**
13870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * Creates and returns a {@link Bitmap} initialized with the given stream content.
13970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     *
14070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @param input the stream from which to read the bitmap content
14170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @param createFlags
14270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @param density the density associated with the bitmap
14370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     *
14470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @see Bitmap#isPremultiplied()
14570f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @see Bitmap#isMutable()
14670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @see Bitmap#getDensity()
14770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     */
14870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    public static Bitmap createBitmap(InputStream input, Set<BitmapCreateFlags> createFlags,
14970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta            Density density) throws IOException {
150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // create a delegate with the content of the stream.
151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
15370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        return createBitmap(delegate, createFlags, density.getDpiValue());
154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     *
159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param image the bitmap content
160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param isMutable whether the bitmap is mutable
161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param density the density associated with the bitmap
162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     *
163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @see Bitmap#isMutable()
164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @see Bitmap#getDensity()
165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public static Bitmap createBitmap(BufferedImage image, boolean isMutable,
167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Density density) throws IOException {
16870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density);
16970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    }
17070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta
17170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    /**
17270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
17370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     *
17470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @param image the bitmap content
17570f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @param createFlags
17670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @param density the density associated with the bitmap
17770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     *
17870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @see Bitmap#isMutable()
17970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     * @see Bitmap#getDensity()
18070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta     */
18170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags,
18270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta            Density density) throws IOException {
183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // create a delegate with the given image.
184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
18670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        return createBitmap(delegate, createFlags, density.getDpiValue());
187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public static BufferedImage getImage(Bitmap bitmap) {
193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the delegate from the native int.
194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(bitmap.mNativeBitmap);
195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return null;
197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return delegate.mImage;
200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public static int getBufferedImageType(int nativeBitmapConfig) {
203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        switch (Config.nativeToConfig(nativeBitmapConfig)) {
204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            case ALPHA_8:
205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return BufferedImage.TYPE_INT_ARGB;
206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            case RGB_565:
207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return BufferedImage.TYPE_INT_ARGB;
208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            case ARGB_4444:
209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return BufferedImage.TYPE_INT_ARGB;
210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            case ARGB_8888:
211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return BufferedImage.TYPE_INT_ARGB;
212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return BufferedImage.TYPE_INT_ARGB;
215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public BufferedImage getImage() {
221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mImage;
222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Returns the Android bitmap config. Note that this not the config of the underlying
226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Java2D bitmap.
227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public Config getConfig() {
229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mConfig;
230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Returns the hasAlpha rendering hint
234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @return true if the bitmap alpha should be used at render time
235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public boolean hasAlpha() {
237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mHasAlpha && mConfig != Config.RGB_565;
238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public boolean hasMipMap() {
241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // TODO: check if more checks are required as in hasAlpha.
242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mHasMipMap;
243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Update the generationId.
246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     *
247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @see Bitmap#getGenerationId()
248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public void change() {
250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mGenerationId++;
251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // ---- native methods ----
254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
25770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta            int height, int nativeConfig, boolean isMutable) {
258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int imageType = getBufferedImageType(nativeConfig);
259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // create the image
261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        BufferedImage image = new BufferedImage(width, height, imageType);
262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (colors != null) {
264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            image.setRGB(0, 0, width, height, colors, offset, stride);
265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // create a delegate with the content of the stream.
268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
27070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
27170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta                Bitmap.getDefaultDensity());
272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
27588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static Bitmap nativeCopy(long srcBitmap, int nativeConfig, boolean isMutable) {
276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(srcBitmap);
277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (srcBmpDelegate == null) {
278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return null;
279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        BufferedImage srcImage = srcBmpDelegate.getImage();
282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int width = srcImage.getWidth();
284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int height = srcImage.getHeight();
285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int imageType = getBufferedImageType(nativeConfig);
287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // create the image
289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        BufferedImage image = new BufferedImage(width, height, imageType);
290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // copy the source image into the image.
292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int[] argb = new int[width * height];
293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        srcImage.getRGB(0, 0, width, height, argb, 0, width);
294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        image.setRGB(0, 0, width, height, argb, 0, width);
295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // create a delegate with the content of the stream.
297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
29970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
30070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta                Bitmap.getDefaultDensity());
301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
30488a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static void nativeDestructor(long nativeBitmap) {
305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sManager.removeJavaReferenceFor(nativeBitmap);
306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
30988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static void nativeRecycle(long nativeBitmap) {
310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sManager.removeJavaReferenceFor(nativeBitmap);
311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
31488a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static boolean nativeCompress(long nativeBitmap, int format, int quality,
315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            OutputStream stream, byte[] tempStorage) {
316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                "Bitmap.compress() is not supported", null /*data*/);
318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return true;
319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
32288a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static void nativeErase(long nativeBitmap, int color) {
323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the delegate from the native int.
324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        BufferedImage image = delegate.mImage;
330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Graphics2D g = image.createGraphics();
332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        try {
333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            g.setColor(new java.awt.Color(color, true));
334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            g.fillRect(0, 0, image.getWidth(), image.getHeight());
336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } finally {
337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            g.dispose();
338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
34288a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static int nativeWidth(long nativeBitmap) {
343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the delegate from the native int.
344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 0;
347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return delegate.mImage.getWidth();
350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
35388a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static int nativeHeight(long nativeBitmap) {
354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the delegate from the native int.
355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 0;
358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return delegate.mImage.getHeight();
361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
36488a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static int nativeRowBytes(long nativeBitmap) {
365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the delegate from the native int.
366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 0;
369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return delegate.mImage.getWidth();
372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
37588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static int nativeConfig(long nativeBitmap) {
376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the delegate from the native int.
377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 0;
380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return delegate.mConfig.nativeInt;
383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
38688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static boolean nativeHasAlpha(long nativeBitmap) {
387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the delegate from the native int.
388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return true;
391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return delegate.mHasAlpha;
394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
39788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static boolean nativeHasMipMap(long nativeBitmap) {
398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the delegate from the native int.
399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return true;
402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return delegate.mHasMipMap;
405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
40888a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static int nativeGetPixel(long nativeBitmap, int x, int y) {
409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the delegate from the native int.
410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 0;
413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return delegate.mImage.getRGB(x, y);
416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
41988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static void nativeGetPixels(long nativeBitmap, int[] pixels, int offset,
420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int stride, int x, int y, int width, int height) {
421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        delegate.getImage().getRGB(x, y, width, height, pixels, offset, stride);
427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
43188a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static void nativeSetPixel(long nativeBitmap, int x, int y, int color) {
432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        delegate.getImage().setRGB(x, y, color);
438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
44188a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static void nativeSetPixels(long nativeBitmap, int[] colors, int offset,
442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int stride, int x, int y, int width, int height) {
443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        delegate.getImage().setRGB(x, y, width, height, colors, offset, stride);
449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
45288a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static void nativeCopyPixelsToBuffer(long nativeBitmap, Buffer dst) {
453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // FIXME implement native delegate
454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                "Bitmap.copyPixelsToBuffer is not supported.", null, null /*data*/);
456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
45988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static void nativeCopyPixelsFromBuffer(long nb, Buffer src) {
460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // FIXME implement native delegate
461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                "Bitmap.copyPixelsFromBuffer is not supported.", null, null /*data*/);
463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
46688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static int nativeGenerationId(long nativeBitmap) {
467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return 0;
470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return delegate.mGenerationId;
473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) {
477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only
478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // used during aidl call so really this should not be called.
479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.",
481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                null /*data*/);
482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
48688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static boolean nativeWriteToParcel(long nativeBitmap, boolean isMutable,
487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int density, Parcel p) {
488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // This is only called when sending a bitmap through aidl, so really this should not
489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // be called.
490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.",
492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                null /*data*/);
493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return false;
494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
49788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static Bitmap nativeExtractAlpha(long nativeBitmap, long nativePaint,
498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int[] offsetXY) {
499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate bitmap = sManager.getDelegate(nativeBitmap);
500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (bitmap == null) {
501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return null;
502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the paint which can be null if nativePaint is 0.
505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (paint != null && paint.getMaskFilter() != null) {
508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    "MaskFilter not supported in Bitmap.extractAlpha",
510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    null, null /*data*/);
511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int alpha = paint != null ? paint.getAlpha() : 0xFF;
514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        BufferedImage image = createCopy(bitmap.getImage(), BufferedImage.TYPE_INT_ARGB, alpha);
515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // create the delegate. The actual Bitmap config is only an alpha channel
517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8);
518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // the density doesn't matter, it's set by the Java method.
52070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE),
521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Density.DEFAULT_DENSITY /*density*/);
522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
52588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static void nativePrepareToDraw(long nativeBitmap) {
526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // nothing to be done here.
527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
53088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static void nativeSetHasAlpha(long nativeBitmap, boolean hasAlpha) {
531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the delegate from the native int.
532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        delegate.mHasAlpha = hasAlpha;
538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
54188a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap) {
542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the delegate from the native int.
543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate == null) {
545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return;
546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        delegate.mHasMipMap = hasMipMap;
549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @LayoutlibDelegate
55288a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath    /*package*/ static boolean nativeSameAs(long nb0, long nb1) {
553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate1 = sManager.getDelegate(nb0);
554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate1 == null) {
555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return false;
556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Bitmap_Delegate delegate2 = sManager.getDelegate(nb1);
559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate2 == null) {
560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return false;
561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        BufferedImage image1 = delegate1.getImage();
564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        BufferedImage image2 = delegate2.getImage();
565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate1.mConfig != delegate2.mConfig ||
566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                image1.getWidth() != image2.getWidth() ||
567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                image1.getHeight() != image2.getHeight()) {
568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return false;
569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get the internal data
572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int w = image1.getWidth();
573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int h = image2.getHeight();
574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int[] argb1 = new int[w*h];
575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int[] argb2 = new int[w*h];
576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        image1.getRGB(0, 0, w, h, argb1, 0, w);
578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        image2.getRGB(0, 0, w, h, argb2, 0, w);
579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // compares
581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (delegate1.mConfig == Config.ALPHA_8) {
582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // in this case we have to manually compare the alpha channel as the rest is garbage.
583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            final int length = w*h;
584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            for (int i = 0 ; i < length ; i++) {
585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if ((argb1[i] & 0xFF000000) != (argb2[i] & 0xFF000000)) {
586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return false;
587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return true;
590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return Arrays.equals(argb1, argb2);
593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    // ---- Private delegate/helper methods ----
596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private Bitmap_Delegate(BufferedImage image, Config config) {
598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mImage = image;
599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mConfig = config;
600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
60270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    private static Bitmap createBitmap(Bitmap_Delegate delegate,
60370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta            Set<BitmapCreateFlags> createFlags, int density) {
604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // get its native_int
60588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath        long nativeInt = sManager.addNewDelegate(delegate);
606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
60770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        int width = delegate.mImage.getWidth();
60870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        int height = delegate.mImage.getHeight();
60970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        boolean isMutable = createFlags.contains(BitmapCreateFlags.MUTABLE);
61070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        boolean isPremultiplied = createFlags.contains(BitmapCreateFlags.PREMULTIPLIED);
61170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta
612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // and create/return a new Bitmap with it
61370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        return new Bitmap(nativeInt, null /* buffer */, width, height, density, isMutable,
61470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta                          isPremultiplied, null /*ninePatchChunk*/, null /* layoutBounds */);
615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
61770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) {
61870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        Set<BitmapCreateFlags> createFlags =  EnumSet.of(BitmapCreateFlags.PREMULTIPLIED);
61970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        if (isMutable) {
62070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta            createFlags.add(BitmapCreateFlags.MUTABLE);
62170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        }
62270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta        return createFlags;
62370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta    }
624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Creates and returns a copy of a given BufferedImage.
626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * <p/>
627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * if alpha is different than 255, then it is applied to the alpha channel of each pixel.
628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     *
629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param image the image to copy
630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param imageType the type of the new image
631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param alpha an optional alpha modifier
632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @return a new BufferedImage
633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /*package*/ static BufferedImage createCopy(BufferedImage image, int imageType, int alpha) {
635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int w = image.getWidth();
636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int h = image.getHeight();
637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        BufferedImage result = new BufferedImage(w, h, imageType);
639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        int[] argb = new int[w * h];
641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (alpha != 255) {
644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            final int length = argb.length;
645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            for (int i = 0 ; i < length; i++) {
646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                int a = (argb[i] >>> 24 * alpha) / 255;
647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                argb[i] = (a << 24) | (argb[i] & 0x00FFFFFF);
648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        result.setRGB(0, 0, w, h, argb, 0, w);
652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return result;
654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
657