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;
365de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
375de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohetimport javax.imageio.ImageIO;
385de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
395de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet/**
405de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * Delegate implementing the native methods of android.graphics.Bitmap
415de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *
425de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced
435de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * by calls to methods of the same name in this delegate class.
445de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *
455de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * This class behaves like the original native implementation, but in Java, keeping previously
465de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * native data into its own objects and mapping them to int that are sent back and forth between
475de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * it and the original Bitmap class.
485de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *
495de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet * @see DelegateManager
505de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet *
515de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet */
52d348b6eaa98e23cb38d90906df109aaa2d20ea7fXavier Ducrohetpublic final class Bitmap_Delegate {
535de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
545de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- delegate manager ----
555de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    private static final DelegateManager<Bitmap_Delegate> sManager =
56f0a53435f14d23d9555fc46014352ee6a7baa647Xavier Ducrohet            new DelegateManager<Bitmap_Delegate>(Bitmap_Delegate.class);
575de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
585de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- delegate helper data ----
595de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
605de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- delegate data ----
6163fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet    private final Config mConfig;
625de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    private BufferedImage mImage;
635de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    private boolean mHasAlpha = true;
64b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    private int mGenerationId = 0;
655de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
6663fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet
675de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- Public Helper methods ----
685de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
695de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /**
709f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     * Returns the native delegate associated to a given {@link Bitmap_Delegate} object.
719f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     */
729f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    public static Bitmap_Delegate getDelegate(Bitmap bitmap) {
739f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet        return sManager.getDelegate(bitmap.mNativeBitmap);
749f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    }
759f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet
769f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    /**
779f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object.
789f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     */
799f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    public static Bitmap_Delegate getDelegate(int native_bitmap) {
809f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet        return sManager.getDelegate(native_bitmap);
819f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    }
829f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet
839f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    /**
845de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     * Creates and returns a {@link Bitmap} initialized with the given file content.
852d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
862d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param input the file from which to read the bitmap content
872d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param isMutable whether the bitmap is mutable
882d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param density the density associated with the bitmap
892d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
902d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#isMutable()
912d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#getDensity()
925de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     */
9316584225125acba18b74920b902c798dfead0328Xavier Ducrohet    public static Bitmap createBitmap(File input, boolean isMutable, Density density)
942d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet            throws IOException {
955de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // create a delegate with the content of the file.
9663fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
975de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
9816584225125acba18b74920b902c798dfead0328Xavier Ducrohet        return createBitmap(delegate, isMutable, density.getDpiValue());
995de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
1005de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
1015de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /**
1025de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     * Creates and returns a {@link Bitmap} initialized with the given stream content.
1032d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
1042d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param input the stream from which to read the bitmap content
1052d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param isMutable whether the bitmap is mutable
1062d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param density the density associated with the bitmap
1072d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
1082d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#isMutable()
1092d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#getDensity()
1105de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     */
11116584225125acba18b74920b902c798dfead0328Xavier Ducrohet    public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density)
1122d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet            throws IOException {
1135de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // create a delegate with the content of the stream.
11463fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
1155de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
11616584225125acba18b74920b902c798dfead0328Xavier Ducrohet        return createBitmap(delegate, isMutable, density.getDpiValue());
1175de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
1185de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
1195de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /**
1205de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
1212d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
1222d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param image the bitmap content
1232d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param isMutable whether the bitmap is mutable
1242d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @param density the density associated with the bitmap
1252d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     *
1262d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#isMutable()
1272d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * @see Bitmap#getDensity()
1285de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     */
129ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet    public static Bitmap createBitmap(BufferedImage image, boolean isMutable,
13016584225125acba18b74920b902c798dfead0328Xavier Ducrohet            Density density) throws IOException {
1315de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // create a delegate with the given image.
13263fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
1335de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
13416584225125acba18b74920b902c798dfead0328Xavier Ducrohet        return createBitmap(delegate, isMutable, density.getDpiValue());
1355de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
1365de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
1375de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /**
1385de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
1395de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet     */
1405de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    public static BufferedImage getImage(Bitmap bitmap) {
1415de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
1425de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(bitmap.mNativeBitmap);
1435de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
1445de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return null;
1455de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
1465de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
1475de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return delegate.mImage;
1485de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
1495de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
1505de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    public static int getBufferedImageType(int nativeBitmapConfig) {
1517f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet        switch (Config.nativeToConfig(nativeBitmapConfig)) {
1525de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            case ALPHA_8:
1535de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet                return BufferedImage.TYPE_INT_ARGB;
1545de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            case RGB_565:
1555de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet                return BufferedImage.TYPE_INT_ARGB;
1565de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            case ARGB_4444:
1575de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet                return BufferedImage.TYPE_INT_ARGB;
1585de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            case ARGB_8888:
1595de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet                return BufferedImage.TYPE_INT_ARGB;
1605de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
1615de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
1625de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return BufferedImage.TYPE_INT_ARGB;
1635de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
1645de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
1659f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    /**
1669f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
1679f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet     */
1689f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    public BufferedImage getImage() {
1699f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet        return mImage;
1709f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet    }
1719f63ff263b0a97f0fa63e97136c18f6abccbfc68Xavier Ducrohet
17263fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet    /**
17363fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet     * Returns the Android bitmap config. Note that this not the config of the underlying
17463fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet     * Java2D bitmap.
17563fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet     */
17663fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet    public Config getConfig() {
17763fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        return mConfig;
17863fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet    }
17963fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet
180b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    /**
181b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * Returns the hasAlpha rendering hint
182b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @return true if the bitmap alpha should be used at render time
183b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     */
184b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    public boolean hasAlpha() {
185b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return mHasAlpha && mConfig != Config.RGB_565;
186b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    }
187b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
188b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    /**
189b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * Update the generationId.
190b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     *
191b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @see Bitmap#getGenerationId()
192b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     */
193b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    public void change() {
194b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        mGenerationId++;
195b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    }
19663fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet
1975de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- native methods ----
1985de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
1999a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
2005de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
2015de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            int height, int nativeConfig, boolean mutable) {
2025de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        int imageType = getBufferedImageType(nativeConfig);
2035de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2045de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // create the image
2055de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        BufferedImage image = new BufferedImage(width, height, imageType);
2065de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
207b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (colors != null) {
208b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            image.setRGB(0, 0, width, height, colors, offset, stride);
209b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
2105de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2115de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // create a delegate with the content of the stream.
2127f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
2135de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2142d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet        return createBitmap(delegate, mutable, Bitmap.getDefaultDensity());
2155de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
2165de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2179a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
2185de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static Bitmap nativeCopy(int srcBitmap, int nativeConfig, boolean isMutable) {
219b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(srcBitmap);
220b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (srcBmpDelegate == null) {
221b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return null;
222b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
223b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
224b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage srcImage = srcBmpDelegate.getImage();
225b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
226b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int width = srcImage.getWidth();
227b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int height = srcImage.getHeight();
228b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
229b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int imageType = getBufferedImageType(nativeConfig);
230b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
231b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // create the image
232b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage image = new BufferedImage(width, height, imageType);
233b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
234b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // copy the source image into the image.
235b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int[] argb = new int[width * height];
236b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        srcImage.getRGB(0, 0, width, height, argb, 0, width);
237b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        image.setRGB(0, 0, width, height, argb, 0, width);
238b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
239b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // create a delegate with the content of the stream.
2407f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
241b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
242b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return createBitmap(delegate, isMutable, Bitmap.getDefaultDensity());
2435de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
2445de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2459a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
2465de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeDestructor(int nativeBitmap) {
247cc4977d0fdaf657907912fd6cc2f9426dc8d2e36Xavier Ducrohet        sManager.removeJavaReferenceFor(nativeBitmap);
2485de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
2495de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2509a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
2515de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeRecycle(int nativeBitmap) {
252cc4977d0fdaf657907912fd6cc2f9426dc8d2e36Xavier Ducrohet        sManager.removeJavaReferenceFor(nativeBitmap);
2535de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
2545de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2559a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
2565de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static boolean nativeCompress(int nativeBitmap, int format, int quality,
2575de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            OutputStream stream, byte[] tempStorage) {
258918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
25951a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                "Bitmap.compress() is not supported", null /*data*/);
260b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return true;
2615de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
2625de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2639a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
2645de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeErase(int nativeBitmap, int color) {
2655de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
2665de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
2675de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
2685de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return;
2695de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
2705de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2715de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        BufferedImage image = delegate.mImage;
2725de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2735de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Graphics2D g = image.createGraphics();
2745de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        try {
275b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            g.setColor(new java.awt.Color(color, true));
2765de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2775de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            g.fillRect(0, 0, image.getWidth(), image.getHeight());
2785de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        } finally {
2795de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            g.dispose();
2805de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
2815de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
2825de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2839a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
2845de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static int nativeWidth(int nativeBitmap) {
2855de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
2865de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
2875de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
2885de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return 0;
2895de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
2905de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2915de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return delegate.mImage.getWidth();
2925de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
2935de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
2949a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
2955de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static int nativeHeight(int nativeBitmap) {
2965de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
2975de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
2985de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
2995de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return 0;
3005de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
3015de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3025de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return delegate.mImage.getHeight();
3035de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3045de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3059a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3065de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static int nativeRowBytes(int nativeBitmap) {
3075de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
3085de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
3095de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
3105de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return 0;
3115de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
3125de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3135de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return delegate.mImage.getWidth();
3145de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3155de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3169a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3175de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static int nativeConfig(int nativeBitmap) {
31863fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        // get the delegate from the native int.
31963fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
32063fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        if (delegate == null) {
32163fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet            return 0;
32263fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        }
32363fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet
32463fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        return delegate.mConfig.nativeInt;
3255de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3265de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3279a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3285de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static boolean nativeHasAlpha(int nativeBitmap) {
3295de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
3305de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
3315de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
3325de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return true;
3335de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
3345de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3355de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return delegate.mHasAlpha;
3365de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3375de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3389a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3395de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static int nativeGetPixel(int nativeBitmap, int x, int y) {
3405de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
3415de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
3425de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
3435de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return 0;
3445de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
3455de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3465de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        return delegate.mImage.getRGB(x, y);
3475de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3485de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3499a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3505de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeGetPixels(int nativeBitmap, int[] pixels, int offset,
3515de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            int stride, int x, int y, int width, int height) {
352b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
353b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate == null) {
354b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return;
355b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
356b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
357b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        delegate.getImage().getRGB(x, y, width, height, pixels, offset, stride);
3585de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3595de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3605de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3619a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3625de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeSetPixel(int nativeBitmap, int x, int y, int color) {
363b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
364b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate == null) {
365b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return;
366b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
367b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
368b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        delegate.getImage().setRGB(x, y, color);
3695de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3705de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3719a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3725de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeSetPixels(int nativeBitmap, int[] colors, int offset,
3735de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            int stride, int x, int y, int width, int height) {
374b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
375b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate == null) {
376b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return;
377b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
378b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
379b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        delegate.getImage().setRGB(x, y, width, height, colors, offset, stride);
3805de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3815de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3829a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3835de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeCopyPixelsToBuffer(int nativeBitmap, Buffer dst) {
3845de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // FIXME implement native delegate
3858a80a8555238cc564f445f902aff5231993a8f96Xavier Ducrohet        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
3868a80a8555238cc564f445f902aff5231993a8f96Xavier Ducrohet                "Bitmap.copyPixelsToBuffer is not supported.", null, null /*data*/);
3875de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3885de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3899a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3905de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeCopyPixelsFromBuffer(int nb, Buffer src) {
3915de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // FIXME implement native delegate
3928a80a8555238cc564f445f902aff5231993a8f96Xavier Ducrohet        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
3938a80a8555238cc564f445f902aff5231993a8f96Xavier Ducrohet                "Bitmap.copyPixelsFromBuffer is not supported.", null, null /*data*/);
3945de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
3955de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
3969a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
3975de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static int nativeGenerationId(int nativeBitmap) {
398b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
399b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate == null) {
400b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return 0;
401b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
402b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
403b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return delegate.mGenerationId;
4045de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4055de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4069a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4075de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) {
408b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only
409b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // used during aidl call so really this should not be called.
410918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
41151a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.",
41251a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                null /*data*/);
413b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return null;
4145de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4155de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4169a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4175de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static boolean nativeWriteToParcel(int nativeBitmap, boolean isMutable,
4185de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            int density, Parcel p) {
419b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // This is only called when sending a bitmap through aidl, so really this should not
420b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // be called.
421918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
42251a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.",
42351a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                null /*data*/);
424b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return false;
4255de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4265de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4279a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4285de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static Bitmap nativeExtractAlpha(int nativeBitmap, int nativePaint,
4295de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            int[] offsetXY) {
430b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate bitmap = sManager.getDelegate(nativeBitmap);
431b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (bitmap == null) {
432b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return null;
433b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
434b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
435d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        // get the paint which can be null if nativePaint is 0.
436d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
437b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
438d43909c7503e11eb335a452d296a10804bb01fd6Xavier Ducrohet        if (paint != null && paint.getMaskFilter() != null) {
439918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
440b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                    "MaskFilter not supported in Bitmap.extractAlpha",
44151a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                    null, null /*data*/);
442b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
4435de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
444b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int alpha = paint != null ? paint.getAlpha() : 0xFF;
445b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage image = createCopy(bitmap.getImage(), BufferedImage.TYPE_INT_ARGB, alpha);
446b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
447b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // create the delegate. The actual Bitmap config is only an alpha channel
448b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8);
449b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
450b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // the density doesn't matter, it's set by the Java method.
451b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return createBitmap(delegate, false /*isMutable*/,
45216584225125acba18b74920b902c798dfead0328Xavier Ducrohet                Density.DEFAULT_DENSITY /*density*/);
453b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    }
4545de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4559a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4565de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativePrepareToDraw(int nativeBitmap) {
457b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // nothing to be done here.
4585de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4595de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4609a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4615de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static void nativeSetHasAlpha(int nativeBitmap, boolean hasAlpha) {
4625de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get the delegate from the native int.
4635de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
4645de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        if (delegate == null) {
4655de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet            return;
4665de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        }
4675de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4685de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        delegate.mHasAlpha = hasAlpha;
4695de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
4705de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
4719a4fe29c8d92014d2d9a848e9116b8cc9d0842f9Xavier Ducrohet    @LayoutlibDelegate
4725de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    /*package*/ static boolean nativeSameAs(int nb0, int nb1) {
473b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate1 = sManager.getDelegate(nb0);
474b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate1 == null) {
475b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return false;
476b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
477b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
478b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        Bitmap_Delegate delegate2 = sManager.getDelegate(nb1);
479b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate2 == null) {
480b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return false;
481b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
482b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
483b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage image1 = delegate1.getImage();
484b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage image2 = delegate2.getImage();
485b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate1.mConfig != delegate2.mConfig ||
486b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                image1.getWidth() != image2.getWidth() ||
487b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                image1.getHeight() != image2.getHeight()) {
488b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return false;
489b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
490b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
491b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // get the internal data
492b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int w = image1.getWidth();
493b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int h = image2.getHeight();
494b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int[] argb1 = new int[w*h];
495b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int[] argb2 = new int[w*h];
496b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
497b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        image1.getRGB(0, 0, w, h, argb1, 0, w);
498b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        image2.getRGB(0, 0, w, h, argb2, 0, w);
499b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
500b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        // compares
501b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (delegate1.mConfig == Config.ALPHA_8) {
502b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            // in this case we have to manually compare the alpha channel as the rest is garbage.
503b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            final int length = w*h;
504b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            for (int i = 0 ; i < length ; i++) {
505b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                if ((argb1[i] & 0xFF000000) != (argb2[i] & 0xFF000000)) {
506b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                    return false;
507b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                }
508b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            }
509b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            return true;
510b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
511b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
512b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return Arrays.equals(argb1, argb2);
5135de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
5145de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
5155de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    // ---- Private delegate/helper methods ----
5165de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
51763fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet    private Bitmap_Delegate(BufferedImage image, Config config) {
5185de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        mImage = image;
51963fd87113cea6abec97a6cd966e090e9b590fc3bXavier Ducrohet        mConfig = config;
5205de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
5215de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
5222d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet    private static Bitmap createBitmap(Bitmap_Delegate delegate, boolean isMutable, int density) {
5235de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // get its native_int
524cc4977d0fdaf657907912fd6cc2f9426dc8d2e36Xavier Ducrohet        int nativeInt = sManager.addNewDelegate(delegate);
5255de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet
5265de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet        // and create/return a new Bitmap with it
527ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani        return new Bitmap(nativeInt, null /* buffer */, isMutable, null /*ninePatchChunk*/,
528ec4a50428d5f26a22df3edaf7e5b08f41d5cb54bAmith Yamasani                density);
5295de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet    }
530b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
531b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    /**
532b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * Creates and returns a copy of a given BufferedImage.
533b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * <p/>
534b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * if alpha is different than 255, then it is applied to the alpha channel of each pixel.
535b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     *
536b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @param image the image to copy
537b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @param imageType the type of the new image
538b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @param alpha an optional alpha modifier
539b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     * @return a new BufferedImage
540b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet     */
541b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    /*package*/ static BufferedImage createCopy(BufferedImage image, int imageType, int alpha) {
542b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int w = image.getWidth();
543b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int h = image.getHeight();
544b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
545b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        BufferedImage result = new BufferedImage(w, h, imageType);
546b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
547b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        int[] argb = new int[w * h];
548b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
549b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
550b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        if (alpha != 255) {
551b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            final int length = argb.length;
552b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            for (int i = 0 ; i < length; i++) {
553b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                int a = (argb[i] >>> 24 * alpha) / 255;
554b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet                argb[i] = (a << 24) | (argb[i] & 0x00FFFFFF);
555b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet            }
556b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        }
557b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
558b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        result.setRGB(0, 0, w, h, argb, 0, w);
559b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
560b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet        return result;
561b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet    }
562b1da1afa7418960b650780250bbd34c81af61aa3Xavier Ducrohet
5635de11a18e9151e6bc9b3e81cf31fc43dc63dffbfXavier Ducrohet}
564