Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef5498ed authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Add reconfigure method to Bitmap"

parents 350503fb c84d203d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -8742,13 +8742,17 @@ package android.graphics {
    method public final boolean isPremultiplied();
    method public final boolean isRecycled();
    method public void prepareToDraw();
    method public void reconfigure(int, int, android.graphics.Bitmap.Config);
    method public void recycle();
    method public boolean sameAs(android.graphics.Bitmap);
    method public void setConfig(android.graphics.Bitmap.Config);
    method public void setDensity(int);
    method public void setHasAlpha(boolean);
    method public final void setHasMipMap(boolean);
    method public void setHeight(int);
    method public void setPixel(int, int, int);
    method public void setPixels(int[], int, int, int, int, int, int);
    method public void setWidth(int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
    field public static final int DENSITY_NONE = 0; // 0x0
+21 −0
Original line number Diff line number Diff line
@@ -271,6 +271,26 @@ static jboolean Bitmap_recycle(JNIEnv* env, jobject, SkBitmap* bitmap) {
    return true;
}

static void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jint bitmapInt,
        int width, int height, SkBitmap::Config config, int allocSize) {
    if (width * height * SkBitmap::ComputeBytesPerPixel(config) > allocSize) {
        // done in native as there's no way to get BytesPerPixel in Java
        doThrowIAE(env, "Bitmap not large enough to support new configuration");
        return;
    }
    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapInt);
    SkPixelRef* ref = bitmap->pixelRef();
    SkSafeRef(ref);
    bitmap->setConfig(config, width, height);
    bitmap->setPixelRef(ref);

    // notifyPixelsChanged will increment the generation ID even though the actual pixel data
    // hasn't been touched. This signals the renderer that the bitmap (including width, height,
    // and config) has changed.
    ref->notifyPixelsChanged();
    SkSafeUnref(ref);
}

// These must match the int values in Bitmap.java
enum JavaEncodeFormat {
    kJPEG_JavaEncodeFormat = 0,
@@ -666,6 +686,7 @@ static JNINativeMethod gBitmapMethods[] = {
        (void*)Bitmap_copy },
    {   "nativeDestructor",         "(I)V", (void*)Bitmap_destructor },
    {   "nativeRecycle",            "(I)Z", (void*)Bitmap_recycle },
    {   "nativeReconfigure",        "(IIIII)V", (void*)Bitmap_reconfigure },
    {   "nativeCompress",           "(IIILjava/io/OutputStream;[B)Z",
        (void*)Bitmap_compress },
    {   "nativeErase",              "(II)V", (void*)Bitmap_erase },
+104 −7
Original line number Diff line number Diff line
@@ -171,6 +171,97 @@ public final class Bitmap implements Parcelable {
        mDensity = density;
    }

    /**
     * <p>Modifies the bitmap to have a specified width, height, and {@link
     * Config}, without affecting the underlying allocation backing the bitmap.
     * Bitmap pixel data is not re-initialized for the new configuration.</p>
     *
     * <p>This method can be used to avoid allocating a new bitmap, instead
     * reusing an existing bitmap's allocation for a new configuration of equal
     * or lesser size. If the Bitmap's allocation isn't large enough to support
     * the new configuration, an IllegalArgumentException will be thrown and the
     * bitmap will not be modified.</p>
     *
     * <p>The result of {@link #getByteCount()} will reflect the new configuration,
     * while {@link #getAllocationByteCount()} will reflect that of the initial
     * configuration.</p>
     *
     * <p>WARNING: This method should NOT be called on a bitmap currently used
     * by the view system. It does not make guarantees about how the underlying
     * pixel buffer is remapped to the new config, just that the allocation is
     * reused. Additionally, the view system does not account for bitmap
     * properties being modifying during use, e.g. while attached to
     * drawables.</p>
     *
     * @see #setWidth(int)
     * @see #setHeight(int)
     * @see #setConfig(Config)
     */
    public void reconfigure(int width, int height, Config config) {
        checkRecycled("Can't call reconfigure() on a recycled bitmap");
        if (width <= 0 || height <= 0) {
            throw new IllegalArgumentException("width and height must be > 0");
        }
        if (!isMutable()) {
            throw new IllegalArgumentException("only mutable bitmaps may be reconfigured");
        }
        if (mBuffer == null) {
            throw new IllegalArgumentException("only non-inPurgeable bitmaps may be reconfigured");
        }

        nativeReconfigure(mNativeBitmap, width, height, config.nativeInt, mBuffer.length);
        mWidth = width;
        mHeight = height;
    }

    /**
     * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
     * with the current height and config.</p>
     *
     * <p>WARNING: this method should not be used on bitmaps currently used by
     * the view system, see {@link #reconfigure(int, int, Config)} for more
     * details.</p>
     *
     * @see #reconfigure(int, int, Config)
     * @see #setHeight(int)
     * @see #setConfig(Config)
     */
    public void setWidth(int width) {
        reconfigure(width, getHeight(), getConfig());
    }

    /**
     * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
     * with the current width and config.</p>
     *
     * <p>WARNING: this method should not be used on bitmaps currently used by
     * the view system, see {@link #reconfigure(int, int, Config)} for more
     * details.</p>
     *
     * @see #reconfigure(int, int, Config)
     * @see #setWidth(int)
     * @see #setConfig(Config)
     */
    public void setHeight(int height) {
        reconfigure(getWidth(), height, getConfig());
    }

    /**
     * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
     * with the current height and width.</p>
     *
     * <p>WARNING: this method should not be used on bitmaps currently used by
     * the view system, see {@link #reconfigure(int, int, Config)} for more
     * details.</p>
     *
     * @see #reconfigure(int, int, Config)
     * @see #setWidth(int)
     * @see #setHeight(int)
     */
    public void setConfig(Config config) {
        reconfigure(getWidth(), getHeight(), config);
    }

    /**
     * Sets the nine patch chunk.
     *
@@ -1010,7 +1101,7 @@ public final class Bitmap implements Parcelable {
     *
     * <p>As of {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, the result of this method can
     * no longer be used to determine memory usage of a bitmap. See {@link
     * #getAllocationByteCount()}.
     * #getAllocationByteCount()}.</p>
     */
    public final int getByteCount() {
        // int result permits bitmaps up to 46,340 x 46,340
@@ -1021,11 +1112,15 @@ public final class Bitmap implements Parcelable {
     * Returns the size of the allocated memory used to store this bitmap's pixels.
     *
     * <p>This can be larger than the result of {@link #getByteCount()} if a bitmap is reused to
     * decode other bitmaps of smaller size. See {@link BitmapFactory.Options#inBitmap inBitmap in
     * BitmapFactory.Options}. If a bitmap is not reused in this way, this value will be the same as
     * that returned by {@link #getByteCount()}.
     * decode other bitmaps of smaller size, or by manual reconfiguration. See {@link
     * #reconfigure(int, int, Config)}, {@link #setWidth(int)}, {@link #setHeight(int)}, {@link
     * #setConfig(Bitmap.Config)}, and {@link BitmapFactory.Options#inBitmap
     * BitmapFactory.Options.inBitmap}. If a bitmap is not modified in this way, this value will be
     * the same as that returned by {@link #getByteCount()}.</p>
     *
     * <p>This value will not change over the lifetime of a Bitmap.</p>
     *
     * <p>This value will not change over the lifetime of a Bitmap.
     * @see #reconfigure(int, int, Config)
     */
    public final int getAllocationByteCount() {
        return mBuffer.length;
@@ -1428,6 +1523,8 @@ public final class Bitmap implements Parcelable {
                                            boolean isMutable);
    private static native void nativeDestructor(int nativeBitmap);
    private static native boolean nativeRecycle(int nativeBitmap);
    private static native void nativeReconfigure(int nativeBitmap, int width, int height,
                                                 int config, int allocSize);

    private static native boolean nativeCompress(int nativeBitmap, int format,
                                            int quality, OutputStream stream,
+26 −20
Original line number Diff line number Diff line
@@ -48,34 +48,40 @@ public class BitmapFactory {

        /**
         * If set, decode methods that take the Options object will attempt to
         * reuse this bitmap when loading content. If the decode operation cannot
         * use this bitmap, the decode method will return <code>null</code> and
         * will throw an IllegalArgumentException. The current implementation
         * necessitates that the reused bitmap be mutable, and the resulting
         * reused bitmap will continue to remain mutable even when decoding a
         * resource which would normally result in an immutable bitmap.
         * reuse this bitmap when loading content. If the decode operation
         * cannot use this bitmap, the decode method will return
         * <code>null</code> and will throw an IllegalArgumentException. The
         * current implementation necessitates that the reused bitmap be
         * mutable, and the resulting reused bitmap will continue to remain
         * mutable even when decoding a resource which would normally result in
         * an immutable bitmap.</p>
         *
         * <p>As of {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, any mutable
         * bitmap can be reused to decode any other bitmaps as long as the resulting
         * {@link Bitmap#getByteCount() byte count} of the decoded bitmap is less
         * than or equal to the {@link Bitmap#getAllocationByteCount() allocated byte count}
         * of the reused bitmap. This can be because the intrinsic size is smaller,
         * or the size after density / sampled size scaling is smaller.
         * <p>As of {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}, any
         * mutable bitmap can be reused to decode any other bitmaps as long as
         * the resulting {@link Bitmap#getByteCount() byte count} of the decoded
         * bitmap is less than or equal to the {@link
         * Bitmap#getAllocationByteCount() allocated byte count} of the reused
         * bitmap. This can be because the intrinsic size is smaller, or its
         * size post scaling (for density / sample size) is smaller.</p>
         *
         * <p>Prior to {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE} additional
         * constraints apply: The image being decoded (whether as a resource or
         * as a stream) must be in jpeg or png format. Only equal sized bitmaps
         * are supported, with {@link #inSampleSize} set to 1. Additionally, the
         * {@link android.graphics.Bitmap.Config configuration} of the reused
         * bitmap will override the setting of {@link #inPreferredConfig}, if set.
         * <p>Prior to {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE}
         * additional constraints apply: The image being decoded (whether as a
         * resource or as a stream) must be in jpeg or png format. Only equal
         * sized bitmaps are supported, with {@link #inSampleSize} set to 1.
         * Additionally, the {@link android.graphics.Bitmap.Config
         * configuration} of the reused bitmap will override the setting of
         * {@link #inPreferredConfig}, if set.</p>
         *
         * <p>You should still always use the returned Bitmap of the decode
         * method and not assume that reusing the bitmap worked, due to the
         * constraints outlined above and failure situations that can occur.
         * Checking whether the return value matches the value of the inBitmap
         * set in the Options structure will indicate if the bitmap was reused,
         * but in all cases you should use the Bitmap returned by the decoding function to ensure
         * that you are using the bitmap that was used as the decode destination.</p>
         * but in all cases you should use the Bitmap returned by the decoding
         * function to ensure that you are using the bitmap that was used as the
         * decode destination.</p>
         *
         * @see Bitmap#reconfigure(int,int,Config)
         */
        public Bitmap inBitmap;