Add stride support to JPEG/R java API
Bug: 299202809
Test: YuvImageTest.java
Change-Id: Ifb1500114c9c212eb145c8538a74b46066fd5db7
diff --git a/libs/hwui/jni/YuvToJpegEncoder.cpp b/libs/hwui/jni/YuvToJpegEncoder.cpp
index 8c5cc30..c55066a 100644
--- a/libs/hwui/jni/YuvToJpegEncoder.cpp
+++ b/libs/hwui/jni/YuvToJpegEncoder.cpp
@@ -332,7 +332,8 @@
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 @@
"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 @@
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_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 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 }
};