1ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/* 2ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Copyright (C) 2010 The Android Open Source Project 3ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 4ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * you may not use this file except in compliance with the License. 6ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * You may obtain a copy of the License at 7ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 8ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 10ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Unless required by applicable law or agreed to in writing, software 11ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * See the License for the specific language governing permissions and 14ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * limitations under the License. 15ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 16ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 17ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskipackage android.graphics; 18ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 19ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.ide.common.rendering.api.LayoutLog; 20fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Guptaimport com.android.ide.common.rendering.api.RenderResources; 21fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Guptaimport com.android.ide.common.rendering.api.ResourceValue; 22ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.layoutlib.bridge.Bridge; 23fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Guptaimport com.android.layoutlib.bridge.android.BridgeContext; 24ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.layoutlib.bridge.impl.DelegateManager; 25fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Guptaimport com.android.layoutlib.bridge.impl.RenderAction; 26ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.resources.Density; 27fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Guptaimport com.android.resources.ResourceType; 28ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.tools.layoutlib.annotations.LayoutlibDelegate; 29ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 30442aee6bc1abfb143dcfa1ba60d696e576d066c4Deepanshu Guptaimport android.annotation.Nullable; 31ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport android.graphics.Bitmap.Config; 32ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport android.os.Parcel; 33ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 34ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.Graphics2D; 35ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.image.BufferedImage; 36ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.io.File; 37ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.io.IOException; 38ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.io.InputStream; 39ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.io.OutputStream; 40ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.nio.Buffer; 41ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.Arrays; 42835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Guptaimport java.util.EnumSet; 43835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Guptaimport java.util.Set; 44ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 45ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport javax.imageio.ImageIO; 46fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Guptaimport libcore.util.NativeAllocationRegistry_Delegate; 47ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 48ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/** 49ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Delegate implementing the native methods of android.graphics.Bitmap 50ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 51ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced 52ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * by calls to methods of the same name in this delegate class. 53ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 54ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * This class behaves like the original native implementation, but in Java, keeping previously 55ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * native data into its own objects and mapping them to int that are sent back and forth between 56ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * it and the original Bitmap class. 57ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 58ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see DelegateManager 59ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 60ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 61ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskipublic final class Bitmap_Delegate { 62ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 63eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta 64835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta public enum BitmapCreateFlags { 656d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard NONE, PREMULTIPLIED, MUTABLE 66835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta } 67835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta 68ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // ---- delegate manager ---- 69ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private static final DelegateManager<Bitmap_Delegate> sManager = 7042b832b6c5d5bc57886626949f3ed9a219a5f800Diego Perez new DelegateManager<>(Bitmap_Delegate.class); 71fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta private static long sFinalizer = -1; 72ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 73ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // ---- delegate helper data ---- 74ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 75ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // ---- delegate data ---- 76ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private final Config mConfig; 77fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta private final BufferedImage mImage; 78ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private boolean mHasAlpha = true; 79ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private boolean mHasMipMap = false; // TODO: check the default. 80eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta private boolean mIsPremultiplied = true; 81ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private int mGenerationId = 0; 82ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 83ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 84ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // ---- Public Helper methods ---- 85ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 86ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 87ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object. 88ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 89ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath public static Bitmap_Delegate getDelegate(long native_bitmap) { 90ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return sManager.getDelegate(native_bitmap); 91ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 92ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 939fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta @Nullable 949fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta public static Bitmap_Delegate getDelegate(@Nullable Bitmap bitmap) { 95a6897f8507f92267facb6cfe3f53989de35d2d62Diego Perez return bitmap == null ? null : getDelegate(bitmap.getNativeInstance()); 969fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta } 979fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta 98ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 99ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Creates and returns a {@link Bitmap} initialized with the given file content. 100ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 101ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param input the file from which to read the bitmap content 102ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param isMutable whether the bitmap is mutable 103ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param density the density associated with the bitmap 104ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 105ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see Bitmap#isMutable() 106ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see Bitmap#getDensity() 107ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 108ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public static Bitmap createBitmap(File input, boolean isMutable, Density density) 109ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski throws IOException { 110835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density); 111835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta } 11269fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta 113835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta /** 114835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * Creates and returns a {@link Bitmap} initialized with the given file content. 115835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * 116835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @param input the file from which to read the bitmap content 117835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @param density the density associated with the bitmap 118835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * 11969fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta * @see Bitmap#isPremultiplied() 120835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @see Bitmap#isMutable() 121835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @see Bitmap#getDensity() 122835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta */ 123fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta private static Bitmap createBitmap(File input, Set<BitmapCreateFlags> createFlags, 124835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta Density density) throws IOException { 125ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // create a delegate with the content of the file. 126fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta BufferedImage image = ImageIO.read(input); 127fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta if (image == null && input.exists()) { 128fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta // There was a problem decoding the image, or the decoder isn't registered. Webp maybe. 129fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta // Replace with a broken image icon. 130fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta BridgeContext currentContext = RenderAction.getCurrentContext(); 131fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta if (currentContext != null) { 132fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta RenderResources resources = currentContext.getRenderResources(); 133fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta ResourceValue broken = resources.getFrameworkResource(ResourceType.DRAWABLE, 134fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta "ic_menu_report_image"); 135fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta File brokenFile = new File(broken.getValue()); 136fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta if (brokenFile.exists()) { 137fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta image = ImageIO.read(brokenFile); 138fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta } 139fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta } 140fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta } 141fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888); 14269fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta 143835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta return createBitmap(delegate, createFlags, density.getDpiValue()); 144ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 145ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 146ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 147ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Creates and returns a {@link Bitmap} initialized with the given stream content. 148ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 149ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param input the stream from which to read the bitmap content 150ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param isMutable whether the bitmap is mutable 151ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param density the density associated with the bitmap 152ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 153ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see Bitmap#isMutable() 154ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see Bitmap#getDensity() 155ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 156ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density) 157ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski throws IOException { 158835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density); 159835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta } 160835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta 161835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta /** 162835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * Creates and returns a {@link Bitmap} initialized with the given stream content. 163835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * 164835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @param input the stream from which to read the bitmap content 165835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @param density the density associated with the bitmap 166835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * 16769fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta * @see Bitmap#isPremultiplied() 168835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @see Bitmap#isMutable() 169835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @see Bitmap#getDensity() 170835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta */ 171835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta public static Bitmap createBitmap(InputStream input, Set<BitmapCreateFlags> createFlags, 172835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta Density density) throws IOException { 173ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // create a delegate with the content of the stream. 174ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888); 175ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 176835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta return createBitmap(delegate, createFlags, density.getDpiValue()); 177ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 178ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 179ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 180ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage} 181ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 182ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param image the bitmap content 183ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param isMutable whether the bitmap is mutable 184ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param density the density associated with the bitmap 185ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 186ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see Bitmap#isMutable() 187ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see Bitmap#getDensity() 188ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 189c8460df6228766eaf9f1f6e15994f9ba84910a4dDeepanshu Gupta public static Bitmap createBitmap(BufferedImage image, boolean isMutable, Density density) { 190835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density); 191835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta } 192835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta 193835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta /** 194835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage} 195835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * 196835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @param image the bitmap content 197835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @param density the density associated with the bitmap 198835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * 19969fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta * @see Bitmap#isPremultiplied() 200835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @see Bitmap#isMutable() 201835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta * @see Bitmap#getDensity() 202835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta */ 203835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags, 204c8460df6228766eaf9f1f6e15994f9ba84910a4dDeepanshu Gupta Density density) { 205ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // create a delegate with the given image. 206ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888); 207ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 208835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta return createBitmap(delegate, createFlags, density.getDpiValue()); 209ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 210ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 2119fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta private static int getBufferedImageType() { 212ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return BufferedImage.TYPE_INT_ARGB; 213ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 214ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 215ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 216ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}. 217ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 218ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public BufferedImage getImage() { 219ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mImage; 220ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 221ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 222ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 223ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Returns the Android bitmap config. Note that this not the config of the underlying 224ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Java2D bitmap. 225ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 226ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public Config getConfig() { 227ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mConfig; 228ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 229ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 230ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 231ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Returns the hasAlpha rendering hint 232ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return true if the bitmap alpha should be used at render time 233ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 234ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public boolean hasAlpha() { 235ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mHasAlpha && mConfig != Config.RGB_565; 236ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 237ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 238ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 239ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Update the generationId. 240ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 241ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see Bitmap#getGenerationId() 242ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 243ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void change() { 244ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mGenerationId++; 245ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 246ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 247ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // ---- native methods ---- 248ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 249ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 250ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width, 2516c050fc5ebba61fe6857b598a89fa9e9bc30aac2Jerome Gaillard int height, int nativeConfig, boolean isMutable, @Nullable float[] xyzD50, 2526c050fc5ebba61fe6857b598a89fa9e9bc30aac2Jerome Gaillard @Nullable ColorSpace.Rgb.TransferParameters p) { 2539fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta int imageType = getBufferedImageType(); 254ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 255ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // create the image 256ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski BufferedImage image = new BufferedImage(width, height, imageType); 257ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 258ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (colors != null) { 259ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski image.setRGB(0, 0, width, height, colors, offset, stride); 260ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 261ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 262ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // create a delegate with the content of the stream. 263ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig)); 264ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 265835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable), 26669fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta Bitmap.getDefaultDensity()); 267ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 268ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 269ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 270ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static Bitmap nativeCopy(long srcBitmap, int nativeConfig, boolean isMutable) { 271ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(srcBitmap); 272ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (srcBmpDelegate == null) { 273ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return null; 274ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 275ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 276ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski BufferedImage srcImage = srcBmpDelegate.getImage(); 277ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 278ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int width = srcImage.getWidth(); 279ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int height = srcImage.getHeight(); 280ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 2819fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta int imageType = getBufferedImageType(); 282ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 283ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // create the image 284ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski BufferedImage image = new BufferedImage(width, height, imageType); 285ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 286ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // copy the source image into the image. 287ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int[] argb = new int[width * height]; 288ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski srcImage.getRGB(0, 0, width, height, argb, 0, width); 289ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski image.setRGB(0, 0, width, height, argb, 0, width); 290ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 291ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // create a delegate with the content of the stream. 292ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig)); 293ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 294835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable), 295835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta Bitmap.getDefaultDensity()); 296ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 297ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 298ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 299b8275ed6b07d9a4568faee675101651710f8efc0Deepanshu Gupta /*package*/ static Bitmap nativeCopyAshmem(long nativeSrcBitmap) { 300b8275ed6b07d9a4568faee675101651710f8efc0Deepanshu Gupta // Unused method; no implementation provided. 301b8275ed6b07d9a4568faee675101651710f8efc0Deepanshu Gupta assert false; 302b8275ed6b07d9a4568faee675101651710f8efc0Deepanshu Gupta return null; 303b8275ed6b07d9a4568faee675101651710f8efc0Deepanshu Gupta } 304b8275ed6b07d9a4568faee675101651710f8efc0Deepanshu Gupta 305b8275ed6b07d9a4568faee675101651710f8efc0Deepanshu Gupta @LayoutlibDelegate 30674065acbaf49f180d061262237e70b92f339bf89Diego Perez /*package*/ static Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig) { 30774065acbaf49f180d061262237e70b92f339bf89Diego Perez // Unused method; no implementation provided. 30874065acbaf49f180d061262237e70b92f339bf89Diego Perez assert false; 30974065acbaf49f180d061262237e70b92f339bf89Diego Perez return null; 31074065acbaf49f180d061262237e70b92f339bf89Diego Perez } 31174065acbaf49f180d061262237e70b92f339bf89Diego Perez 31274065acbaf49f180d061262237e70b92f339bf89Diego Perez @LayoutlibDelegate 313fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta /*package*/ static long nativeGetNativeFinalizer() { 314fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta synchronized (Bitmap_Delegate.class) { 315fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta if (sFinalizer == -1) { 316fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor); 317fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta } 318fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta return sFinalizer; 319fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta } 320ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 321ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 322ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 32369fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta /*package*/ static boolean nativeRecycle(long nativeBitmap) { 32442b832b6c5d5bc57886626949f3ed9a219a5f800Diego Perez // In our case reycle() is a no-op. We will let the finalizer to dispose the bitmap. 32569fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta return true; 32669fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta } 32769fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta 32869fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta @LayoutlibDelegate 32969fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta /*package*/ static void nativeReconfigure(long nativeBitmap, int width, int height, 3307fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard int config, boolean isPremultiplied) { 33169fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 33269fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta "Bitmap.reconfigure() is not supported", null /*data*/); 333ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 334ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 335ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 336ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static boolean nativeCompress(long nativeBitmap, int format, int quality, 337ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski OutputStream stream, byte[] tempStorage) { 338ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 339ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "Bitmap.compress() is not supported", null /*data*/); 340ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return true; 341ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 342ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 343ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 344ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static void nativeErase(long nativeBitmap, int color) { 345ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the delegate from the native int. 346ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 347ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate == null) { 348ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return; 349ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 350ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 351ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski BufferedImage image = delegate.mImage; 352ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 353ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Graphics2D g = image.createGraphics(); 354ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski try { 355ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski g.setColor(new java.awt.Color(color, true)); 356ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 357ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski g.fillRect(0, 0, image.getWidth(), image.getHeight()); 358ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } finally { 359ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski g.dispose(); 360ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 361ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 362ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 363ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 364ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static int nativeRowBytes(long nativeBitmap) { 365ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the delegate from the native int. 366ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 367ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate == null) { 368ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return 0; 369ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 370ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 371ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return delegate.mImage.getWidth(); 372ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 373ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 374ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 375ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static int nativeConfig(long nativeBitmap) { 376ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the delegate from the native int. 377ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 378ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate == null) { 379ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return 0; 380ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 381ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 382ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return delegate.mConfig.nativeInt; 383ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 384ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 385ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 386ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static boolean nativeHasAlpha(long nativeBitmap) { 387ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the delegate from the native int. 388ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 3899fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta return delegate == null || delegate.mHasAlpha; 390ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 391ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 392ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 393ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 394ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static boolean nativeHasMipMap(long nativeBitmap) { 395ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the delegate from the native int. 396ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 3979fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta return delegate == null || delegate.mHasMipMap; 398ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 399ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 400ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 401ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 402eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta /*package*/ static int nativeGetPixel(long nativeBitmap, int x, int y) { 403ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the delegate from the native int. 404ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 405ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate == null) { 406ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return 0; 407ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 408ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 409ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return delegate.mImage.getRGB(x, y); 410ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 411ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 412ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 413ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static void nativeGetPixels(long nativeBitmap, int[] pixels, int offset, 414eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta int stride, int x, int y, int width, int height) { 415ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 416ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate == null) { 417ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return; 418ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 419ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 420ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski delegate.getImage().getRGB(x, y, width, height, pixels, offset, stride); 421ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 422ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 423ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 424ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 425eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta /*package*/ static void nativeSetPixel(long nativeBitmap, int x, int y, int color) { 426ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 427ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate == null) { 428ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return; 429ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 430ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 431ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski delegate.getImage().setRGB(x, y, color); 432ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 433ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 434ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 435ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static void nativeSetPixels(long nativeBitmap, int[] colors, int offset, 436eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta int stride, int x, int y, int width, int height) { 437ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 438ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate == null) { 439ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return; 440ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 441ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 442ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski delegate.getImage().setRGB(x, y, width, height, colors, offset, stride); 443ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 444ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 445ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 446ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static void nativeCopyPixelsToBuffer(long nativeBitmap, Buffer dst) { 447ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // FIXME implement native delegate 448ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, 449ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "Bitmap.copyPixelsToBuffer is not supported.", null, null /*data*/); 450ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 451ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 452ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 453ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static void nativeCopyPixelsFromBuffer(long nb, Buffer src) { 454ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // FIXME implement native delegate 455ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, 456ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "Bitmap.copyPixelsFromBuffer is not supported.", null, null /*data*/); 457ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 458ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 459ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 460ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static int nativeGenerationId(long nativeBitmap) { 461ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 462ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate == null) { 463ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return 0; 464ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 465ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 466ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return delegate.mGenerationId; 467ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 468ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 469ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 470ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) { 471ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only 472ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // used during aidl call so really this should not be called. 473ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 474ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.", 475ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski null /*data*/); 476ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return null; 477ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 478ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 479ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 480ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static boolean nativeWriteToParcel(long nativeBitmap, boolean isMutable, 481ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int density, Parcel p) { 482ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // This is only called when sending a bitmap through aidl, so really this should not 483ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // be called. 484ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 485ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.", 486ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski null /*data*/); 487ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return false; 488ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 489ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 490ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 491ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static Bitmap nativeExtractAlpha(long nativeBitmap, long nativePaint, 492ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int[] offsetXY) { 493ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate bitmap = sManager.getDelegate(nativeBitmap); 494ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (bitmap == null) { 495ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return null; 496ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 497ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 498ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the paint which can be null if nativePaint is 0. 499ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint); 500ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 501ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (paint != null && paint.getMaskFilter() != null) { 502ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER, 503ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "MaskFilter not supported in Bitmap.extractAlpha", 504ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski null, null /*data*/); 505ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 506ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 507ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int alpha = paint != null ? paint.getAlpha() : 0xFF; 508ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski BufferedImage image = createCopy(bitmap.getImage(), BufferedImage.TYPE_INT_ARGB, alpha); 509ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 510ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // create the delegate. The actual Bitmap config is only an alpha channel 511ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8); 512ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 513ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // the density doesn't matter, it's set by the Java method. 514835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE), 515ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Density.DEFAULT_DENSITY /*density*/); 516ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 517ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 518ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 519eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta /*package*/ static boolean nativeIsPremultiplied(long nativeBitmap) { 520eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta // get the delegate from the native int. 521eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 522eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta return delegate != null && delegate.mIsPremultiplied; 523eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta 524eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta } 525eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta 526eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta @LayoutlibDelegate 527eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta /*package*/ static void nativeSetPremultiplied(long nativeBitmap, boolean isPremul) { 528eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta // get the delegate from the native int. 529eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 530eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta if (delegate == null) { 531eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta return; 532eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta } 533eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta 534eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta delegate.mIsPremultiplied = isPremul; 535eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta } 536eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta 537eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta @LayoutlibDelegate 538eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta /*package*/ static void nativeSetHasAlpha(long nativeBitmap, boolean hasAlpha, 539cd0ed56f8a5f7788bcff050ab8aa42b0504e8535Deepanshu Gupta boolean isPremul) { 540ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the delegate from the native int. 541ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 542ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate == null) { 543ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return; 544ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 545ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 546ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski delegate.mHasAlpha = hasAlpha; 547ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 548ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 549ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 550ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap) { 551ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the delegate from the native int. 552ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 553ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate == null) { 554ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return; 555ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 556ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 557ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski delegate.mHasMipMap = hasMipMap; 558ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 559ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 560ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @LayoutlibDelegate 561ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath /*package*/ static boolean nativeSameAs(long nb0, long nb1) { 562ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate1 = sManager.getDelegate(nb0); 563ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate1 == null) { 564ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return false; 565ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 566ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 567ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bitmap_Delegate delegate2 = sManager.getDelegate(nb1); 568ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate2 == null) { 569ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return false; 570ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 571ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 572ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski BufferedImage image1 = delegate1.getImage(); 573ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski BufferedImage image2 = delegate2.getImage(); 574ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate1.mConfig != delegate2.mConfig || 575ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski image1.getWidth() != image2.getWidth() || 576ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski image1.getHeight() != image2.getHeight()) { 577ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return false; 578ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 579ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 580ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the internal data 581ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int w = image1.getWidth(); 582ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int h = image2.getHeight(); 583ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int[] argb1 = new int[w*h]; 584ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int[] argb2 = new int[w*h]; 585ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 586ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski image1.getRGB(0, 0, w, h, argb1, 0, w); 587ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski image2.getRGB(0, 0, w, h, argb2, 0, w); 588ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 589ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // compares 590ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (delegate1.mConfig == Config.ALPHA_8) { 591ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // in this case we have to manually compare the alpha channel as the rest is garbage. 592ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski final int length = w*h; 593ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (int i = 0 ; i < length ; i++) { 594ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if ((argb1[i] & 0xFF000000) != (argb2[i] & 0xFF000000)) { 595ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return false; 596ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 597ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 598ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return true; 599ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 600ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 601ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return Arrays.equals(argb1, argb2); 602ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 603ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 6047fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard @LayoutlibDelegate 6057fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard /*package*/ static int nativeGetAllocationByteCount(long nativeBitmap) { 6067fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard // get the delegate from the native int. 6077fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); 6087fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard if (delegate == null) { 6097fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard return 0; 6107fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard } 61128508735a5fb6527d3e87adffe6359cd4ab51a98Jerome Gaillard int size = nativeRowBytes(nativeBitmap) * delegate.mImage.getHeight(); 61228508735a5fb6527d3e87adffe6359cd4ab51a98Jerome Gaillard return size < 0 ? Integer.MAX_VALUE : size; 6137fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard 6147fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard } 6157fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard 6167fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard @LayoutlibDelegate 6177fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard /*package*/ static void nativePrepareToDraw(long nativeBitmap) { 6187fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard // do nothing as Bitmap_Delegate does not have caches 6197fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard } 6207fa71f524c86d6224fb95b571d3a9e32edb32f22Jerome Gaillard 6216d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard @LayoutlibDelegate 6226d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard /*package*/ static Bitmap nativeCopyPreserveInternalConfig(long nativeBitmap) { 6236d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(nativeBitmap); 6246d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard if (srcBmpDelegate == null) { 6256d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard return null; 6266d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard } 6276d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard 6286d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard BufferedImage srcImage = srcBmpDelegate.getImage(); 6296d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard 6306d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard // create the image 6316d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard BufferedImage image = new BufferedImage(srcImage.getColorModel(), srcImage.copyData(null), 6326d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard srcImage.isAlphaPremultiplied(), null); 6336d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard 6346d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard // create a delegate with the content of the stream. 6356d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard Bitmap_Delegate delegate = new Bitmap_Delegate(image, srcBmpDelegate.getConfig()); 6366d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard 6376d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.NONE), 6386d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard Bitmap.getDefaultDensity()); 6396d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard } 6406d60df19df21854a555f76ab46d73fa43a9af43fJerome Gaillard 6410cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez @LayoutlibDelegate 6420cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez /*package*/ static Bitmap nativeCreateHardwareBitmap(GraphicBuffer buffer) { 6430cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 6440cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez "Bitmap.nativeCreateHardwareBitmap() is not supported", null /*data*/); 6450cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez return null; 6460cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez } 6470cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez 6480cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez @LayoutlibDelegate 6490cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez /*package*/ static GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap) { 6500cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 6510cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez "Bitmap.nativeCreateGraphicBufferHandle() is not supported", null /*data*/); 6520cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez return null; 6530cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez } 6540cd6c5b6bcaea7216a444a2729b728846878922eDiego Perez 655ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard @LayoutlibDelegate 656ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard /*package*/ static boolean nativeIsSRGB(long nativeBitmap) { 657ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 658ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard "Color spaces are not supported", null /*data*/); 659ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard return false; 660ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard } 661ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard 662ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard @LayoutlibDelegate 663ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard /*package*/ static boolean nativeGetColorSpace(long nativePtr, float[] xyz, float[] params) { 664ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 665ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard "Color spaces are not supported", null /*data*/); 666ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard return false; 667ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard } 668ce2fcba587558e22a3f407b5ed07fcf97f091d41Jerome Gaillard 6696c050fc5ebba61fe6857b598a89fa9e9bc30aac2Jerome Gaillard @LayoutlibDelegate 6706c050fc5ebba61fe6857b598a89fa9e9bc30aac2Jerome Gaillard /*package*/ static void nativeCopyColorSpace(long srcBitmap, long dstBitmap) { 6716c050fc5ebba61fe6857b598a89fa9e9bc30aac2Jerome Gaillard Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, 6726c050fc5ebba61fe6857b598a89fa9e9bc30aac2Jerome Gaillard "Color spaces are not supported", null /*data*/); 6736c050fc5ebba61fe6857b598a89fa9e9bc30aac2Jerome Gaillard } 6746c050fc5ebba61fe6857b598a89fa9e9bc30aac2Jerome Gaillard 675ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // ---- Private delegate/helper methods ---- 676ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 677ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private Bitmap_Delegate(BufferedImage image, Config config) { 678ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mImage = image; 679ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mConfig = config; 680ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 681ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 682835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta private static Bitmap createBitmap(Bitmap_Delegate delegate, 683835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta Set<BitmapCreateFlags> createFlags, int density) { 684ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get its native_int 685ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath long nativeInt = sManager.addNewDelegate(delegate); 686ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 687835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta int width = delegate.mImage.getWidth(); 688835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta int height = delegate.mImage.getHeight(); 689835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta boolean isMutable = createFlags.contains(BitmapCreateFlags.MUTABLE); 690835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta boolean isPremultiplied = createFlags.contains(BitmapCreateFlags.PREMULTIPLIED); 691835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta 692ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // and create/return a new Bitmap with it 693c6ab3686a244dfc9b05d281c6998652fcc115ce1sergeyv return new Bitmap(nativeInt, width, height, density, isMutable, 694835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta isPremultiplied, null /*ninePatchChunk*/, null /* layoutBounds */); 695ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 696ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 697835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) { 69869fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta Set<BitmapCreateFlags> createFlags = EnumSet.of(BitmapCreateFlags.PREMULTIPLIED); 699835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta if (isMutable) { 700835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta createFlags.add(BitmapCreateFlags.MUTABLE); 701835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta } 702835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta return createFlags; 703835e279c3960664c32b35aa7e3215b13c8fa3be4Deepanshu Gupta } 70469fea4897f756b9cf489a92b7073554086e6d252Deepanshu Gupta 705ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 706ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Creates and returns a copy of a given BufferedImage. 707ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * <p/> 708ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * if alpha is different than 255, then it is applied to the alpha channel of each pixel. 709ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 710ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param image the image to copy 711ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param imageType the type of the new image 712ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param alpha an optional alpha modifier 713ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return a new BufferedImage 714ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 715ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /*package*/ static BufferedImage createCopy(BufferedImage image, int imageType, int alpha) { 716ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int w = image.getWidth(); 717ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int h = image.getHeight(); 718ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 719ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski BufferedImage result = new BufferedImage(w, h, imageType); 720ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 721ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int[] argb = new int[w * h]; 722ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth()); 723ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 724ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (alpha != 255) { 725ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski final int length = argb.length; 726ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (int i = 0 ; i < length; i++) { 727ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int a = (argb[i] >>> 24 * alpha) / 255; 728ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski argb[i] = (a << 24) | (argb[i] & 0x00FFFFFF); 729ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 730ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 731ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 732ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski result.setRGB(0, 0, w, h, argb, 0, w); 733ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 734ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return result; 735ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 736ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 737ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski} 738