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

Commit bf1fe9ae authored by Leon Scroggins's avatar Leon Scroggins Committed by Android (Google) Code Review
Browse files

Merge "Add in/out ColorSpace to ImageDecoder" into pi-dev

parents 275ea423 1a69f459
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -13658,7 +13658,8 @@ package android.graphics {
    method public android.graphics.ImageDecoder setOnPartialImageListener(android.graphics.ImageDecoder.OnPartialImageListener);
    method public android.graphics.ImageDecoder setPostProcessor(android.graphics.PostProcessor);
    method public android.graphics.ImageDecoder setRequireUnpremultiplied(boolean);
    method public android.graphics.ImageDecoder setSampleSize(int);
    method public android.graphics.ImageDecoder setTargetColorSpace(android.graphics.ColorSpace);
    method public android.graphics.ImageDecoder setTargetSampleSize(int);
    method public android.graphics.ImageDecoder setTargetSize(int, int);
    field public static final int ALLOCATOR_DEFAULT = 0; // 0x0
    field public static final int ALLOCATOR_HARDWARE = 3; // 0x3
@@ -13675,6 +13676,7 @@ package android.graphics {
  }
  public static class ImageDecoder.ImageInfo {
    method public android.graphics.ColorSpace getColorSpace();
    method public java.lang.String getMimeType();
    method public android.util.Size getSize();
    method public boolean isAnimated();
+12 −3
Original line number Diff line number Diff line
@@ -210,7 +210,7 @@ static jobject ImageDecoder_nDecodeBitmap(JNIEnv* env, jobject /*clazz*/, jlong
                                          jint desiredWidth, jint desiredHeight, jobject jsubset,
                                          jboolean requireMutable, jint allocator,
                                          jboolean requireUnpremul, jboolean preferRamOverQuality,
                                          jboolean asAlphaMask) {
                                          jboolean asAlphaMask, jobject jcolorSpace) {
    auto* decoder = reinterpret_cast<ImageDecoder*>(nativePtr);
    SkAndroidCodec* codec = decoder->mCodec.get();
    const SkISize desiredSize = SkISize::Make(desiredWidth, desiredHeight);
@@ -264,7 +264,8 @@ static jobject ImageDecoder_nDecodeBitmap(JNIEnv* env, jobject /*clazz*/, jlong
        // This is currently the only way to know that we should decode to F16.
        colorType = codec->computeOutputColorType(colorType);
    }
    sk_sp<SkColorSpace> colorSpace = codec->computeOutputColorSpace(colorType);
    sk_sp<SkColorSpace> colorSpace = GraphicsJNI::getNativeColorSpace(env, jcolorSpace);
    colorSpace = codec->computeOutputColorSpace(colorType, colorSpace);
    decodeInfo = decodeInfo.makeColorType(colorType).makeColorSpace(colorSpace);

    SkBitmap bm;
@@ -507,18 +508,26 @@ static jstring ImageDecoder_nGetMimeType(JNIEnv* env, jobject /*clazz*/, jlong n
    return encodedFormatToString(env, decoder->mCodec->getEncodedFormat());
}

static jobject ImageDecoder_nGetColorSpace(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
    auto* codec = reinterpret_cast<ImageDecoder*>(nativePtr)->mCodec.get();
    auto colorType = codec->computeOutputColorType(codec->getInfo().colorType());
    sk_sp<SkColorSpace> colorSpace = codec->computeOutputColorSpace(colorType);
    return GraphicsJNI::getColorSpace(env, colorSpace, colorType);
}

static const JNINativeMethod gImageDecoderMethods[] = {
    { "nCreate",        "(JLandroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;",    (void*) ImageDecoder_nCreateAsset },
    { "nCreate",        "(Ljava/nio/ByteBuffer;IILandroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateByteBuffer },
    { "nCreate",        "([BIILandroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateByteArray },
    { "nCreate",        "(Ljava/io/InputStream;[BLandroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateInputStream },
    { "nCreate",        "(Ljava/io/FileDescriptor;Landroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateFd },
    { "nDecodeBitmap",  "(JLandroid/graphics/ImageDecoder;ZIILandroid/graphics/Rect;ZIZZZ)Landroid/graphics/Bitmap;",
    { "nDecodeBitmap",  "(JLandroid/graphics/ImageDecoder;ZIILandroid/graphics/Rect;ZIZZZLandroid/graphics/ColorSpace;)Landroid/graphics/Bitmap;",
                                                                 (void*) ImageDecoder_nDecodeBitmap },
    { "nGetSampledSize","(JI)Landroid/util/Size;",               (void*) ImageDecoder_nGetSampledSize },
    { "nGetPadding",    "(JLandroid/graphics/Rect;)V",           (void*) ImageDecoder_nGetPadding },
    { "nClose",         "(J)V",                                  (void*) ImageDecoder_nClose},
    { "nGetMimeType",   "(J)Ljava/lang/String;",                 (void*) ImageDecoder_nGetMimeType },
    { "nGetColorSpace", "(J)Landroid/graphics/ColorSpace;",      (void*) ImageDecoder_nGetColorSpace },
};

int register_android_graphics_ImageDecoder(JNIEnv* env) {
+79 −16
Original line number Diff line number Diff line
@@ -432,6 +432,18 @@ public final class ImageDecoder implements AutoCloseable {
        public boolean isAnimated() {
            return mDecoder.mAnimated;
        }

        /**
         * If known, the color space the decoded bitmap will have. Note that the
         * output color space is not guaranteed to be the color space the bitmap
         * is encoded with. If not known (when the config is
         * {@link Bitmap.Config#ALPHA_8} for instance), or there is an error,
         * it is set to null.
         */
        @Nullable
        public ColorSpace getColorSpace() {
            return mDecoder.getColorSpace();
        }
    };

    /** @removed
@@ -589,6 +601,7 @@ public final class ImageDecoder implements AutoCloseable {
    private boolean    mMutable = false;
    private boolean    mConserveMemory = false;
    private boolean    mDecodeAsAlphaMask = false;
    private ColorSpace mDesiredColorSpace = null;
    private Rect       mCropRect;
    private Rect       mOutPaddingRect;
    private Source     mSource;
@@ -806,7 +819,8 @@ public final class ImageDecoder implements AutoCloseable {
     *  image, which can be retrieved from the {@link ImageInfo} in
     *  {@link OnHeaderDecodedListener#onHeaderDecoded}.</p>
     *
     *  <p>Only the last call to this or {@link #setSampleSize} is respected.</p>
     *  <p>Only the last call to this or {@link #setTargetSampleSize} is
     *  respected.</p>
     *
     *  @param width must be greater than 0.
     *  @param height must be greater than 0.
@@ -824,11 +838,11 @@ public final class ImageDecoder implements AutoCloseable {
    }

    /** @removed
     * @deprecated Renamed to {@link #setSampleSize}.
     * @deprecated Renamed to {@link #setTargetSampleSize}.
     */
    @java.lang.Deprecated
    public ImageDecoder setResize(int sampleSize) {
        return this.setSampleSize(sampleSize);
        return this.setTargetSampleSize(sampleSize);
    }

    private int getTargetDimension(int original, int sampleSize, int computed) {
@@ -877,7 +891,7 @@ public final class ImageDecoder implements AutoCloseable {
     *  @param sampleSize Sampling rate of the encoded image.
     *  @return this object for chaining.
     */
    public ImageDecoder setSampleSize(int sampleSize) {
    public ImageDecoder setTargetSampleSize(int sampleSize) {
        Size size = this.getSampledSize(sampleSize);
        int targetWidth = getTargetDimension(mWidth, sampleSize, size.getWidth());
        int targetHeight = getTargetDimension(mHeight, sampleSize, size.getHeight());
@@ -1179,6 +1193,37 @@ public final class ImageDecoder implements AutoCloseable {
        return this.getDecodeAsAlphaMask();
    }

    /**
     * Specify the desired {@link ColorSpace} for the output.
     *
     * <p>If non-null, the decoder will try to decode into this
     * color space. If it is null, which is the default, or the request cannot
     * be met, the decoder will pick either the color space embedded in the
     * image or the color space best suited for the requested image
     * configuration (for instance {@link ColorSpace.Named#SRGB sRGB} for
     * the {@link Bitmap.Config#ARGB_8888} configuration).</p>
     *
     * <p>{@link Bitmap.Config#RGBA_F16} always uses the
     * {@link ColorSpace.Named#LINEAR_EXTENDED_SRGB scRGB} color space).
     * Bitmaps in other configurations without an embedded color space are
     * assumed to be in the {@link ColorSpace.Named#SRGB sRGB} color space.</p>
     *
     * <p class="note">Only {@link ColorSpace.Model#RGB} color spaces are
     * currently supported. An <code>IllegalArgumentException</code> will
     * be thrown by the decode methods when setting a non-RGB color space
     * such as {@link ColorSpace.Named#CIE_LAB Lab}.</p>
     *
     * <p class="note">The specified color space's transfer function must be
     * an {@link ColorSpace.Rgb.TransferParameters ICC parametric curve}. An
     * <code>IllegalArgumentException</code> will be thrown by the decode methods
     * if calling {@link ColorSpace.Rgb#getTransferParameters()} on the
     * specified color space returns null.</p>
     */
    public ImageDecoder setTargetColorSpace(ColorSpace colorSpace) {
        mDesiredColorSpace = colorSpace;
        return this;
    }

    @Override
    public void close() {
        mCloseGuard.close();
@@ -1217,6 +1262,17 @@ public final class ImageDecoder implements AutoCloseable {
        if (mPostProcessor != null && mRequireUnpremultiplied) {
            throw new IllegalStateException("Cannot draw to unpremultiplied pixels!");
        }

        if (mDesiredColorSpace != null) {
            if (!(mDesiredColorSpace instanceof ColorSpace.Rgb)) {
                throw new IllegalArgumentException("The target color space must use the "
                            + "RGB color model - provided: " + mDesiredColorSpace);
            }
            if (((ColorSpace.Rgb) mDesiredColorSpace).getTransferParameters() == null) {
                throw new IllegalArgumentException("The target color space must use an "
                            + "ICC parametric transfer function - provided: " + mDesiredColorSpace);
            }
        }
    }

    private static void checkSubset(int width, int height, Rect r) {
@@ -1235,7 +1291,7 @@ public final class ImageDecoder implements AutoCloseable {
        return nDecodeBitmap(mNativePtr, this, mPostProcessor != null,
                mDesiredWidth, mDesiredHeight, mCropRect,
                mMutable, mAllocator, mRequireUnpremultiplied,
                mConserveMemory, mDecodeAsAlphaMask);
                mConserveMemory, mDecodeAsAlphaMask, mDesiredColorSpace);
    }

    private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener,
@@ -1425,6 +1481,11 @@ public final class ImageDecoder implements AutoCloseable {
        return nGetMimeType(mNativePtr);
    }

    @Nullable
    private ColorSpace getColorSpace() {
        return nGetColorSpace(mNativePtr);
    }

    /**
     *  See {@link #decodeBitmap(Source, OnHeaderDecodedListener)}.
     */
@@ -1474,11 +1535,13 @@ public final class ImageDecoder implements AutoCloseable {
            int width, int height,
            @Nullable Rect cropRect, boolean mutable,
            int allocator, boolean requireUnpremul,
            boolean conserveMemory, boolean decodeAsAlphaMask)
            boolean conserveMemory, boolean decodeAsAlphaMask,
            @Nullable ColorSpace desiredColorSpace)
        throws IOException;
    private static native Size nGetSampledSize(long nativePtr,
                                               int sampleSize);
    private static native void nGetPadding(long nativePtr, @NonNull Rect outRect);
    private static native void nClose(long nativePtr);
    private static native String nGetMimeType(long nativePtr);
    private static native ColorSpace nGetColorSpace(long nativePtr);
}