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

Commit 14720d38 authored by John Reck's avatar John Reck Committed by Automerger Merge Worker
Browse files

Merge "Transform & preserve gainmaps" into udc-dev am: 3bc2f704

parents a722a063 3bc2f704
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -997,12 +997,63 @@ public final class Bitmap implements Parcelable {
        canvas.concat(m);
        canvas.drawBitmap(source, srcR, dstR, paint);
        canvas.setBitmap(null);

        // If the source has a gainmap, apply the same set of transformations to the gainmap
        // and set it on the output
        if (source.hasGainmap()) {
            Bitmap newMapContents = transformGainmap(source, m, neww, newh, paint, srcR, dstR,
                    deviceR);
            if (newMapContents != null) {
                bitmap.setGainmap(new Gainmap(source.getGainmap(), newMapContents));
            }
        }

        if (isHardware) {
            return bitmap.copy(Config.HARDWARE, false);
        }
        return bitmap;
    }

    private static Bitmap transformGainmap(Bitmap source, Matrix m, int neww, int newh, Paint paint,
            Rect srcR, RectF dstR, RectF deviceR) {
        Canvas canvas;
        Bitmap sourceGainmap = source.getGainmap().getGainmapContents();
        // Gainmaps can be scaled relative to the base image (eg, 1/4th res)
        // Preserve that relative scaling between the base & gainmap in the output
        float scaleX = (sourceGainmap.getWidth() / (float) source.getWidth());
        float scaleY = (sourceGainmap.getHeight() / (float) source.getHeight());
        int mapw = Math.round(neww * scaleX);
        int maph = Math.round(newh * scaleY);

        if (mapw == 0 || maph == 0) {
            // The gainmap has been scaled away entirely, drop it
            return null;
        }

        // Scale the computed `srcR` used for rendering the source bitmap to the destination
        // to be in gainmap dimensions
        Rect gSrcR = new Rect((int) (srcR.left * scaleX),
                (int) (srcR.top * scaleY), (int) (srcR.right * scaleX),
                (int) (srcR.bottom * scaleY));

        // Note: createBitmap isn't used as that requires a non-null colorspace, however
        // gainmaps don't have a colorspace. So use `nativeCreate` directly to bypass
        // that colorspace enforcement requirement (#getColorSpace() allows a null return)
        Bitmap newMapContents = nativeCreate(null, 0, mapw, mapw, maph,
                sourceGainmap.getConfig().nativeInt, true, 0);
        newMapContents.eraseColor(0);
        canvas = new Canvas(newMapContents);
        // Scale the translate & matrix to be in gainmap-relative dimensions
        canvas.scale(scaleX, scaleY);
        canvas.translate(-deviceR.left, -deviceR.top);
        canvas.concat(m);
        canvas.drawBitmap(sourceGainmap, gSrcR, dstR, paint);
        canvas.setBitmap(null);
        // Create a new gainmap using a copy of the metadata information from the source but
        // with the transformed bitmap created above
        return newMapContents;
    }

    /**
     * Returns a mutable bitmap with the specified width and height.  Its
     * initial density is as per {@link #getDensity}. The newly created
+11 −0
Original line number Diff line number Diff line
@@ -121,6 +121,16 @@ public final class Gainmap implements Parcelable {
        this(gainmapContents, nCreateEmpty());
    }

    /**
     * Creates a new gainmap using the provided gainmap as the metadata source and the provided
     * bitmap as the replacement for the gainmapContents
     * TODO: Make public, it's useful
     * @hide
     */
    public Gainmap(@NonNull Gainmap gainmap, @NonNull Bitmap gainmapContents) {
        this(gainmapContents, nCreateCopy(gainmap.mNativePtr));
    }

    /**
     * @return Returns the image data of the gainmap represented as a Bitmap. This is represented
     * as a Bitmap for broad API compatibility, however certain aspects of the Bitmap are ignored
@@ -325,6 +335,7 @@ public final class Gainmap implements Parcelable {

    private static native long nGetFinalizer();
    private static native long nCreateEmpty();
    private static native long nCreateCopy(long source);

    private static native void nSetBitmap(long ptr, Bitmap bitmap);

+11 −0
Original line number Diff line number Diff line
@@ -86,6 +86,16 @@ jlong Gainmap_createEmpty(JNIEnv*, jobject) {
    return static_cast<jlong>(reinterpret_cast<uintptr_t>(gainmap));
}

jlong Gainmap_createCopy(JNIEnv*, jobject, jlong sourcePtr) {
    Gainmap* gainmap = new Gainmap();
    gainmap->incStrong(0);
    if (sourcePtr) {
        Gainmap* src = fromJava(sourcePtr);
        gainmap->info = src->info;
    }
    return static_cast<jlong>(reinterpret_cast<uintptr_t>(gainmap));
}

static void Gainmap_setBitmap(JNIEnv* env, jobject, jlong gainmapPtr, jobject jBitmap) {
    android::Bitmap* bitmap = GraphicsJNI::getNativeBitmap(env, jBitmap);
    fromJava(gainmapPtr)->bitmap = sk_ref_sp(bitmap);
@@ -237,6 +247,7 @@ static void Gainmap_readFromParcel(JNIEnv* env, jobject, jlong nativeObject, job
static const JNINativeMethod gGainmapMethods[] = {
        {"nGetFinalizer", "()J", (void*)Gainmap_getNativeFinalizer},
        {"nCreateEmpty", "()J", (void*)Gainmap_createEmpty},
        {"nCreateCopy", "(J)J", (void*)Gainmap_createCopy},
        {"nSetBitmap", "(JLandroid/graphics/Bitmap;)V", (void*)Gainmap_setBitmap},
        {"nSetRatioMin", "(JFFF)V", (void*)Gainmap_setRatioMin},
        {"nGetRatioMin", "(J[F)V", (void*)Gainmap_getRatioMin},
+122 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2023 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<com.android.test.silkfx.hdr.GainmapTransformsTest xmlns:android="http://schemas.android.com/apk/res/android"
                                               android:layout_width="match_parent"
                                               android:layout_height="match_parent"
                                               android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/original"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Original" />

        <Button
            android:id="@+id/scaled"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Scaled (1/3)" />

        <Button
            android:id="@+id/rotate_90"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Rotate 90" />

        <Button
            android:id="@+id/rotate_90_scaled"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Rot90+Scale" />

        <Button
            android:id="@+id/crop"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Crop" />

        <Button
            android:id="@+id/crop_200"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Crop 200" />

    </LinearLayout>

    <TextView
        android:id="@+id/source_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_weight="1">

            <TextView
                android:id="@+id/sdr_label"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <ImageView
                android:id="@+id/sdr_source"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="8dp"
                android:scaleType="fitStart" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_weight="1">

            <TextView
                android:id="@+id/gainmap_label"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <ImageView
                android:id="@+id/gainmap"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="8dp"
                android:scaleType="fitStart" />
        </LinearLayout>

    </LinearLayout>

</com.android.test.silkfx.hdr.GainmapTransformsTest>
 No newline at end of file
+3 −1
Original line number Diff line number Diff line
@@ -55,7 +55,9 @@ private val AllDemos = listOf(
                Demo("Color Grid", R.layout.color_grid),
                Demo("Gradient Sweep", R.layout.gradient_sweep),
                Demo("Gainmap Image", R.layout.gainmap_image),
                Demo("Gainmap Decode Test", R.layout.gainmap_decode_test, commonControls = false)
                Demo("Gainmap Decode Test", R.layout.gainmap_decode_test, commonControls = false),
                Demo("Gainmap Transform Test", R.layout.gainmap_transform_test,
                        commonControls = false)
        )),
        DemoGroup("Materials", listOf(
                Demo("Glass", GlassActivity::class),
Loading