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; 20491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Guptaimport com.android.ide.common.rendering.api.RenderResources; 21491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Guptaimport com.android.ide.common.rendering.api.ResourceValue; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.Bridge; 23491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Guptaimport com.android.layoutlib.bridge.android.BridgeContext; 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.impl.DelegateManager; 25491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Guptaimport com.android.layoutlib.bridge.impl.RenderAction; 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.resources.Density; 27491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Guptaimport com.android.resources.ResourceType; 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.tools.layoutlib.annotations.LayoutlibDelegate; 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 30476e582d2ffdf25102d4c55f8c242baa3d21d37fDeepanshu Guptaimport android.annotation.Nullable; 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.Bitmap.Config; 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.os.Parcel; 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.awt.Graphics2D; 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.awt.image.BufferedImage; 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.File; 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.IOException; 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.InputStream; 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.OutputStream; 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.nio.Buffer; 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Arrays; 4270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Guptaimport java.util.EnumSet; 4370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Guptaimport java.util.Set; 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport javax.imageio.ImageIO; 46491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Guptaimport libcore.util.NativeAllocationRegistry_Delegate; 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Delegate implementing the native methods of android.graphics.Bitmap 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * by calls to methods of the same name in this delegate class. 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This class behaves like the original native implementation, but in Java, keeping previously 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * native data into its own objects and mapping them to int that are sent back and forth between 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * it and the original Bitmap class. 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see DelegateManager 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic final class Bitmap_Delegate { 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 6326e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta 6470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta public enum BitmapCreateFlags { 659758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard NONE, PREMULTIPLIED, MUTABLE 6670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta } 6770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---- delegate manager ---- 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static final DelegateManager<Bitmap_Delegate> sManager = 70adf62b3ebc8ae5e3e76cf6cfce978e8d1ca5bf8eDiego Perez new DelegateManager<>(Bitmap_Delegate.class); 71491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta private static long sFinalizer = -1; 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---- delegate helper data ---- 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---- delegate data ---- 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final Config mConfig; 77491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta private final BufferedImage mImage; 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private boolean mHasAlpha = true; 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private boolean mHasMipMap = false; // TODO: check the default. 8026e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta private boolean mIsPremultiplied = true; 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int mGenerationId = 0; 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---- Public Helper methods ---- 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object. 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 8988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath public static Bitmap_Delegate getDelegate(long native_bitmap) { 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sManager.getDelegate(native_bitmap); 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 93d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta @Nullable 94d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta public static Bitmap_Delegate getDelegate(@Nullable Bitmap bitmap) { 95906f2ad1c857077368d5ca154d8e849f4ad420fcDiego Perez return bitmap == null ? null : getDelegate(bitmap.getNativeInstance()); 96d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta } 97d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Creates and returns a {@link Bitmap} initialized with the given file content. 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param input the file from which to read the bitmap content 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param isMutable whether the bitmap is mutable 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param density the density associated with the bitmap 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see Bitmap#isMutable() 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see Bitmap#getDensity() 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static Bitmap createBitmap(File input, boolean isMutable, Density density) 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski throws IOException { 11070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density); 11170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta } 112bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta 11370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta /** 11470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * Creates and returns a {@link Bitmap} initialized with the given file content. 11570f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * 11670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @param input the file from which to read the bitmap content 11770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @param density the density associated with the bitmap 11870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * 119bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta * @see Bitmap#isPremultiplied() 12070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @see Bitmap#isMutable() 12170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @see Bitmap#getDensity() 12270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta */ 123491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta private static Bitmap createBitmap(File input, Set<BitmapCreateFlags> createFlags, 12470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta Density density) throws IOException { 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // create a delegate with the content of the file. 126491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta BufferedImage image = ImageIO.read(input); 127491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta if (image == null && input.exists()) { 128491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta // There was a problem decoding the image, or the decoder isn't registered. Webp maybe. 129491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta // Replace with a broken image icon. 130491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta BridgeContext currentContext = RenderAction.getCurrentContext(); 131491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta if (currentContext != null) { 132491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta RenderResources resources = currentContext.getRenderResources(); 133491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta ResourceValue broken = resources.getFrameworkResource(ResourceType.DRAWABLE, 134491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta "ic_menu_report_image"); 135491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta File brokenFile = new File(broken.getValue()); 136491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta if (brokenFile.exists()) { 137491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta image = ImageIO.read(brokenFile); 138491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta } 139491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta } 140491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta } 141491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888); 142bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta 14370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta return createBitmap(delegate, createFlags, density.getDpiValue()); 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Creates and returns a {@link Bitmap} initialized with the given stream content. 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param input the stream from which to read the bitmap content 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param isMutable whether the bitmap is mutable 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param density the density associated with the bitmap 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see Bitmap#isMutable() 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see Bitmap#getDensity() 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density) 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski throws IOException { 15870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density); 15970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta } 16070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta 16170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta /** 16270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * Creates and returns a {@link Bitmap} initialized with the given stream content. 16370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * 16470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @param input the stream from which to read the bitmap content 16570f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @param density the density associated with the bitmap 16670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * 167bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta * @see Bitmap#isPremultiplied() 16870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @see Bitmap#isMutable() 16970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @see Bitmap#getDensity() 17070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta */ 17170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta public static Bitmap createBitmap(InputStream input, Set<BitmapCreateFlags> createFlags, 17270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta Density density) throws IOException { 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // create a delegate with the content of the stream. 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888); 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta return createBitmap(delegate, createFlags, density.getDpiValue()); 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage} 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param image the bitmap content 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param isMutable whether the bitmap is mutable 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param density the density associated with the bitmap 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see Bitmap#isMutable() 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see Bitmap#getDensity() 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1899173c8a2e90a48959dedc9d4aa415482f5014844Deepanshu Gupta public static Bitmap createBitmap(BufferedImage image, boolean isMutable, Density density) { 19070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density); 19170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta } 19270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta 19370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta /** 19470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage} 19570f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * 19670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @param image the bitmap content 19770f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @param density the density associated with the bitmap 19870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * 199bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta * @see Bitmap#isPremultiplied() 20070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @see Bitmap#isMutable() 20170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta * @see Bitmap#getDensity() 20270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta */ 20370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags, 2049173c8a2e90a48959dedc9d4aa415482f5014844Deepanshu Gupta Density density) { 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // create a delegate with the given image. 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888); 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 20870f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta return createBitmap(delegate, createFlags, density.getDpiValue()); 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 211d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta private static int getBufferedImageType() { 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return BufferedImage.TYPE_INT_ARGB; 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}. 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public BufferedImage getImage() { 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mImage; 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns the Android bitmap config. Note that this not the config of the underlying 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Java2D bitmap. 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public Config getConfig() { 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mConfig; 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns the hasAlpha rendering hint 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return true if the bitmap alpha should be used at render time 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public boolean hasAlpha() { 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mHasAlpha && mConfig != Config.RGB_565; 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Update the generationId. 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see Bitmap#getGenerationId() 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void change() { 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGenerationId++; 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---- native methods ---- 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width, 25170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta int height, int nativeConfig, boolean isMutable) { 252d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta int imageType = getBufferedImageType(); 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // create the image 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski BufferedImage image = new BufferedImage(width, height, imageType); 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (colors != null) { 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski image.setRGB(0, 0, width, height, colors, offset, stride); 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // create a delegate with the content of the stream. 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig)); 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 26470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable), 265bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta Bitmap.getDefaultDensity()); 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 26988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static Bitmap nativeCopy(long srcBitmap, int nativeConfig, boolean isMutable) { 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(srcBitmap); 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (srcBmpDelegate == null) { 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski BufferedImage srcImage = srcBmpDelegate.getImage(); 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int width = srcImage.getWidth(); 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int height = srcImage.getHeight(); 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 280d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta int imageType = getBufferedImageType(); 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // create the image 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski BufferedImage image = new BufferedImage(width, height, imageType); 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // copy the source image into the image. 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] argb = new int[width * height]; 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski srcImage.getRGB(0, 0, width, height, argb, 0, width); 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski image.setRGB(0, 0, width, height, argb, 0, width); 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // create a delegate with the content of the stream. 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig)); 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 29370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable), 29470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta Bitmap.getDefaultDensity()); 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 298a5e6298b35fa212a7f20740174c553ce4079cce2Deepanshu Gupta /*package*/ static Bitmap nativeCopyAshmem(long nativeSrcBitmap) { 299a5e6298b35fa212a7f20740174c553ce4079cce2Deepanshu Gupta // Unused method; no implementation provided. 300a5e6298b35fa212a7f20740174c553ce4079cce2Deepanshu Gupta assert false; 301a5e6298b35fa212a7f20740174c553ce4079cce2Deepanshu Gupta return null; 302a5e6298b35fa212a7f20740174c553ce4079cce2Deepanshu Gupta } 303a5e6298b35fa212a7f20740174c553ce4079cce2Deepanshu Gupta 304a5e6298b35fa212a7f20740174c553ce4079cce2Deepanshu Gupta @LayoutlibDelegate 305d7d2119fe37f48e4157c3bc471c1153544cf5604Diego Perez /*package*/ static Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig) { 306d7d2119fe37f48e4157c3bc471c1153544cf5604Diego Perez // Unused method; no implementation provided. 307d7d2119fe37f48e4157c3bc471c1153544cf5604Diego Perez assert false; 308d7d2119fe37f48e4157c3bc471c1153544cf5604Diego Perez return null; 309d7d2119fe37f48e4157c3bc471c1153544cf5604Diego Perez } 310d7d2119fe37f48e4157c3bc471c1153544cf5604Diego Perez 311d7d2119fe37f48e4157c3bc471c1153544cf5604Diego Perez @LayoutlibDelegate 312491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta /*package*/ static long nativeGetNativeFinalizer() { 313491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta synchronized (Bitmap_Delegate.class) { 314491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta if (sFinalizer == -1) { 315491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor); 316491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta } 317491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta return sFinalizer; 318491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta } 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 322bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta /*package*/ static boolean nativeRecycle(long nativeBitmap) { 323adf62b3ebc8ae5e3e76cf6cfce978e8d1ca5bf8eDiego Perez // In our case reycle() is a no-op. We will let the finalizer to dispose the bitmap. 324bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta return true; 325bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta } 326bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta 327bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta @LayoutlibDelegate 328bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta /*package*/ static void nativeReconfigure(long nativeBitmap, int width, int height, 329a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard int config, boolean isPremultiplied) { 330bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 331bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta "Bitmap.reconfigure() is not supported", null /*data*/); 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 33588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean nativeCompress(long nativeBitmap, int format, int quality, 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski OutputStream stream, byte[] tempStorage) { 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Bitmap.compress() is not supported", null /*data*/); 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 34388a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void nativeErase(long nativeBitmap, int color) { 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the delegate from the native int. 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski BufferedImage image = delegate.mImage; 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Graphics2D g = image.createGraphics(); 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski g.setColor(new java.awt.Color(color, true)); 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski g.fillRect(0, 0, image.getWidth(), image.getHeight()); 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } finally { 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski g.dispose(); 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 36388a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static int nativeRowBytes(long nativeBitmap) { 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the delegate from the native int. 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return delegate.mImage.getWidth(); 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 37488a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static int nativeConfig(long nativeBitmap) { 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the delegate from the native int. 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return delegate.mConfig.nativeInt; 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 38588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean nativeHasAlpha(long nativeBitmap) { 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the delegate from the native int. 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 388d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta return delegate == null || delegate.mHasAlpha; 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 39388a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean nativeHasMipMap(long nativeBitmap) { 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the delegate from the native int. 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 396d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta return delegate == null || delegate.mHasMipMap; 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 40126e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta /*package*/ static int nativeGetPixel(long nativeBitmap, int x, int y) { 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the delegate from the native int. 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return delegate.mImage.getRGB(x, y); 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 41288a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void nativeGetPixels(long nativeBitmap, int[] pixels, int offset, 41326e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta int stride, int x, int y, int width, int height) { 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delegate.getImage().getRGB(x, y, width, height, pixels, offset, stride); 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 42426e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta /*package*/ static void nativeSetPixel(long nativeBitmap, int x, int y, int color) { 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delegate.getImage().setRGB(x, y, color); 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 43488a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void nativeSetPixels(long nativeBitmap, int[] colors, int offset, 43526e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta int stride, int x, int y, int width, int height) { 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delegate.getImage().setRGB(x, y, width, height, colors, offset, stride); 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 44588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void nativeCopyPixelsToBuffer(long nativeBitmap, Buffer dst) { 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // FIXME implement native delegate 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Bitmap.copyPixelsToBuffer is not supported.", null, null /*data*/); 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 45288a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void nativeCopyPixelsFromBuffer(long nb, Buffer src) { 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // FIXME implement native delegate 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Bitmap.copyPixelsFromBuffer is not supported.", null, null /*data*/); 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 45988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static int nativeGenerationId(long nativeBitmap) { 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return delegate.mGenerationId; 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) { 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // used during aidl call so really this should not be called. 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.", 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski null /*data*/); 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 47988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean nativeWriteToParcel(long nativeBitmap, boolean isMutable, 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int density, Parcel p) { 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // This is only called when sending a bitmap through aidl, so really this should not 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // be called. 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.", 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski null /*data*/); 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 49088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static Bitmap nativeExtractAlpha(long nativeBitmap, long nativePaint, 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] offsetXY) { 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate bitmap = sManager.getDelegate(nativeBitmap); 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (bitmap == null) { 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the paint which can be null if nativePaint is 0. 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint); 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (paint != null && paint.getMaskFilter() != null) { 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER, 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "MaskFilter not supported in Bitmap.extractAlpha", 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski null, null /*data*/); 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int alpha = paint != null ? paint.getAlpha() : 0xFF; 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski BufferedImage image = createCopy(bitmap.getImage(), BufferedImage.TYPE_INT_ARGB, alpha); 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // create the delegate. The actual Bitmap config is only an alpha channel 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8); 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the density doesn't matter, it's set by the Java method. 51370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE), 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Density.DEFAULT_DENSITY /*density*/); 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 51826e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta /*package*/ static boolean nativeIsPremultiplied(long nativeBitmap) { 51926e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta // get the delegate from the native int. 52026e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 52126e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta return delegate != null && delegate.mIsPremultiplied; 52226e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta 52326e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta } 52426e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta 52526e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta @LayoutlibDelegate 52626e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta /*package*/ static void nativeSetPremultiplied(long nativeBitmap, boolean isPremul) { 52726e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta // get the delegate from the native int. 52826e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 52926e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta if (delegate == null) { 53026e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta return; 53126e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta } 53226e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta 53326e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta delegate.mIsPremultiplied = isPremul; 53426e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta } 53526e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta 53626e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta @LayoutlibDelegate 53726e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta /*package*/ static void nativeSetHasAlpha(long nativeBitmap, boolean hasAlpha, 538e05bb956ce429618fd4f971a9dc708b9313c59eaDeepanshu Gupta boolean isPremul) { 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the delegate from the native int. 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delegate.mHasAlpha = hasAlpha; 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 54988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap) { 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the delegate from the native int. 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delegate.mHasMipMap = hasMipMap; 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 56088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean nativeSameAs(long nb0, long nb1) { 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate1 = sManager.getDelegate(nb0); 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate1 == null) { 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap_Delegate delegate2 = sManager.getDelegate(nb1); 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate2 == null) { 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski BufferedImage image1 = delegate1.getImage(); 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski BufferedImage image2 = delegate2.getImage(); 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate1.mConfig != delegate2.mConfig || 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski image1.getWidth() != image2.getWidth() || 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski image1.getHeight() != image2.getHeight()) { 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the internal data 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int w = image1.getWidth(); 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int h = image2.getHeight(); 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] argb1 = new int[w*h]; 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] argb2 = new int[w*h]; 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski image1.getRGB(0, 0, w, h, argb1, 0, w); 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski image2.getRGB(0, 0, w, h, argb2, 0, w); 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // compares 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate1.mConfig == Config.ALPHA_8) { 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // in this case we have to manually compare the alpha channel as the rest is garbage. 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int length = w*h; 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0 ; i < length ; i++) { 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((argb1[i] & 0xFF000000) != (argb2[i] & 0xFF000000)) { 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Arrays.equals(argb1, argb2); 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 603a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard @LayoutlibDelegate 604a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard /*package*/ static int nativeGetAllocationByteCount(long nativeBitmap) { 605a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard // get the delegate from the native int. 606a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 607a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard if (delegate == null) { 608a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard return 0; 609a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard } 610a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard return nativeRowBytes(nativeBitmap) * delegate.mImage.getHeight(); 611a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard 612a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard } 613a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard 614a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard @LayoutlibDelegate 615a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard /*package*/ static void nativePrepareToDraw(long nativeBitmap) { 616a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard // do nothing as Bitmap_Delegate does not have caches 617a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard } 618a10973ebd1ca33c14f0cb06c22ea9d2f9828ac99Jerome Gaillard 6199758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard @LayoutlibDelegate 6209758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard /*package*/ static Bitmap nativeCopyPreserveInternalConfig(long nativeBitmap) { 6219758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(nativeBitmap); 6229758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard if (srcBmpDelegate == null) { 6239758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard return null; 6249758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard } 6259758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard 6269758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard BufferedImage srcImage = srcBmpDelegate.getImage(); 6279758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard 6289758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard // create the image 6299758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard BufferedImage image = new BufferedImage(srcImage.getColorModel(), srcImage.copyData(null), 6309758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard srcImage.isAlphaPremultiplied(), null); 6319758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard 6329758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard // create a delegate with the content of the stream. 6339758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard Bitmap_Delegate delegate = new Bitmap_Delegate(image, srcBmpDelegate.getConfig()); 6349758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard 6359758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.NONE), 6369758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard Bitmap.getDefaultDensity()); 6379758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard } 6389758e22d2c852e9f1152b540775360b28dbc2b3eJerome Gaillard 6392a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez @LayoutlibDelegate 6402a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez /*package*/ static Bitmap nativeCreateHardwareBitmap(GraphicBuffer buffer) { 6412a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 6422a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez "Bitmap.nativeCreateHardwareBitmap() is not supported", null /*data*/); 6432a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez return null; 6442a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez } 6452a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez 6462a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez @LayoutlibDelegate 6472a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez /*package*/ static GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap) { 6482a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 6492a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez "Bitmap.nativeCreateGraphicBufferHandle() is not supported", null /*data*/); 6502a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez return null; 6512a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez } 6522a1b23966af3a9ee25cd223e1679f08beb8ed072Diego Perez 65380447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard @LayoutlibDelegate 65480447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard /*package*/ static boolean nativeIsSRGB(long nativeBitmap) { 65580447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 65680447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard "Color spaces are not supported", null /*data*/); 65780447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard return false; 65880447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard } 65980447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard 66080447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard @LayoutlibDelegate 66180447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard /*package*/ static boolean nativeGetColorSpace(long nativePtr, float[] xyz, float[] params) { 66280447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 66380447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard "Color spaces are not supported", null /*data*/); 66480447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard return false; 66580447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard } 66680447d42f0c60cfe45a7acf43bd3d8e2c83a18ebJerome Gaillard 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---- Private delegate/helper methods ---- 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Bitmap_Delegate(BufferedImage image, Config config) { 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mImage = image; 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mConfig = config; 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 67470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta private static Bitmap createBitmap(Bitmap_Delegate delegate, 67570f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta Set<BitmapCreateFlags> createFlags, int density) { 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get its native_int 67788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath long nativeInt = sManager.addNewDelegate(delegate); 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 67970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta int width = delegate.mImage.getWidth(); 68070f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta int height = delegate.mImage.getHeight(); 68170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta boolean isMutable = createFlags.contains(BitmapCreateFlags.MUTABLE); 68270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta boolean isPremultiplied = createFlags.contains(BitmapCreateFlags.PREMULTIPLIED); 68370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and create/return a new Bitmap with it 6854508218850faedea95371188da587b6734f5f3dasergeyv return new Bitmap(nativeInt, width, height, density, isMutable, 68670f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta isPremultiplied, null /*ninePatchChunk*/, null /* layoutBounds */); 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 68970f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) { 690bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta Set<BitmapCreateFlags> createFlags = EnumSet.of(BitmapCreateFlags.PREMULTIPLIED); 69170f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta if (isMutable) { 69270f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta createFlags.add(BitmapCreateFlags.MUTABLE); 69370f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta } 69470f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta return createFlags; 69570f5cc1d5bb9c67781fa6e076e21547547301a3bDeepanshu Gupta } 696bd28e2d9d3c2a7e80babd39471d5788843a48d4aDeepanshu Gupta 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Creates and returns a copy of a given BufferedImage. 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/> 700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * if alpha is different than 255, then it is applied to the alpha channel of each pixel. 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param image the image to copy 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param imageType the type of the new image 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param alpha an optional alpha modifier 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return a new BufferedImage 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static BufferedImage createCopy(BufferedImage image, int imageType, int alpha) { 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int w = image.getWidth(); 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int h = image.getHeight(); 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski BufferedImage result = new BufferedImage(w, h, imageType); 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] argb = new int[w * h]; 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth()); 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (alpha != 255) { 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int length = argb.length; 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0 ; i < length; i++) { 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int a = (argb[i] >>> 24 * alpha) / 255; 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski argb[i] = (a << 24) | (argb[i] & 0x00FFFFFF); 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result.setRGB(0, 0, w, h, argb, 0, w); 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 730