/* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.imagepipeline.nativecode; import android.annotation.TargetApi; import android.graphics.Bitmap; import com.facebook.common.internal.DoNotStrip; import com.facebook.common.internal.Preconditions; import com.facebook.imagepipeline.nativecode.ImagePipelineNativeLoader; /** * Utility methods for handling Bitmaps. */ @DoNotStrip public class Bitmaps { /** * The only bitmap config we use. Every bitmap managed by this pool will use this config. * If we need to change this, please change BYTES_PER_PIXEL below. */ public static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; /** * Bytes per pixel - corresponds to the specific BITMAP_CONFIG above ARGB_8888. * Must change if the Config above changes */ public static final int BYTES_PER_PIXEL = 4; static { ImagePipelineNativeLoader.load(); } /** * Pin the bitmap so that it cannot be 'purged'. Only makes sense for purgeable bitmaps * WARNING: Use with caution. Make sure that the pinned bitmap is recycled eventually. Otherwise, * this will simply eat up ashmem memory and eventually lead to unfortunate crashes. * We *may* eventually provide an unpin method - but we don't yet have a compelling use case for * that. * @param bitmap the purgeable bitmap to pin */ public static void pinBitmap(Bitmap bitmap) { Preconditions.checkNotNull(bitmap); nativePinBitmap(bitmap); } /** * This blits the pixel data from src to dest. * <p>The destination bitmap must have both a height and a width equal to the source. For maximum * speed stride should be equal as well. * <p>Both bitmaps must be in {@link android.graphics.Bitmap.Config#ARGB_8888} format. * <p>If the src is purgeable, it will be decoded as part of this operation if it was purged. * The dest should not be purgeable. If it is, the copy will still take place, * but will be lost the next time the dest gets purged, without warning. * <p>The dest must be mutable. * @param dest Bitmap to copy into * @param src Bitmap to copy out of */ public static void copyBitmap(Bitmap dest, Bitmap src) { Preconditions.checkArgument(src.getConfig() == Bitmap.Config.ARGB_8888); Preconditions.checkArgument(dest.getConfig() == Bitmap.Config.ARGB_8888); Preconditions.checkArgument(dest.isMutable()); Preconditions.checkArgument(dest.getWidth() == src.getWidth()); Preconditions.checkArgument(dest.getHeight() == src.getHeight()); nativeCopyBitmap( dest, dest.getRowBytes(), src, src.getRowBytes(), dest.getHeight()); } /** * Reconfigures bitmap after checking its allocation size. * * <p> This method is here to overcome our testing framework limit. Robolectric does not provide * KitKat specific APIs: {@link Bitmap#reconfigure} and {@link Bitmap#getAllocationByteCount} * are part of that. */ @TargetApi(19) public static void reconfigureBitmap(Bitmap bitmap, int width, int height) { Preconditions.checkArgument( bitmap.getAllocationByteCount() >= width * height * BYTES_PER_PIXEL); bitmap.reconfigure(width, height, BITMAP_CONFIG); } @DoNotStrip private static native void nativePinBitmap(Bitmap bitmap); @DoNotStrip private static native void nativeCopyBitmap( Bitmap dest, int destStride, Bitmap src, int srcStride, int rows); }