Add Gainmap API
Bug: 266628247 Test: CtsGraphicsTestCases:GainmapTest Change-Id: I288516df8ba2bb72525462699d2704bb43a0fd90
This commit is contained in:
@@ -14779,6 +14779,7 @@ package android.graphics {
|
||||
method @Nullable public android.graphics.ColorSpace getColorSpace();
|
||||
method @NonNull public android.graphics.Bitmap.Config getConfig();
|
||||
method public int getDensity();
|
||||
method @Nullable public android.graphics.Gainmap getGainmap();
|
||||
method public int getGenerationId();
|
||||
method @NonNull public android.hardware.HardwareBuffer getHardwareBuffer();
|
||||
method public int getHeight();
|
||||
@@ -14794,6 +14795,7 @@ package android.graphics {
|
||||
method public int getScaledWidth(int);
|
||||
method public int getWidth();
|
||||
method public boolean hasAlpha();
|
||||
method public boolean hasGainmap();
|
||||
method public boolean hasMipMap();
|
||||
method public boolean isMutable();
|
||||
method public boolean isPremultiplied();
|
||||
@@ -14805,6 +14807,7 @@ package android.graphics {
|
||||
method public void setColorSpace(@NonNull android.graphics.ColorSpace);
|
||||
method public void setConfig(@NonNull android.graphics.Bitmap.Config);
|
||||
method public void setDensity(int);
|
||||
method public void setGainmap(@Nullable android.graphics.Gainmap);
|
||||
method public void setHasAlpha(boolean);
|
||||
method public void setHasMipMap(boolean);
|
||||
method public void setHeight(int);
|
||||
@@ -15338,6 +15341,26 @@ package android.graphics {
|
||||
ctor @Deprecated public EmbossMaskFilter(float[], float, float, float);
|
||||
}
|
||||
|
||||
public final class Gainmap {
|
||||
ctor public Gainmap(@NonNull android.graphics.Bitmap);
|
||||
method @NonNull public float getDisplayRatioForFullHdr();
|
||||
method @NonNull public float[] getEpsilonHdr();
|
||||
method @NonNull public float[] getEpsilonSdr();
|
||||
method @NonNull public android.graphics.Bitmap getGainmapContents();
|
||||
method @NonNull public float[] getGamma();
|
||||
method @NonNull public float getMinDisplayRatioForHdrTransition();
|
||||
method @NonNull public float[] getRatioMax();
|
||||
method @NonNull public float[] getRatioMin();
|
||||
method @NonNull public void setDisplayRatioForFullHdr(float);
|
||||
method @NonNull public void setEpsilonHdr(float, float, float);
|
||||
method @NonNull public void setEpsilonSdr(float, float, float);
|
||||
method public void setGainmapContents(@NonNull android.graphics.Bitmap);
|
||||
method @NonNull public void setGamma(float, float, float);
|
||||
method @NonNull public void setMinDisplayRatioForHdrTransition(@FloatRange(from=1.0f) float);
|
||||
method @NonNull public void setRatioMax(float, float, float);
|
||||
method @NonNull public void setRatioMin(float, float, float);
|
||||
}
|
||||
|
||||
public class HardwareBufferRenderer implements java.lang.AutoCloseable {
|
||||
ctor public HardwareBufferRenderer(@NonNull android.hardware.HardwareBuffer);
|
||||
method public void close();
|
||||
|
||||
@@ -1899,7 +1899,6 @@ public final class Bitmap implements Parcelable {
|
||||
|
||||
/**
|
||||
* Returns whether or not this Bitmap contains a Gainmap.
|
||||
* @hide
|
||||
*/
|
||||
public boolean hasGainmap() {
|
||||
checkRecycled("Bitmap is recycled");
|
||||
@@ -1908,7 +1907,6 @@ public final class Bitmap implements Parcelable {
|
||||
|
||||
/**
|
||||
* Returns the gainmap or null if the bitmap doesn't contain a gainmap
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable Gainmap getGainmap() {
|
||||
checkRecycled("Bitmap is recycled");
|
||||
@@ -1918,6 +1916,14 @@ public final class Bitmap implements Parcelable {
|
||||
return mGainmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a gainmap on this bitmap, or removes the gainmap if null
|
||||
*/
|
||||
public void setGainmap(@Nullable Gainmap gainmap) {
|
||||
checkRecycled("Bitmap is recycled");
|
||||
nativeSetGainmap(mNativePtr, gainmap == null ? 0 : gainmap.mNativePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the bitmap's pixels with the specified {@link Color}.
|
||||
*
|
||||
@@ -2403,6 +2409,7 @@ public final class Bitmap implements Parcelable {
|
||||
private static native void nativeSetImmutable(long nativePtr);
|
||||
|
||||
private static native Gainmap nativeExtractGainmap(long nativePtr);
|
||||
private static native void nativeSetGainmap(long bitmapPtr, long gainmapPtr);
|
||||
|
||||
// ---------------- @CriticalNative -------------------
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.graphics;
|
||||
|
||||
import android.annotation.FloatRange;
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import libcore.util.NativeAllocationRegistry;
|
||||
@@ -24,104 +25,288 @@ import libcore.util.NativeAllocationRegistry;
|
||||
* Gainmap represents a mechanism for augmenting an SDR image to produce an HDR one with variable
|
||||
* display adjustment capability.
|
||||
*
|
||||
* It is a combination of a set of metadata describing the gainmap, as well as either a 1 or 3
|
||||
* It is a combination of a set of metadata describing how to apply the gainmap, as well as either
|
||||
* a 1 (such as {@link android.graphics.Bitmap.Config#ALPHA_8} or 3
|
||||
* (such as {@link android.graphics.Bitmap.Config#ARGB_8888} with the alpha channel ignored)
|
||||
* channel Bitmap that represents the gainmap data itself.
|
||||
*
|
||||
* @hide
|
||||
* When rendering to an {@link android.content.pm.ActivityInfo#COLOR_MODE_HDR} activity, the
|
||||
* hardware accelerated {@link Canvas} will automatically apply the gainmap when sufficient
|
||||
* HDR headroom is available.
|
||||
*
|
||||
* <h3>Gainmap Structure</h3>
|
||||
*
|
||||
* The logical whole of a gainmap'd image consists of a base Bitmap that represents the original
|
||||
* image as would be displayed without gainmap support in addition to a gainmap with a second
|
||||
* enhancement image. In the case of a JPEG, the base image would be the typical 8-bit SDR image
|
||||
* that the format is commonly associated with. The gainmap image is embedded alongside the base
|
||||
* image, often at a lower resolution (such as 1/4th), along with some metadata to describe
|
||||
* how to apply the gainmap. The gainmap image itself is then a greyscale image representing
|
||||
* the transformation to apply onto the base image to reconstruct an HDR rendition of it.
|
||||
*
|
||||
* As such these "gainmap images" consist of 3 parts - a base {@link Bitmap} with a
|
||||
* {@link Bitmap#getGainmap()} that returns an instance of this class which in turn contains
|
||||
* the enhancement layer represented as another Bitmap, accessible via {@link #getGainmapContents()}
|
||||
*
|
||||
* <h3>Applying a gainmap manually</h3>
|
||||
*
|
||||
* When doing custom rendering such as to an OpenGL ES or Vulkan context, the gainmap is not
|
||||
* automatically applied. In such situations, the following steps are appropriate to render the
|
||||
* gainmap in combination with the base image.
|
||||
*
|
||||
* Suppose our display has HDR to SDR ratio of H, and we wish to display an image with gainmap on
|
||||
* this display. Let B be the pixel value from the base image in a color space that has the
|
||||
* primaries of the base image and a linear transfer function. Let G be the pixel value from the
|
||||
* gainmap. Let D be the output pixel in the same color space as B. The value of D is computed
|
||||
* as follows:
|
||||
*
|
||||
* First, let W be a weight parameter determining how much the gainmap will be applied.
|
||||
* W = clamp((log(H) - log(displayRatioHdr)) /
|
||||
* (log(displayRatioHdr) - log(displayRatioSdr), 0, 1)
|
||||
*
|
||||
* Next, let L be the gainmap value in log space. We compute this from the value G that was
|
||||
* sampled from the texture as follows:
|
||||
* L = mix(log(gainmapRatioMin), log(gainmapRatioMax), pow(G, gainmapGamma))
|
||||
*
|
||||
* Finally, apply the gainmap to compute D, the displayed pixel. If the base image is SDR then
|
||||
* compute:
|
||||
* D = (B + epsilonSdr) * exp(L * W) - epsilonHdr
|
||||
* If the base image is HDR then compute:
|
||||
* D = (B + epsilonHdr) * exp(L * (W - 1)) - epsilonSdr
|
||||
*
|
||||
* In the above math, log() is a natural logarithm and exp() is natural exponentiation.
|
||||
*/
|
||||
public class Gainmap {
|
||||
private final long mNativePtr;
|
||||
private final Bitmap mGainmapImage;
|
||||
public final class Gainmap {
|
||||
|
||||
// called from JNI and Bitmap_Delegate.
|
||||
private Gainmap(Bitmap gainmapImage, long nativeGainmap, int allocationByteCount,
|
||||
boolean fromMalloc) {
|
||||
// Use a Holder to allow static initialization of Gainmap in the boot image.
|
||||
private static class NoImagePreloadHolder {
|
||||
public static final NativeAllocationRegistry sRegistry =
|
||||
NativeAllocationRegistry.createMalloced(
|
||||
Gainmap.class.getClassLoader(), nGetFinalizer());
|
||||
}
|
||||
|
||||
final long mNativePtr;
|
||||
private Bitmap mGainmapContents;
|
||||
|
||||
// called from JNI
|
||||
private Gainmap(Bitmap gainmapContents, long nativeGainmap) {
|
||||
if (nativeGainmap == 0) {
|
||||
throw new RuntimeException("internal error: native gainmap is 0");
|
||||
}
|
||||
|
||||
mGainmapImage = gainmapImage;
|
||||
mGainmapContents = gainmapContents;
|
||||
mNativePtr = nativeGainmap;
|
||||
|
||||
final NativeAllocationRegistry registry;
|
||||
if (fromMalloc) {
|
||||
registry = NativeAllocationRegistry.createMalloced(
|
||||
Bitmap.class.getClassLoader(), nGetFinalizer(), allocationByteCount);
|
||||
} else {
|
||||
registry = NativeAllocationRegistry.createNonmalloced(
|
||||
Bitmap.class.getClassLoader(), nGetFinalizer(), allocationByteCount);
|
||||
}
|
||||
registry.registerNativeAllocation(this, nativeGainmap);
|
||||
NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, nativeGainmap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image data of the gainmap represented as a Bitmap
|
||||
* @return
|
||||
* Creates a gainmap from a given Bitmap. The caller is responsible for setting the various
|
||||
* fields to the desired values. The defaults are as follows:
|
||||
* <ul>
|
||||
* <li>Ratio min is 1f, 1f, 1f</li>
|
||||
* <li>Ratio max is 2f, 2f, 2f</li>
|
||||
* <li>Gamma is 1f, 1f, 1f</li>
|
||||
* <li>Epsilon SDR is 0f, 0f, 0f</li>
|
||||
* <li>Epsilon HDR is 0f, 0f, 0f</li>
|
||||
* <li>Display ratio SDR is 1f</li>
|
||||
* <li>Display ratio HDR is 2f</li>
|
||||
* </ul>
|
||||
* It is strongly recommended that at least the ratio max and display ratio HDR are adjusted
|
||||
* to better suit the given gainmap contents.
|
||||
*/
|
||||
public Gainmap(@NonNull Bitmap gainmapContents) {
|
||||
this(gainmapContents, nCreateEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* such as {@link Bitmap#getColorSpace()} or {@link Bitmap#getGainmap()} as they are not
|
||||
* relevant to the gainmap's enhancement layer.
|
||||
*/
|
||||
@NonNull
|
||||
public Bitmap getGainmapImage() {
|
||||
return mGainmapImage;
|
||||
public Bitmap getGainmapContents() {
|
||||
return mGainmapContents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the gainmap max metadata. For single-plane gainmaps, r, g, and b should be the same.
|
||||
* Sets the image data of the gainmap. This is the 1 or 3 channel enhancement layer to apply
|
||||
* to the base image. This is represented as a Bitmap for broad API compatibility, however
|
||||
* certain aspects of the Bitmap are ignored such as {@link Bitmap#getColorSpace()} or
|
||||
* {@link Bitmap#getGainmap()} as they are not relevant to the gainmap's enhancement layer.
|
||||
*
|
||||
* @param bitmap The non-null bitmap to set as the gainmap's contents
|
||||
*/
|
||||
public void setGainmapContents(@NonNull Bitmap bitmap) {
|
||||
// TODO: Validate here or leave native-side?
|
||||
if (bitmap.isRecycled()) throw new IllegalArgumentException("Bitmap is recycled");
|
||||
nSetBitmap(mNativePtr, bitmap);
|
||||
mGainmapContents = bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the gainmap ratio min. For single-plane gainmaps, r, g, and b should be the same.
|
||||
*/
|
||||
@NonNull
|
||||
public void setGainmapMax(float r, float g, float b) {
|
||||
nSetGainmapMax(mNativePtr, r, g, b);
|
||||
public void setRatioMin(float r, float g, float b) {
|
||||
nSetRatioMin(mNativePtr, r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the gainmap max metadata. For single-plane gainmaps, all 3 components should be the
|
||||
* Gets the gainmap ratio max. For single-plane gainmaps, all 3 components should be the
|
||||
* same. The components are in r, g, b order.
|
||||
*/
|
||||
@NonNull
|
||||
public float[] getGainmapMax() {
|
||||
public float[] getRatioMin() {
|
||||
float[] ret = new float[3];
|
||||
nGetGainmapMax(mNativePtr, ret);
|
||||
nGetRatioMin(mNativePtr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum HDR ratio for the gainmap
|
||||
* Sets the gainmap ratio max. For single-plane gainmaps, r, g, and b should be the same.
|
||||
*/
|
||||
@NonNull
|
||||
public void setHdrRatioMax(float max) {
|
||||
nSetHdrRatioMax(mNativePtr, max);
|
||||
public void setRatioMax(float r, float g, float b) {
|
||||
nSetRatioMax(mNativePtr, r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum HDR ratio for the gainmap
|
||||
* Gets the gainmap ratio max. For single-plane gainmaps, all 3 components should be the
|
||||
* same. The components are in r, g, b order.
|
||||
*/
|
||||
@NonNull
|
||||
public float getHdrRatioMax() {
|
||||
return nGetHdrRatioMax(mNativePtr);
|
||||
public float[] getRatioMax() {
|
||||
float[] ret = new float[3];
|
||||
nGetRatioMax(mNativePtr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum HDR ratio for the gainmap
|
||||
* Sets the gainmap gamma. For single-plane gainmaps, r, g, and b should be the same.
|
||||
*/
|
||||
@NonNull
|
||||
public void setHdrRatioMin(float min) {
|
||||
nSetHdrRatioMin(mNativePtr, min);
|
||||
public void setGamma(float r, float g, float b) {
|
||||
nSetGamma(mNativePtr, r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum HDR ratio for the gainmap
|
||||
* Gets the gainmap gamma. For single-plane gainmaps, all 3 components should be the
|
||||
* same. The components are in r, g, b order.
|
||||
*/
|
||||
@NonNull
|
||||
public float getHdrRatioMin() {
|
||||
return nGetHdrRatioMin(mNativePtr);
|
||||
public float[] getGamma() {
|
||||
float[] ret = new float[3];
|
||||
nGetGamma(mNativePtr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the sdr epsilon which is used to avoid numerical instability.
|
||||
* For single-plane gainmaps, r, g, and b should be the same.
|
||||
*/
|
||||
@NonNull
|
||||
public void setEpsilonSdr(float r, float g, float b) {
|
||||
nSetEpsilonSdr(mNativePtr, r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sdr epsilon. For single-plane gainmaps, all 3 components should be the
|
||||
* same. The components are in r, g, b order.
|
||||
*/
|
||||
@NonNull
|
||||
public float[] getEpsilonSdr() {
|
||||
float[] ret = new float[3];
|
||||
nGetEpsilonSdr(mNativePtr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hdr epsilon which is used to avoid numerical instability.
|
||||
* For single-plane gainmaps, r, g, and b should be the same.
|
||||
*/
|
||||
@NonNull
|
||||
public void setEpsilonHdr(float r, float g, float b) {
|
||||
nSetEpsilonHdr(mNativePtr, r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hdr epsilon. For single-plane gainmaps, all 3 components should be the
|
||||
* same. The components are in r, g, b order.
|
||||
*/
|
||||
@NonNull
|
||||
public float[] getEpsilonHdr() {
|
||||
float[] ret = new float[3];
|
||||
nGetEpsilonHdr(mNativePtr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hdr/sdr ratio at which point the gainmap is fully applied.
|
||||
* @param max The hdr/sdr ratio at which the gainmap is fully applied. Must be >= 1.0f
|
||||
*/
|
||||
@NonNull
|
||||
public void setDisplayRatioForFullHdr(float max) {
|
||||
if (!Float.isFinite(max) || max < 1f) {
|
||||
throw new IllegalArgumentException(
|
||||
"setDisplayRatioForFullHdr must be >= 1.0f, got = " + max);
|
||||
}
|
||||
nSetDisplayRatioHdr(mNativePtr, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hdr/sdr ratio at which point the gainmap is fully applied.
|
||||
*/
|
||||
@NonNull
|
||||
public float getDisplayRatioForFullHdr() {
|
||||
return nGetDisplayRatioHdr(mNativePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hdr/sdr ratio below which only the SDR image is displayed.
|
||||
* @param min The minimum hdr/sdr ratio at which to begin applying the gainmap. Must be >= 1.0f
|
||||
*/
|
||||
@NonNull
|
||||
public void setMinDisplayRatioForHdrTransition(@FloatRange(from = 1.0f) float min) {
|
||||
if (!Float.isFinite(min) || min < 1f) {
|
||||
throw new IllegalArgumentException(
|
||||
"setMinDisplayRatioForHdrTransition must be >= 1.0f, got = " + min);
|
||||
}
|
||||
nSetDisplayRatioSdr(mNativePtr, min);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hdr/sdr ratio below which only the SDR image is displayed.
|
||||
*/
|
||||
@NonNull
|
||||
public float getMinDisplayRatioForHdrTransition() {
|
||||
return nGetDisplayRatioSdr(mNativePtr);
|
||||
}
|
||||
|
||||
private static native long nGetFinalizer();
|
||||
private static native long nCreateEmpty();
|
||||
|
||||
private static native void nSetGainmapMax(long ptr, float r, float g, float b);
|
||||
private static native void nGetGainmapMax(long ptr, float[] components);
|
||||
private static native void nSetBitmap(long ptr, Bitmap bitmap);
|
||||
|
||||
private static native void nSetHdrRatioMax(long ptr, float max);
|
||||
private static native float nGetHdrRatioMax(long ptr);
|
||||
private static native void nSetRatioMin(long ptr, float r, float g, float b);
|
||||
private static native void nGetRatioMin(long ptr, float[] components);
|
||||
|
||||
private static native void nSetHdrRatioMin(long ptr, float min);
|
||||
private static native float nGetHdrRatioMin(long ptr);
|
||||
private static native void nSetRatioMax(long ptr, float r, float g, float b);
|
||||
private static native void nGetRatioMax(long ptr, float[] components);
|
||||
|
||||
private static native void nSetGamma(long ptr, float r, float g, float b);
|
||||
private static native void nGetGamma(long ptr, float[] components);
|
||||
|
||||
private static native void nSetEpsilonSdr(long ptr, float r, float g, float b);
|
||||
private static native void nGetEpsilonSdr(long ptr, float[] components);
|
||||
|
||||
private static native void nSetEpsilonHdr(long ptr, float r, float g, float b);
|
||||
private static native void nGetEpsilonHdr(long ptr, float[] components);
|
||||
|
||||
private static native void nSetDisplayRatioHdr(long ptr, float max);
|
||||
private static native float nGetDisplayRatioHdr(long ptr);
|
||||
|
||||
private static native void nSetDisplayRatioSdr(long ptr, float min);
|
||||
private static native float nGetDisplayRatioSdr(long ptr);
|
||||
}
|
||||
|
||||
@@ -506,6 +506,9 @@ SkCodec::Result ImageDecoder::extractGainmap(Bitmap* destination) {
|
||||
decoder.mOverrideOrigin.emplace(getOrigin());
|
||||
// Update mDecodeSize / mTargetSize for the overridden origin
|
||||
decoder.setTargetSize(decoder.width(), decoder.height());
|
||||
if (decoder.gray()) {
|
||||
decoder.setOutColorType(kGray_8_SkColorType);
|
||||
}
|
||||
|
||||
const bool isScaled = width() != mTargetSize.width() || height() != mTargetSize.height();
|
||||
|
||||
@@ -528,6 +531,9 @@ SkCodec::Result ImageDecoder::extractGainmap(Bitmap* destination) {
|
||||
}
|
||||
|
||||
SkImageInfo bitmapInfo = decoder.getOutputInfo();
|
||||
if (bitmapInfo.colorType() == kGray_8_SkColorType) {
|
||||
bitmapInfo = bitmapInfo.makeColorType(kAlpha_8_SkColorType);
|
||||
}
|
||||
|
||||
SkBitmap bm;
|
||||
if (!bm.setInfo(bitmapInfo)) {
|
||||
|
||||
@@ -1269,6 +1269,13 @@ static jobject Bitmap_extractGainmap(JNIEnv* env, jobject, jlong bitmapHandle) {
|
||||
return Gainmap_extractFromBitmap(env, bitmapHolder->bitmap());
|
||||
}
|
||||
|
||||
static void Bitmap_setGainmap(JNIEnv*, jobject, jlong bitmapHandle, jlong gainmapPtr) {
|
||||
LocalScopedBitmap bitmapHolder(bitmapHandle);
|
||||
if (!bitmapHolder.valid()) return;
|
||||
uirenderer::Gainmap* gainmap = reinterpret_cast<uirenderer::Gainmap*>(gainmapPtr);
|
||||
bitmapHolder->bitmap().setGainmap(sp<uirenderer::Gainmap>::fromExisting(gainmap));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const JNINativeMethod gBitmapMethods[] = {
|
||||
@@ -1320,6 +1327,7 @@ static const JNINativeMethod gBitmapMethods[] = {
|
||||
{"nativeIsSRGBLinear", "(J)Z", (void*)Bitmap_isSRGBLinear},
|
||||
{"nativeSetImmutable", "(J)V", (void*)Bitmap_setImmutable},
|
||||
{"nativeExtractGainmap", "(J)Landroid/graphics/Gainmap;", (void*)Bitmap_extractGainmap},
|
||||
{"nativeSetGainmap", "(JJ)V", (void*)Bitmap_setGainmap},
|
||||
|
||||
// ------------ @CriticalNative ----------------
|
||||
{"nativeIsImmutable", "(J)Z", (void*)Bitmap_isImmutable},
|
||||
|
||||
@@ -45,20 +45,18 @@ static int getCreateFlags(const sk_sp<Bitmap>& bitmap) {
|
||||
jobject Gainmap_extractFromBitmap(JNIEnv* env, const Bitmap& bitmap) {
|
||||
auto gainmap = bitmap.gainmap();
|
||||
jobject jGainmapImage;
|
||||
size_t allocationSize;
|
||||
|
||||
{
|
||||
// Scope to guard the release of nativeBitmap
|
||||
auto nativeBitmap = gainmap->bitmap;
|
||||
const int createFlags = getCreateFlags(nativeBitmap);
|
||||
allocationSize = nativeBitmap->getAllocationByteCount();
|
||||
jGainmapImage = bitmap::createBitmap(env, nativeBitmap.release(), createFlags);
|
||||
}
|
||||
|
||||
// Grab a ref for the jobject
|
||||
gainmap->incStrong(0);
|
||||
jobject obj = env->NewObject(gGainmap_class, gGainmap_constructorMethodID, jGainmapImage,
|
||||
gainmap.get(), allocationSize + sizeof(Gainmap), true);
|
||||
gainmap.get());
|
||||
|
||||
if (env->ExceptionCheck() != 0) {
|
||||
// sadtrombone
|
||||
@@ -77,47 +75,109 @@ static jlong Gainmap_getNativeFinalizer(JNIEnv*, jobject) {
|
||||
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Gainmap_destructor));
|
||||
}
|
||||
|
||||
static void Gainmap_setGainmapMax(JNIEnv*, jobject, jlong gainmapPtr, jfloat r, jfloat g,
|
||||
jfloat b) {
|
||||
fromJava(gainmapPtr)->info.fLogRatioMax = {r, g, b, 1.f};
|
||||
jlong Gainmap_createEmpty(JNIEnv*, jobject) {
|
||||
Gainmap* gainmap = new Gainmap();
|
||||
gainmap->incStrong(0);
|
||||
return static_cast<jlong>(reinterpret_cast<uintptr_t>(gainmap));
|
||||
}
|
||||
|
||||
static void Gainmap_getGainmapMax(JNIEnv* env, jobject, jlong gainmapPtr, jfloatArray components) {
|
||||
const auto ratioMax = fromJava(gainmapPtr)->info.fLogRatioMax;
|
||||
jfloat buf[3]{ratioMax.fR, ratioMax.fG, ratioMax.fB};
|
||||
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);
|
||||
}
|
||||
|
||||
static void Gainmap_setRatioMin(JNIEnv*, jobject, jlong gainmapPtr, jfloat r, jfloat g, jfloat b) {
|
||||
fromJava(gainmapPtr)->info.fGainmapRatioMin = {r, g, b, 1.f};
|
||||
}
|
||||
|
||||
static void Gainmap_getRatioMin(JNIEnv* env, jobject, jlong gainmapPtr, jfloatArray components) {
|
||||
const auto value = fromJava(gainmapPtr)->info.fGainmapRatioMin;
|
||||
jfloat buf[3]{value.fR, value.fG, value.fB};
|
||||
env->SetFloatArrayRegion(components, 0, 3, buf);
|
||||
}
|
||||
|
||||
static void Gainmap_setHdrRatioMax(JNIEnv*, jobject, jlong gainmapPtr, jfloat max) {
|
||||
fromJava(gainmapPtr)->info.fHdrRatioMax = max;
|
||||
static void Gainmap_setRatioMax(JNIEnv*, jobject, jlong gainmapPtr, jfloat r, jfloat g, jfloat b) {
|
||||
fromJava(gainmapPtr)->info.fGainmapRatioMax = {r, g, b, 1.f};
|
||||
}
|
||||
|
||||
static jfloat Gainmap_getHdrRatioMax(JNIEnv*, jobject, jlong gainmapPtr) {
|
||||
return fromJava(gainmapPtr)->info.fHdrRatioMax;
|
||||
static void Gainmap_getRatioMax(JNIEnv* env, jobject, jlong gainmapPtr, jfloatArray components) {
|
||||
const auto value = fromJava(gainmapPtr)->info.fGainmapRatioMax;
|
||||
jfloat buf[3]{value.fR, value.fG, value.fB};
|
||||
env->SetFloatArrayRegion(components, 0, 3, buf);
|
||||
}
|
||||
|
||||
static void Gainmap_setHdrRatioMin(JNIEnv*, jobject, jlong gainmapPtr, jfloat min) {
|
||||
fromJava(gainmapPtr)->info.fHdrRatioMin = min;
|
||||
static void Gainmap_setGamma(JNIEnv*, jobject, jlong gainmapPtr, jfloat r, jfloat g, jfloat b) {
|
||||
fromJava(gainmapPtr)->info.fGainmapGamma = {r, g, b, 1.f};
|
||||
}
|
||||
|
||||
static jfloat Gainmap_getHdrRatioMin(JNIEnv*, jobject, jlong gainmapPtr) {
|
||||
return fromJava(gainmapPtr)->info.fHdrRatioMin;
|
||||
static void Gainmap_getGamma(JNIEnv* env, jobject, jlong gainmapPtr, jfloatArray components) {
|
||||
const auto value = fromJava(gainmapPtr)->info.fGainmapGamma;
|
||||
jfloat buf[3]{value.fR, value.fG, value.fB};
|
||||
env->SetFloatArrayRegion(components, 0, 3, buf);
|
||||
}
|
||||
|
||||
static void Gainmap_setEpsilonSdr(JNIEnv*, jobject, jlong gainmapPtr, jfloat r, jfloat g,
|
||||
jfloat b) {
|
||||
fromJava(gainmapPtr)->info.fEpsilonSdr = {r, g, b, 1.f};
|
||||
}
|
||||
|
||||
static void Gainmap_getEpsilonSdr(JNIEnv* env, jobject, jlong gainmapPtr, jfloatArray components) {
|
||||
const auto value = fromJava(gainmapPtr)->info.fEpsilonSdr;
|
||||
jfloat buf[3]{value.fR, value.fG, value.fB};
|
||||
env->SetFloatArrayRegion(components, 0, 3, buf);
|
||||
}
|
||||
|
||||
static void Gainmap_setEpsilonHdr(JNIEnv*, jobject, jlong gainmapPtr, jfloat r, jfloat g,
|
||||
jfloat b) {
|
||||
fromJava(gainmapPtr)->info.fEpsilonHdr = {r, g, b, 1.f};
|
||||
}
|
||||
|
||||
static void Gainmap_getEpsilonHdr(JNIEnv* env, jobject, jlong gainmapPtr, jfloatArray components) {
|
||||
const auto value = fromJava(gainmapPtr)->info.fEpsilonHdr;
|
||||
jfloat buf[3]{value.fR, value.fG, value.fB};
|
||||
env->SetFloatArrayRegion(components, 0, 3, buf);
|
||||
}
|
||||
|
||||
static void Gainmap_setDisplayRatioHdr(JNIEnv*, jobject, jlong gainmapPtr, jfloat max) {
|
||||
fromJava(gainmapPtr)->info.fDisplayRatioHdr = max;
|
||||
}
|
||||
|
||||
static jfloat Gainmap_getDisplayRatioHdr(JNIEnv*, jobject, jlong gainmapPtr) {
|
||||
return fromJava(gainmapPtr)->info.fDisplayRatioHdr;
|
||||
}
|
||||
|
||||
static void Gainmap_setDisplayRatioSdr(JNIEnv*, jobject, jlong gainmapPtr, jfloat min) {
|
||||
fromJava(gainmapPtr)->info.fDisplayRatioSdr = min;
|
||||
}
|
||||
|
||||
static jfloat Gainmap_getDisplayRatioSdr(JNIEnv*, jobject, jlong gainmapPtr) {
|
||||
return fromJava(gainmapPtr)->info.fDisplayRatioSdr;
|
||||
}
|
||||
|
||||
static const JNINativeMethod gGainmapMethods[] = {
|
||||
{"nGetFinalizer", "()J", (void*)Gainmap_getNativeFinalizer},
|
||||
{"nSetGainmapMax", "(JFFF)V", (void*)Gainmap_setGainmapMax},
|
||||
{"nGetGainmapMax", "(J[F)V", (void*)Gainmap_getGainmapMax},
|
||||
{"nSetHdrRatioMax", "(JF)V", (void*)Gainmap_setHdrRatioMax},
|
||||
{"nGetHdrRatioMax", "(J)F", (void*)Gainmap_getHdrRatioMax},
|
||||
{"nSetHdrRatioMin", "(JF)V", (void*)Gainmap_setHdrRatioMin},
|
||||
{"nGetHdrRatioMin", "(J)F", (void*)Gainmap_getHdrRatioMin},
|
||||
{"nCreateEmpty", "()J", (void*)Gainmap_createEmpty},
|
||||
{"nSetBitmap", "(JLandroid/graphics/Bitmap;)V", (void*)Gainmap_setBitmap},
|
||||
{"nSetRatioMin", "(JFFF)V", (void*)Gainmap_setRatioMin},
|
||||
{"nGetRatioMin", "(J[F)V", (void*)Gainmap_getRatioMin},
|
||||
{"nSetRatioMax", "(JFFF)V", (void*)Gainmap_setRatioMax},
|
||||
{"nGetRatioMax", "(J[F)V", (void*)Gainmap_getRatioMax},
|
||||
{"nSetGamma", "(JFFF)V", (void*)Gainmap_setGamma},
|
||||
{"nGetGamma", "(J[F)V", (void*)Gainmap_getGamma},
|
||||
{"nSetEpsilonSdr", "(JFFF)V", (void*)Gainmap_setEpsilonSdr},
|
||||
{"nGetEpsilonSdr", "(J[F)V", (void*)Gainmap_getEpsilonSdr},
|
||||
{"nSetEpsilonHdr", "(JFFF)V", (void*)Gainmap_setEpsilonHdr},
|
||||
{"nGetEpsilonHdr", "(J[F)V", (void*)Gainmap_getEpsilonHdr},
|
||||
{"nSetDisplayRatioHdr", "(JF)V", (void*)Gainmap_setDisplayRatioHdr},
|
||||
{"nGetDisplayRatioHdr", "(J)F", (void*)Gainmap_getDisplayRatioHdr},
|
||||
{"nSetDisplayRatioSdr", "(JF)V", (void*)Gainmap_setDisplayRatioSdr},
|
||||
{"nGetDisplayRatioSdr", "(J)F", (void*)Gainmap_getDisplayRatioSdr},
|
||||
};
|
||||
|
||||
int register_android_graphics_Gainmap(JNIEnv* env) {
|
||||
gGainmap_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Gainmap"));
|
||||
gGainmap_constructorMethodID =
|
||||
GetMethodIDOrDie(env, gGainmap_class, "<init>", "(Landroid/graphics/Bitmap;JIZ)V");
|
||||
GetMethodIDOrDie(env, gGainmap_class, "<init>", "(Landroid/graphics/Bitmap;J)V");
|
||||
return android::RegisterMethodsOrDie(env, "android/graphics/Gainmap", gGainmapMethods,
|
||||
NELEM(gGainmapMethods));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user