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

Commit 843f1bda authored by Dichen Zhang's avatar Dichen Zhang
Browse files

Add stride support to JPEG/R java API

Bug: 299202809
Test: YuvImageTest.java
Change-Id: Ifb1500114c9c212eb145c8538a74b46066fd5db7
parent bfd2380f
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -339,7 +339,8 @@ public class YuvImage {
      return nativeCompressToJpegR(mData, mColorSpace.getDataSpace(),
                                   sdr.getYuvData(), sdr.getColorSpace().getDataSpace(),
                                   mWidth, mHeight, quality, stream,
                                   new byte[WORKING_COMPRESS_STORAGE], exif);
                                   new byte[WORKING_COMPRESS_STORAGE], exif,
                                   mStrides, sdr.getStrides());
  }


@@ -451,5 +452,6 @@ public class YuvImage {

    private static native boolean nativeCompressToJpegR(byte[] hdr, int hdrColorSpaceId,
            byte[] sdr, int sdrColorSpaceId, int width, int height, int quality,
            OutputStream stream, byte[] tempStorage, byte[] exif);
            OutputStream stream, byte[] tempStorage, byte[] exif,
            int[] hdrStrides, int[] sdrStrides);
}
+31 −4
Original line number Diff line number Diff line
@@ -332,7 +332,8 @@ ultrahdr_transfer_function P010Yuv420ToJpegREncoder::findHdrTransferFunction(JNI

bool P010Yuv420ToJpegREncoder::encode(JNIEnv* env,
        SkWStream* stream, void* hdr, int hdrColorSpace, void* sdr, int sdrColorSpace,
        int width, int height, int jpegQuality, ScopedByteArrayRO* jExif) {
        int width, int height, int jpegQuality, ScopedByteArrayRO* jExif,
        ScopedIntArrayRO* jHdrStrides, ScopedIntArrayRO* jSdrStrides) {
    // Check SDR color space. Now we only support SRGB transfer function
    if ((sdrColorSpace & ADataSpace::TRANSFER_MASK) !=  ADataSpace::TRANSFER_SRGB) {
        jclass IllegalArgumentException = env->FindClass("java/lang/IllegalArgumentException");
@@ -340,6 +341,19 @@ bool P010Yuv420ToJpegREncoder::encode(JNIEnv* env,
            "The requested SDR color space is not supported. Transfer function must be SRGB");
        return false;
    }
    // Check HDR and SDR strides length.
    // HDR is YCBCR_P010 color format, and its strides length must be 2 (Y, chroma (Cb, Cr)).
    // SDR is YUV_420_888 color format, and its strides length must be 3 (Y, Cb, Cr).
    if (jHdrStrides->size() != 2) {
        jclass IllegalArgumentException = env->FindClass("java/lang/IllegalArgumentException");
        env->ThrowNew(IllegalArgumentException, "HDR stride length must be 2.");
        return false;
    }
    if (jSdrStrides->size() != 3) {
        jclass IllegalArgumentException = env->FindClass("java/lang/IllegalArgumentException");
        env->ThrowNew(IllegalArgumentException, "SDR stride length must be 3.");
        return false;
    }

    ultrahdr_color_gamut hdrColorGamut = findColorGamut(env, hdrColorSpace);
    ultrahdr_color_gamut sdrColorGamut = findColorGamut(env, sdrColorSpace);
@@ -351,18 +365,26 @@ bool P010Yuv420ToJpegREncoder::encode(JNIEnv* env,
        return false;
    }

    const int* hdrStrides = reinterpret_cast<const int*>(jHdrStrides->get());
    const int* sdrStrides = reinterpret_cast<const int*>(jSdrStrides->get());

    JpegR jpegREncoder;

    jpegr_uncompressed_struct p010;
    p010.data = hdr;
    p010.width = width;
    p010.height = height;
    // Divided by 2 because unit in libultrader is pixel and in YuvImage it is byte.
    p010.luma_stride = (hdrStrides[0] + 1) / 2;
    p010.chroma_stride = (hdrStrides[1] + 1) / 2;
    p010.colorGamut = hdrColorGamut;

    jpegr_uncompressed_struct yuv420;
    yuv420.data = sdr;
    yuv420.width = width;
    yuv420.height = height;
    yuv420.luma_stride = sdrStrides[0];
    yuv420.chroma_stride = sdrStrides[1];
    yuv420.colorGamut = sdrColorGamut;

    jpegr_exif_struct exif;
@@ -420,22 +442,27 @@ static jboolean YuvImage_compressToJpeg(JNIEnv* env, jobject, jbyteArray inYuv,
static jboolean YuvImage_compressToJpegR(JNIEnv* env, jobject, jbyteArray inHdr,
        jint hdrColorSpace, jbyteArray inSdr, jint sdrColorSpace,
        jint width, jint height, jint quality, jobject jstream,
        jbyteArray jstorage, jbyteArray jExif) {
        jbyteArray jstorage, jbyteArray jExif,
        jintArray jHdrStrides, jintArray jSdrStrides) {
    jbyte* hdr = env->GetByteArrayElements(inHdr, NULL);
    jbyte* sdr = env->GetByteArrayElements(inSdr, NULL);
    ScopedByteArrayRO exif(env, jExif);
    ScopedIntArrayRO hdrStrides(env, jHdrStrides);
    ScopedIntArrayRO sdrStrides(env, jSdrStrides);

    SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
    P010Yuv420ToJpegREncoder encoder;

    jboolean result = JNI_FALSE;
    if (encoder.encode(env, strm, hdr, hdrColorSpace, sdr, sdrColorSpace,
                       width, height, quality, &exif)) {
                       width, height, quality, &exif,
                       &hdrStrides, &sdrStrides)) {
        result = JNI_TRUE;
    }

    env->ReleaseByteArrayElements(inHdr, hdr, 0);
    env->ReleaseByteArrayElements(inSdr, sdr, 0);

    delete strm;
    return result;
}
@@ -444,7 +471,7 @@ static jboolean YuvImage_compressToJpegR(JNIEnv* env, jobject, jbyteArray inHdr,
static const JNINativeMethod gYuvImageMethods[] = {
    {   "nativeCompressToJpeg",  "([BIII[I[IILjava/io/OutputStream;[B)Z",
        (void*)YuvImage_compressToJpeg },
    {   "nativeCompressToJpegR",  "([BI[BIIIILjava/io/OutputStream;[B[B)Z",
    {   "nativeCompressToJpegR",  "([BI[BIIIILjava/io/OutputStream;[B[B[I[I)Z",
        (void*)YuvImage_compressToJpegR }
};

+4 −1
Original line number Diff line number Diff line
@@ -92,11 +92,14 @@ public:
     *  @param height Height of the Yuv data in terms of pixels.
     *  @param jpegQuality Picture quality in [0, 100].
     *  @param exif Buffer holds EXIF package.
     *  @param hdrStrides The number of row bytes in each image plane of the HDR input.
     *  @param sdrStrides The number of row bytes in each image plane of the SDR input.
     *  @return true if successfully compressed the stream.
     */
    bool encode(JNIEnv* env,
            SkWStream* stream, void* hdr, int hdrColorSpace, void* sdr, int sdrColorSpace,
            int width, int height, int jpegQuality, ScopedByteArrayRO* exif);
            int width, int height, int jpegQuality, ScopedByteArrayRO* exif,
            ScopedIntArrayRO* hdrStrides, ScopedIntArrayRO* sdrStrides);

    /** Map data space (defined in DataSpace.java and data_space.h) to the color gamut
     *  used in JPEG/R