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


    SkBitmap bm;
    SkBitmap bm;
@@ -507,18 +508,26 @@ static jstring ImageDecoder_nGetMimeType(JNIEnv* env, jobject /*clazz*/, jlong n
    return encodedFormatToString(env, decoder->mCodec->getEncodedFormat());
    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[] = {
static const JNINativeMethod gImageDecoderMethods[] = {
    { "nCreate",        "(JLandroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;",    (void*) ImageDecoder_nCreateAsset },
    { "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",        "(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",        "([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/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 },
    { "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 },
                                                                 (void*) ImageDecoder_nDecodeBitmap },
    { "nGetSampledSize","(JI)Landroid/util/Size;",               (void*) ImageDecoder_nGetSampledSize },
    { "nGetSampledSize","(JI)Landroid/util/Size;",               (void*) ImageDecoder_nGetSampledSize },
    { "nGetPadding",    "(JLandroid/graphics/Rect;)V",           (void*) ImageDecoder_nGetPadding },
    { "nGetPadding",    "(JLandroid/graphics/Rect;)V",           (void*) ImageDecoder_nGetPadding },
    { "nClose",         "(J)V",                                  (void*) ImageDecoder_nClose},
    { "nClose",         "(J)V",                                  (void*) ImageDecoder_nClose},
    { "nGetMimeType",   "(J)Ljava/lang/String;",                 (void*) ImageDecoder_nGetMimeType },
    { "nGetMimeType",   "(J)Ljava/lang/String;",                 (void*) ImageDecoder_nGetMimeType },
    { "nGetColorSpace", "(J)Landroid/graphics/ColorSpace;",      (void*) ImageDecoder_nGetColorSpace },
};
};


int register_android_graphics_ImageDecoder(JNIEnv* env) {
int register_android_graphics_ImageDecoder(JNIEnv* env) {
+79 −16
Original line number Original line Diff line number Diff line
@@ -432,6 +432,18 @@ public final class ImageDecoder implements AutoCloseable {
        public boolean isAnimated() {
        public boolean isAnimated() {
            return mDecoder.mAnimated;
            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
    /** @removed
@@ -589,6 +601,7 @@ public final class ImageDecoder implements AutoCloseable {
    private boolean    mMutable = false;
    private boolean    mMutable = false;
    private boolean    mConserveMemory = false;
    private boolean    mConserveMemory = false;
    private boolean    mDecodeAsAlphaMask = false;
    private boolean    mDecodeAsAlphaMask = false;
    private ColorSpace mDesiredColorSpace = null;
    private Rect       mCropRect;
    private Rect       mCropRect;
    private Rect       mOutPaddingRect;
    private Rect       mOutPaddingRect;
    private Source     mSource;
    private Source     mSource;
@@ -806,7 +819,8 @@ public final class ImageDecoder implements AutoCloseable {
     *  image, which can be retrieved from the {@link ImageInfo} in
     *  image, which can be retrieved from the {@link ImageInfo} in
     *  {@link OnHeaderDecodedListener#onHeaderDecoded}.</p>
     *  {@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 width must be greater than 0.
     *  @param height must be greater than 0.
     *  @param height must be greater than 0.
@@ -824,11 +838,11 @@ public final class ImageDecoder implements AutoCloseable {
    }
    }


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


    private int getTargetDimension(int original, int sampleSize, int computed) {
    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.
     *  @param sampleSize Sampling rate of the encoded image.
     *  @return this object for chaining.
     *  @return this object for chaining.
     */
     */
    public ImageDecoder setSampleSize(int sampleSize) {
    public ImageDecoder setTargetSampleSize(int sampleSize) {
        Size size = this.getSampledSize(sampleSize);
        Size size = this.getSampledSize(sampleSize);
        int targetWidth = getTargetDimension(mWidth, sampleSize, size.getWidth());
        int targetWidth = getTargetDimension(mWidth, sampleSize, size.getWidth());
        int targetHeight = getTargetDimension(mHeight, sampleSize, size.getHeight());
        int targetHeight = getTargetDimension(mHeight, sampleSize, size.getHeight());
@@ -1179,6 +1193,37 @@ public final class ImageDecoder implements AutoCloseable {
        return this.getDecodeAsAlphaMask();
        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
    @Override
    public void close() {
    public void close() {
        mCloseGuard.close();
        mCloseGuard.close();
@@ -1217,6 +1262,17 @@ public final class ImageDecoder implements AutoCloseable {
        if (mPostProcessor != null && mRequireUnpremultiplied) {
        if (mPostProcessor != null && mRequireUnpremultiplied) {
            throw new IllegalStateException("Cannot draw to unpremultiplied pixels!");
            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) {
    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,
        return nDecodeBitmap(mNativePtr, this, mPostProcessor != null,
                mDesiredWidth, mDesiredHeight, mCropRect,
                mDesiredWidth, mDesiredHeight, mCropRect,
                mMutable, mAllocator, mRequireUnpremultiplied,
                mMutable, mAllocator, mRequireUnpremultiplied,
                mConserveMemory, mDecodeAsAlphaMask);
                mConserveMemory, mDecodeAsAlphaMask, mDesiredColorSpace);
    }
    }


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


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

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