xref: /aosp_15_r20/external/libultrahdr/java/jni/ultrahdr-jni.cpp (revision 89a0ef05262152531a00a15832a2d3b1e3990773)
1*89a0ef05SAndroid Build Coastguard Worker /*
2*89a0ef05SAndroid Build Coastguard Worker  * Copyright 2024 The Android Open Source Project
3*89a0ef05SAndroid Build Coastguard Worker  *
4*89a0ef05SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*89a0ef05SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*89a0ef05SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*89a0ef05SAndroid Build Coastguard Worker  *
8*89a0ef05SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*89a0ef05SAndroid Build Coastguard Worker  *
10*89a0ef05SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*89a0ef05SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*89a0ef05SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*89a0ef05SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*89a0ef05SAndroid Build Coastguard Worker  * limitations under the License.
15*89a0ef05SAndroid Build Coastguard Worker  */
16*89a0ef05SAndroid Build Coastguard Worker 
17*89a0ef05SAndroid Build Coastguard Worker #include <cstring>
18*89a0ef05SAndroid Build Coastguard Worker #include <string>
19*89a0ef05SAndroid Build Coastguard Worker 
20*89a0ef05SAndroid Build Coastguard Worker #include "com_google_media_codecs_ultrahdr_UltraHDRCommon.h"
21*89a0ef05SAndroid Build Coastguard Worker #include "com_google_media_codecs_ultrahdr_UltraHDRDecoder.h"
22*89a0ef05SAndroid Build Coastguard Worker #include "com_google_media_codecs_ultrahdr_UltraHDREncoder.h"
23*89a0ef05SAndroid Build Coastguard Worker #include "ultrahdr_api.h"
24*89a0ef05SAndroid Build Coastguard Worker 
25*89a0ef05SAndroid Build Coastguard Worker static_assert(sizeof(void *) <= sizeof(jlong),
26*89a0ef05SAndroid Build Coastguard Worker               "unsupported architecture, size of pointer address exceeds jlong storage");
27*89a0ef05SAndroid Build Coastguard Worker 
28*89a0ef05SAndroid Build Coastguard Worker #define RET_IF_TRUE(cond, exception_class, msg)      \
29*89a0ef05SAndroid Build Coastguard Worker   {                                                  \
30*89a0ef05SAndroid Build Coastguard Worker     if ((cond) || env->ExceptionCheck()) {           \
31*89a0ef05SAndroid Build Coastguard Worker       env->ExceptionClear();                         \
32*89a0ef05SAndroid Build Coastguard Worker       auto _clazz = env->FindClass(exception_class); \
33*89a0ef05SAndroid Build Coastguard Worker       if (!_clazz || env->ExceptionCheck()) {        \
34*89a0ef05SAndroid Build Coastguard Worker         return;                                      \
35*89a0ef05SAndroid Build Coastguard Worker       }                                              \
36*89a0ef05SAndroid Build Coastguard Worker       env->ThrowNew(_clazz, msg);                    \
37*89a0ef05SAndroid Build Coastguard Worker       return;                                        \
38*89a0ef05SAndroid Build Coastguard Worker     }                                                \
39*89a0ef05SAndroid Build Coastguard Worker   }
40*89a0ef05SAndroid Build Coastguard Worker 
41*89a0ef05SAndroid Build Coastguard Worker #define GET_HANDLE()                                                                         \
42*89a0ef05SAndroid Build Coastguard Worker   jclass clazz = env->GetObjectClass(thiz);                                                  \
43*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(clazz == nullptr, "java/io/IOException", "GetObjectClass returned with error") \
44*89a0ef05SAndroid Build Coastguard Worker   jfieldID fid = env->GetFieldID(clazz, "handle", "J");                                      \
45*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(fid == nullptr, "java/io/IOException",                                         \
46*89a0ef05SAndroid Build Coastguard Worker               "GetFieldID for field 'handle' returned with error")                           \
47*89a0ef05SAndroid Build Coastguard Worker   jlong handle = env->GetLongField(thiz, fid);
48*89a0ef05SAndroid Build Coastguard Worker 
49*89a0ef05SAndroid Build Coastguard Worker #define RET_VAL_IF_TRUE(cond, exception_class, msg, val) \
50*89a0ef05SAndroid Build Coastguard Worker   {                                                      \
51*89a0ef05SAndroid Build Coastguard Worker     if ((cond) || env->ExceptionCheck()) {               \
52*89a0ef05SAndroid Build Coastguard Worker       env->ExceptionClear();                             \
53*89a0ef05SAndroid Build Coastguard Worker       auto _clazz = env->FindClass(exception_class);     \
54*89a0ef05SAndroid Build Coastguard Worker       if (!_clazz || env->ExceptionCheck()) {            \
55*89a0ef05SAndroid Build Coastguard Worker         return (val);                                    \
56*89a0ef05SAndroid Build Coastguard Worker       }                                                  \
57*89a0ef05SAndroid Build Coastguard Worker       env->ThrowNew(_clazz, msg);                        \
58*89a0ef05SAndroid Build Coastguard Worker       return (val);                                      \
59*89a0ef05SAndroid Build Coastguard Worker     }                                                    \
60*89a0ef05SAndroid Build Coastguard Worker   }
61*89a0ef05SAndroid Build Coastguard Worker 
62*89a0ef05SAndroid Build Coastguard Worker #define GET_HANDLE_VAL(val)                                                                      \
63*89a0ef05SAndroid Build Coastguard Worker   jclass clazz = env->GetObjectClass(thiz);                                                      \
64*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(clazz == nullptr, "java/io/IOException", "GetObjectClass returned with error", \
65*89a0ef05SAndroid Build Coastguard Worker                   (val))                                                                         \
66*89a0ef05SAndroid Build Coastguard Worker   jfieldID fid = env->GetFieldID(clazz, "handle", "J");                                          \
67*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(fid == nullptr, "java/io/IOException",                                         \
68*89a0ef05SAndroid Build Coastguard Worker                   "GetFieldID for field 'handle' returned with error", (val))                    \
69*89a0ef05SAndroid Build Coastguard Worker   jlong handle = env->GetLongField(thiz, fid);
70*89a0ef05SAndroid Build Coastguard Worker 
71*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_init(JNIEnv * env,jobject thiz)72*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_init(JNIEnv *env, jobject thiz) {
73*89a0ef05SAndroid Build Coastguard Worker   jclass clazz = env->GetObjectClass(thiz);
74*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(clazz == nullptr, "java/io/IOException", "GetObjectClass returned with error")
75*89a0ef05SAndroid Build Coastguard Worker   jfieldID fid = env->GetFieldID(clazz, "handle", "J");
76*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(fid == nullptr, "java/io/IOException",
77*89a0ef05SAndroid Build Coastguard Worker               "GetFieldID for field 'handle' returned with error")
78*89a0ef05SAndroid Build Coastguard Worker   uhdr_codec_private_t *handle = uhdr_create_encoder();
79*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == nullptr, "java/lang/OutOfMemoryError",
80*89a0ef05SAndroid Build Coastguard Worker               "Unable to allocate encoder instance")
81*89a0ef05SAndroid Build Coastguard Worker   env->SetLongField(thiz, fid, (jlong)handle);
82*89a0ef05SAndroid Build Coastguard Worker }
83*89a0ef05SAndroid Build Coastguard Worker 
84*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_destroy(JNIEnv * env,jobject thiz)85*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_destroy(JNIEnv *env, jobject thiz) {
86*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
87*89a0ef05SAndroid Build Coastguard Worker   if (!handle) {
88*89a0ef05SAndroid Build Coastguard Worker     uhdr_release_encoder((uhdr_codec_private_t *)handle);
89*89a0ef05SAndroid Build Coastguard Worker     env->SetLongField(thiz, fid, (jlong)0);
90*89a0ef05SAndroid Build Coastguard Worker   }
91*89a0ef05SAndroid Build Coastguard Worker }
92*89a0ef05SAndroid Build Coastguard Worker 
93*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setRawImageNative___3IIIIIIIII(JNIEnv * env,jobject thiz,jintArray rgb_buff,jint width,jint height,jint rgb_stride,jint color_gamut,jint color_transfer,jint color_range,jint color_format,jint intent)94*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setRawImageNative___3IIIIIIIII(
95*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jintArray rgb_buff, jint width, jint height, jint rgb_stride,
96*89a0ef05SAndroid Build Coastguard Worker     jint color_gamut, jint color_transfer, jint color_range, jint color_format, jint intent) {
97*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
98*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
99*89a0ef05SAndroid Build Coastguard Worker   jsize length = env->GetArrayLength(rgb_buff);
100*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(length < height * rgb_stride, "java/io/IOException",
101*89a0ef05SAndroid Build Coastguard Worker               "raw image rgba byteArray size is less than required size")
102*89a0ef05SAndroid Build Coastguard Worker   jint *rgbBody = env->GetIntArrayElements(rgb_buff, nullptr);
103*89a0ef05SAndroid Build Coastguard Worker   uhdr_raw_image_t img{(uhdr_img_fmt_t)color_format,
104*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_gamut_t)color_gamut,
105*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_transfer_t)color_transfer,
106*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_range_t)color_range,
107*89a0ef05SAndroid Build Coastguard Worker                        (unsigned int)width,
108*89a0ef05SAndroid Build Coastguard Worker                        (unsigned int)height,
109*89a0ef05SAndroid Build Coastguard Worker                        {rgbBody, nullptr, nullptr},
110*89a0ef05SAndroid Build Coastguard Worker                        {(unsigned int)rgb_stride, 0u, 0u}};
111*89a0ef05SAndroid Build Coastguard Worker   auto status =
112*89a0ef05SAndroid Build Coastguard Worker       uhdr_enc_set_raw_image((uhdr_codec_private_t *)handle, &img, (uhdr_img_label_t)intent);
113*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseIntArrayElements(rgb_buff, rgbBody, 0);
114*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
115*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail : "uhdr_enc_set_raw_image() returned with error")
116*89a0ef05SAndroid Build Coastguard Worker }
117*89a0ef05SAndroid Build Coastguard Worker 
118*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setRawImageNative___3JIIIIIIII(JNIEnv * env,jobject thiz,jlongArray rgb_buff,jint width,jint height,jint rgb_stride,jint color_gamut,jint color_transfer,jint color_range,jint color_format,jint intent)119*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setRawImageNative___3JIIIIIIII(
120*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jlongArray rgb_buff, jint width, jint height, jint rgb_stride,
121*89a0ef05SAndroid Build Coastguard Worker     jint color_gamut, jint color_transfer, jint color_range, jint color_format, jint intent) {
122*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
123*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
124*89a0ef05SAndroid Build Coastguard Worker   jsize length = env->GetArrayLength(rgb_buff);
125*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(length < height * rgb_stride, "java/io/IOException",
126*89a0ef05SAndroid Build Coastguard Worker               "raw image rgba byteArray size is less than required size")
127*89a0ef05SAndroid Build Coastguard Worker   jlong *rgbBody = env->GetLongArrayElements(rgb_buff, nullptr);
128*89a0ef05SAndroid Build Coastguard Worker   uhdr_raw_image_t img{(uhdr_img_fmt_t)color_format,
129*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_gamut_t)color_gamut,
130*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_transfer_t)color_transfer,
131*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_range_t)color_range,
132*89a0ef05SAndroid Build Coastguard Worker                        (unsigned int)width,
133*89a0ef05SAndroid Build Coastguard Worker                        (unsigned int)height,
134*89a0ef05SAndroid Build Coastguard Worker                        {rgbBody, nullptr, nullptr},
135*89a0ef05SAndroid Build Coastguard Worker                        {(unsigned int)rgb_stride, 0u, 0u}};
136*89a0ef05SAndroid Build Coastguard Worker   auto status =
137*89a0ef05SAndroid Build Coastguard Worker       uhdr_enc_set_raw_image((uhdr_codec_private_t *)handle, &img, (uhdr_img_label_t)intent);
138*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseLongArrayElements(rgb_buff, rgbBody, 0);
139*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
140*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail : "uhdr_enc_set_raw_image() returned with error")
141*89a0ef05SAndroid Build Coastguard Worker }
142*89a0ef05SAndroid Build Coastguard Worker 
143*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setRawImageNative___3S_3SIIIIIIIII(JNIEnv * env,jobject thiz,jshortArray y_buff,jshortArray uv_buff,jint width,jint height,jint y_stride,jint uv_stride,jint color_gamut,jint color_transfer,jint color_range,jint color_format,jint intent)144*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setRawImageNative___3S_3SIIIIIIIII(
145*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jshortArray y_buff, jshortArray uv_buff, jint width, jint height,
146*89a0ef05SAndroid Build Coastguard Worker     jint y_stride, jint uv_stride, jint color_gamut, jint color_transfer, jint color_range,
147*89a0ef05SAndroid Build Coastguard Worker     jint color_format, jint intent) {
148*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
149*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
150*89a0ef05SAndroid Build Coastguard Worker   jsize length = env->GetArrayLength(y_buff);
151*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(length < height * y_stride, "java/io/IOException",
152*89a0ef05SAndroid Build Coastguard Worker               "raw image luma byteArray size is less than required size")
153*89a0ef05SAndroid Build Coastguard Worker   length = env->GetArrayLength(uv_buff);
154*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(length < height * uv_stride / 2, "java/io/IOException",
155*89a0ef05SAndroid Build Coastguard Worker               "raw image chroma byteArray size is less than required size")
156*89a0ef05SAndroid Build Coastguard Worker   jshort *lumaBody = env->GetShortArrayElements(y_buff, nullptr);
157*89a0ef05SAndroid Build Coastguard Worker   jshort *chromaBody = env->GetShortArrayElements(uv_buff, nullptr);
158*89a0ef05SAndroid Build Coastguard Worker   uhdr_raw_image_t img{(uhdr_img_fmt_t)color_format,
159*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_gamut_t)color_gamut,
160*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_transfer_t)color_transfer,
161*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_range_t)color_range,
162*89a0ef05SAndroid Build Coastguard Worker                        (unsigned int)width,
163*89a0ef05SAndroid Build Coastguard Worker                        (unsigned int)height,
164*89a0ef05SAndroid Build Coastguard Worker                        {lumaBody, chromaBody, nullptr},
165*89a0ef05SAndroid Build Coastguard Worker                        {(unsigned int)y_stride, (unsigned int)uv_stride, 0u}};
166*89a0ef05SAndroid Build Coastguard Worker   auto status =
167*89a0ef05SAndroid Build Coastguard Worker       uhdr_enc_set_raw_image((uhdr_codec_private_t *)handle, &img, (uhdr_img_label_t)intent);
168*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseShortArrayElements(y_buff, lumaBody, 0);
169*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseShortArrayElements(uv_buff, chromaBody, 0);
170*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
171*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail : "uhdr_enc_set_raw_image() returned with error")
172*89a0ef05SAndroid Build Coastguard Worker }
173*89a0ef05SAndroid Build Coastguard Worker 
174*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setRawImageNative___3B_3B_3BIIIIIIIIII(JNIEnv * env,jobject thiz,jbyteArray y_buff,jbyteArray u_buff,jbyteArray v_buff,jint width,jint height,jint y_stride,jint u_stride,jint v_stride,jint color_gamut,jint color_transfer,jint color_range,jint color_format,jint intent)175*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setRawImageNative___3B_3B_3BIIIIIIIIII(
176*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jbyteArray y_buff, jbyteArray u_buff, jbyteArray v_buff, jint width,
177*89a0ef05SAndroid Build Coastguard Worker     jint height, jint y_stride, jint u_stride, jint v_stride, jint color_gamut, jint color_transfer,
178*89a0ef05SAndroid Build Coastguard Worker     jint color_range, jint color_format, jint intent) {
179*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
180*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
181*89a0ef05SAndroid Build Coastguard Worker   jsize length = env->GetArrayLength(y_buff);
182*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(length < height * y_stride, "java/io/IOException",
183*89a0ef05SAndroid Build Coastguard Worker               "raw image luma byteArray size is less than required size")
184*89a0ef05SAndroid Build Coastguard Worker   length = env->GetArrayLength(u_buff);
185*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(length < height * u_stride / 4, "java/io/IOException",
186*89a0ef05SAndroid Build Coastguard Worker               "raw image cb byteArray size is less than required size")
187*89a0ef05SAndroid Build Coastguard Worker   length = env->GetArrayLength(v_buff);
188*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(length < height * v_stride / 4, "java/io/IOException",
189*89a0ef05SAndroid Build Coastguard Worker               "raw image cb byteArray size is less than required size")
190*89a0ef05SAndroid Build Coastguard Worker   jbyte *lumaBody = env->GetByteArrayElements(y_buff, nullptr);
191*89a0ef05SAndroid Build Coastguard Worker   jbyte *cbBody = env->GetByteArrayElements(u_buff, nullptr);
192*89a0ef05SAndroid Build Coastguard Worker   jbyte *crBody = env->GetByteArrayElements(v_buff, nullptr);
193*89a0ef05SAndroid Build Coastguard Worker   uhdr_raw_image_t img{(uhdr_img_fmt_t)color_format,
194*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_gamut_t)color_gamut,
195*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_transfer_t)color_transfer,
196*89a0ef05SAndroid Build Coastguard Worker                        (uhdr_color_range_t)color_range,
197*89a0ef05SAndroid Build Coastguard Worker                        (unsigned int)width,
198*89a0ef05SAndroid Build Coastguard Worker                        (unsigned int)height,
199*89a0ef05SAndroid Build Coastguard Worker                        {lumaBody, cbBody, crBody},
200*89a0ef05SAndroid Build Coastguard Worker                        {(unsigned int)y_stride, (unsigned int)u_stride, (unsigned int)v_stride}};
201*89a0ef05SAndroid Build Coastguard Worker   auto status =
202*89a0ef05SAndroid Build Coastguard Worker       uhdr_enc_set_raw_image((uhdr_codec_private_t *)handle, &img, (uhdr_img_label_t)intent);
203*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(y_buff, lumaBody, 0);
204*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(u_buff, cbBody, 0);
205*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(v_buff, crBody, 0);
206*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
207*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail : "uhdr_enc_set_raw_image() returned with error")
208*89a0ef05SAndroid Build Coastguard Worker }
209*89a0ef05SAndroid Build Coastguard Worker 
210*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setCompressedImageNative(JNIEnv * env,jobject thiz,jbyteArray data,jint size,jint color_gamut,jint color_transfer,jint range,jint intent)211*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setCompressedImageNative(
212*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jbyteArray data, jint size, jint color_gamut, jint color_transfer,
213*89a0ef05SAndroid Build Coastguard Worker     jint range, jint intent) {
214*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
215*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
216*89a0ef05SAndroid Build Coastguard Worker   jsize length = env->GetArrayLength(data);
217*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(length < size, "java/io/IOException",
218*89a0ef05SAndroid Build Coastguard Worker               "compressed image byteArray size is less than configured size")
219*89a0ef05SAndroid Build Coastguard Worker   jbyte *body = env->GetByteArrayElements(data, nullptr);
220*89a0ef05SAndroid Build Coastguard Worker   uhdr_compressed_image_t img{body,
221*89a0ef05SAndroid Build Coastguard Worker                               (unsigned int)size,
222*89a0ef05SAndroid Build Coastguard Worker                               (unsigned int)length,
223*89a0ef05SAndroid Build Coastguard Worker                               (uhdr_color_gamut_t)color_gamut,
224*89a0ef05SAndroid Build Coastguard Worker                               (uhdr_color_transfer_t)color_transfer,
225*89a0ef05SAndroid Build Coastguard Worker                               (uhdr_color_range_t)range};
226*89a0ef05SAndroid Build Coastguard Worker   auto status =
227*89a0ef05SAndroid Build Coastguard Worker       uhdr_enc_set_compressed_image((uhdr_codec_private_t *)handle, &img, (uhdr_img_label_t)intent);
228*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(data, body, 0);
229*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(
230*89a0ef05SAndroid Build Coastguard Worker       status.error_code != UHDR_CODEC_OK, "java/io/IOException",
231*89a0ef05SAndroid Build Coastguard Worker       status.has_detail ? status.detail : "uhdr_enc_set_compressed_image() returned with error")
232*89a0ef05SAndroid Build Coastguard Worker }
233*89a0ef05SAndroid Build Coastguard Worker 
234*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setGainMapImageInfoNative(JNIEnv * env,jobject thiz,jbyteArray data,jint size,jfloat max_content_boost,jfloat min_content_boost,jfloat gainmap_gamma,jfloat offset_sdr,jfloat offset_hdr,jfloat hdr_capacity_min,jfloat hdr_capacity_max)235*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setGainMapImageInfoNative(
236*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jbyteArray data, jint size, jfloat max_content_boost,
237*89a0ef05SAndroid Build Coastguard Worker     jfloat min_content_boost, jfloat gainmap_gamma, jfloat offset_sdr, jfloat offset_hdr,
238*89a0ef05SAndroid Build Coastguard Worker     jfloat hdr_capacity_min, jfloat hdr_capacity_max) {
239*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
240*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
241*89a0ef05SAndroid Build Coastguard Worker   jsize length = env->GetArrayLength(data);
242*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(length < size, "java/io/IOException",
243*89a0ef05SAndroid Build Coastguard Worker               "compressed image byteArray size is less than configured size")
244*89a0ef05SAndroid Build Coastguard Worker   jbyte *body = env->GetByteArrayElements(data, nullptr);
245*89a0ef05SAndroid Build Coastguard Worker   uhdr_compressed_image_t img{body,
246*89a0ef05SAndroid Build Coastguard Worker                               (unsigned int)size,
247*89a0ef05SAndroid Build Coastguard Worker                               (unsigned int)length,
248*89a0ef05SAndroid Build Coastguard Worker                               UHDR_CG_UNSPECIFIED,
249*89a0ef05SAndroid Build Coastguard Worker                               UHDR_CT_UNSPECIFIED,
250*89a0ef05SAndroid Build Coastguard Worker                               UHDR_CR_UNSPECIFIED};
251*89a0ef05SAndroid Build Coastguard Worker   uhdr_gainmap_metadata_t metadata{max_content_boost, min_content_boost, gainmap_gamma,
252*89a0ef05SAndroid Build Coastguard Worker                                    offset_sdr,        offset_hdr,        hdr_capacity_min,
253*89a0ef05SAndroid Build Coastguard Worker                                    hdr_capacity_max};
254*89a0ef05SAndroid Build Coastguard Worker   auto status = uhdr_enc_set_gainmap_image((uhdr_codec_private_t *)handle, &img, &metadata);
255*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(data, body, 0);
256*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(
257*89a0ef05SAndroid Build Coastguard Worker       status.error_code != UHDR_CODEC_OK, "java/io/IOException",
258*89a0ef05SAndroid Build Coastguard Worker       status.has_detail ? status.detail : "uhdr_enc_set_gainmap_image() returned with error")
259*89a0ef05SAndroid Build Coastguard Worker }
260*89a0ef05SAndroid Build Coastguard Worker 
261*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setExifDataNative(JNIEnv * env,jobject thiz,jbyteArray data,jint size)262*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setExifDataNative(JNIEnv *env, jobject thiz,
263*89a0ef05SAndroid Build Coastguard Worker                                                                         jbyteArray data,
264*89a0ef05SAndroid Build Coastguard Worker                                                                         jint size) {
265*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
266*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
267*89a0ef05SAndroid Build Coastguard Worker   jsize length = env->GetArrayLength(data);
268*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(length < size, "java/io/IOException",
269*89a0ef05SAndroid Build Coastguard Worker               "compressed image byteArray size is less than configured size")
270*89a0ef05SAndroid Build Coastguard Worker   jbyte *body = env->GetByteArrayElements(data, nullptr);
271*89a0ef05SAndroid Build Coastguard Worker   uhdr_mem_block_t exif{body, (unsigned int)size, (unsigned int)length};
272*89a0ef05SAndroid Build Coastguard Worker   auto status = uhdr_enc_set_exif_data((uhdr_codec_private_t *)handle, &exif);
273*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(data, body, 0);
274*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
275*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail : "uhdr_enc_set_exif_data() returned with error")
276*89a0ef05SAndroid Build Coastguard Worker }
277*89a0ef05SAndroid Build Coastguard Worker 
278*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setQualityFactorNative(JNIEnv * env,jobject thiz,jint quality_factor,jint intent)279*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setQualityFactorNative(JNIEnv *env,
280*89a0ef05SAndroid Build Coastguard Worker                                                                              jobject thiz,
281*89a0ef05SAndroid Build Coastguard Worker                                                                              jint quality_factor,
282*89a0ef05SAndroid Build Coastguard Worker                                                                              jint intent) {
283*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
284*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
285*89a0ef05SAndroid Build Coastguard Worker   auto status = uhdr_enc_set_quality((uhdr_codec_private_t *)handle, quality_factor,
286*89a0ef05SAndroid Build Coastguard Worker                                      (uhdr_img_label_t)intent);
287*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
288*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail : "uhdr_enc_set_quality() returned with error")
289*89a0ef05SAndroid Build Coastguard Worker }
290*89a0ef05SAndroid Build Coastguard Worker 
291*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setMultiChannelGainMapEncodingNative(JNIEnv * env,jobject thiz,jboolean enable)292*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setMultiChannelGainMapEncodingNative(
293*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jboolean enable) {
294*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
295*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
296*89a0ef05SAndroid Build Coastguard Worker   auto status =
297*89a0ef05SAndroid Build Coastguard Worker       uhdr_enc_set_using_multi_channel_gainmap((uhdr_codec_private_t *)handle, enable ? 1 : 0);
298*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
299*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail
300*89a0ef05SAndroid Build Coastguard Worker                                 : "uhdr_enc_set_using_multi_channel_gainmap() returned with error")
301*89a0ef05SAndroid Build Coastguard Worker }
302*89a0ef05SAndroid Build Coastguard Worker 
303*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setGainMapScaleFactorNative(JNIEnv * env,jobject thiz,jint scale_factor)304*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setGainMapScaleFactorNative(
305*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jint scale_factor) {
306*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
307*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
308*89a0ef05SAndroid Build Coastguard Worker   auto status = uhdr_enc_set_gainmap_scale_factor((uhdr_codec_private_t *)handle, scale_factor);
309*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(
310*89a0ef05SAndroid Build Coastguard Worker       status.error_code != UHDR_CODEC_OK, "java/io/IOException",
311*89a0ef05SAndroid Build Coastguard Worker       status.has_detail ? status.detail : "uhdr_enc_set_gainmap_scale_factor() returned with error")
312*89a0ef05SAndroid Build Coastguard Worker }
313*89a0ef05SAndroid Build Coastguard Worker 
314*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setGainMapGammaNative(JNIEnv * env,jobject thiz,jfloat gamma)315*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setGainMapGammaNative(JNIEnv *env,
316*89a0ef05SAndroid Build Coastguard Worker                                                                             jobject thiz,
317*89a0ef05SAndroid Build Coastguard Worker                                                                             jfloat gamma) {
318*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
319*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
320*89a0ef05SAndroid Build Coastguard Worker   auto status = uhdr_enc_set_gainmap_gamma((uhdr_codec_private_t *)handle, gamma);
321*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(
322*89a0ef05SAndroid Build Coastguard Worker       status.error_code != UHDR_CODEC_OK, "java/io/IOException",
323*89a0ef05SAndroid Build Coastguard Worker       status.has_detail ? status.detail : "uhdr_enc_set_gainmap_gamma() returned with error")
324*89a0ef05SAndroid Build Coastguard Worker }
325*89a0ef05SAndroid Build Coastguard Worker 
326*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setEncPresetNative(JNIEnv * env,jobject thiz,jint preset)327*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setEncPresetNative(JNIEnv *env, jobject thiz,
328*89a0ef05SAndroid Build Coastguard Worker                                                                          jint preset) {
329*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
330*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
331*89a0ef05SAndroid Build Coastguard Worker   auto status = uhdr_enc_set_preset((uhdr_codec_private_t *)handle, (uhdr_enc_preset_t)preset);
332*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
333*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail : "uhdr_enc_set_preset() returned with error")
334*89a0ef05SAndroid Build Coastguard Worker }
335*89a0ef05SAndroid Build Coastguard Worker 
336*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setOutputFormatNative(JNIEnv * env,jobject thiz,jint media_type)337*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setOutputFormatNative(JNIEnv *env,
338*89a0ef05SAndroid Build Coastguard Worker                                                                             jobject thiz,
339*89a0ef05SAndroid Build Coastguard Worker                                                                             jint media_type) {
340*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
341*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
342*89a0ef05SAndroid Build Coastguard Worker   auto status =
343*89a0ef05SAndroid Build Coastguard Worker       uhdr_enc_set_output_format((uhdr_codec_private_t *)handle, (uhdr_codec_t)media_type);
344*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(
345*89a0ef05SAndroid Build Coastguard Worker       status.error_code != UHDR_CODEC_OK, "java/io/IOException",
346*89a0ef05SAndroid Build Coastguard Worker       status.has_detail ? status.detail : "uhdr_enc_set_output_format() returned with error")
347*89a0ef05SAndroid Build Coastguard Worker }
348*89a0ef05SAndroid Build Coastguard Worker 
349*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setMinMaxContentBoostNative(JNIEnv * env,jobject thiz,jfloat min_content_boost,jfloat max_content_boost)350*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setMinMaxContentBoostNative(
351*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jfloat min_content_boost, jfloat max_content_boost) {
352*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
353*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
354*89a0ef05SAndroid Build Coastguard Worker   auto status = uhdr_enc_set_min_max_content_boost((uhdr_codec_private_t *)handle,
355*89a0ef05SAndroid Build Coastguard Worker                                                    min_content_boost, max_content_boost);
356*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
357*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail
358*89a0ef05SAndroid Build Coastguard Worker                                 : "uhdr_enc_set_min_max_content_boost() returned with error")
359*89a0ef05SAndroid Build Coastguard Worker }
360*89a0ef05SAndroid Build Coastguard Worker 
361*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setTargetDisplayPeakBrightnessNative(JNIEnv * env,jobject thiz,jfloat nits)362*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setTargetDisplayPeakBrightnessNative(
363*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jfloat nits) {
364*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
365*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
366*89a0ef05SAndroid Build Coastguard Worker   auto status = uhdr_enc_set_target_display_peak_brightness((uhdr_codec_private_t *)handle, nits);
367*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
368*89a0ef05SAndroid Build Coastguard Worker               status.has_detail
369*89a0ef05SAndroid Build Coastguard Worker                   ? status.detail
370*89a0ef05SAndroid Build Coastguard Worker                   : "uhdr_enc_set_target_display_peak_brightness() returned with error")
371*89a0ef05SAndroid Build Coastguard Worker }
372*89a0ef05SAndroid Build Coastguard Worker 
373*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_encodeNative(JNIEnv * env,jobject thiz)374*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_encodeNative(JNIEnv *env, jobject thiz) {
375*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
376*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
377*89a0ef05SAndroid Build Coastguard Worker   auto status = uhdr_encode((uhdr_codec_private_t *)handle);
378*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
379*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail : "uhdr_encode() returned with error")
380*89a0ef05SAndroid Build Coastguard Worker }
381*89a0ef05SAndroid Build Coastguard Worker 
382*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_getOutputNative(JNIEnv * env,jobject thiz)383*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_getOutputNative(JNIEnv *env, jobject thiz) {
384*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE_VAL(nullptr)
385*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance", nullptr)
386*89a0ef05SAndroid Build Coastguard Worker   auto enc_output = uhdr_get_encoded_stream((uhdr_codec_private_t *)handle);
387*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(enc_output == nullptr, "java/io/IOException",
388*89a0ef05SAndroid Build Coastguard Worker                   "no output returned, may be call to uhdr_encode() was not made or encountered "
389*89a0ef05SAndroid Build Coastguard Worker                   "error during encoding process.",
390*89a0ef05SAndroid Build Coastguard Worker                   nullptr)
391*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(enc_output->data_sz >= INT32_MAX, "java/lang/OutOfMemoryError",
392*89a0ef05SAndroid Build Coastguard Worker                   "encoded output size exceeds integer max", nullptr)
393*89a0ef05SAndroid Build Coastguard Worker   jbyteArray output = env->NewByteArray(enc_output->data_sz);
394*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(output == nullptr, "java/io/IOException", "failed to allocate storage for output",
395*89a0ef05SAndroid Build Coastguard Worker                   nullptr)
396*89a0ef05SAndroid Build Coastguard Worker   env->SetByteArrayRegion(output, 0, enc_output->data_sz, (jbyte *)enc_output->data);
397*89a0ef05SAndroid Build Coastguard Worker   return output;
398*89a0ef05SAndroid Build Coastguard Worker }
399*89a0ef05SAndroid Build Coastguard Worker 
400*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_resetNative(JNIEnv * env,jobject thiz)401*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_resetNative(JNIEnv *env, jobject thiz) {
402*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
403*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
404*89a0ef05SAndroid Build Coastguard Worker   uhdr_reset_encoder((uhdr_codec_private_t *)handle);
405*89a0ef05SAndroid Build Coastguard Worker }
406*89a0ef05SAndroid Build Coastguard Worker 
407*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_isUHDRImageNative(JNIEnv * env,jclass clazz,jbyteArray data,jint size)408*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_isUHDRImageNative(JNIEnv *env, jclass clazz,
409*89a0ef05SAndroid Build Coastguard Worker                                                                         jbyteArray data,
410*89a0ef05SAndroid Build Coastguard Worker                                                                         jint size) {
411*89a0ef05SAndroid Build Coastguard Worker   jsize length = env->GetArrayLength(data);
412*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(length < size, "java/io/IOException",
413*89a0ef05SAndroid Build Coastguard Worker                   "compressed image byteArray size is less than configured size", 0)
414*89a0ef05SAndroid Build Coastguard Worker   jbyte *body = env->GetByteArrayElements(data, nullptr);
415*89a0ef05SAndroid Build Coastguard Worker   auto status = is_uhdr_image(body, size);
416*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(data, body, 0);
417*89a0ef05SAndroid Build Coastguard Worker   return status;
418*89a0ef05SAndroid Build Coastguard Worker }
419*89a0ef05SAndroid Build Coastguard Worker 
420*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_init(JNIEnv * env,jobject thiz)421*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_init(JNIEnv *env, jobject thiz) {
422*89a0ef05SAndroid Build Coastguard Worker   jclass clazz = env->GetObjectClass(thiz);
423*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(clazz == nullptr, "java/io/IOException", "GetObjectClass returned with error")
424*89a0ef05SAndroid Build Coastguard Worker   jfieldID fid = env->GetFieldID(clazz, "handle", "J");
425*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(fid == nullptr, "java/io/IOException",
426*89a0ef05SAndroid Build Coastguard Worker               "GetFieldID for field 'handle' returned with error")
427*89a0ef05SAndroid Build Coastguard Worker   uhdr_codec_private_t *handle = uhdr_create_decoder();
428*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == nullptr, "java/lang/OutOfMemoryError",
429*89a0ef05SAndroid Build Coastguard Worker               "Unable to allocate decoder instance")
430*89a0ef05SAndroid Build Coastguard Worker   env->SetLongField(thiz, fid, (jlong)handle);
431*89a0ef05SAndroid Build Coastguard Worker }
432*89a0ef05SAndroid Build Coastguard Worker 
433*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_destroy(JNIEnv * env,jobject thiz)434*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_destroy(JNIEnv *env, jobject thiz) {
435*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
436*89a0ef05SAndroid Build Coastguard Worker   if (!handle) {
437*89a0ef05SAndroid Build Coastguard Worker     uhdr_release_decoder((uhdr_codec_private *)handle);
438*89a0ef05SAndroid Build Coastguard Worker     env->SetLongField(thiz, fid, (jlong)0);
439*89a0ef05SAndroid Build Coastguard Worker   }
440*89a0ef05SAndroid Build Coastguard Worker }
441*89a0ef05SAndroid Build Coastguard Worker 
442*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setCompressedImageNative(JNIEnv * env,jobject thiz,jbyteArray data,jint size,jint color_gamut,jint color_transfer,jint range)443*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setCompressedImageNative(
444*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jbyteArray data, jint size, jint color_gamut, jint color_transfer,
445*89a0ef05SAndroid Build Coastguard Worker     jint range) {
446*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(size < 0, "java/io/IOException", "invalid compressed image size")
447*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
448*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
449*89a0ef05SAndroid Build Coastguard Worker   jsize length = env->GetArrayLength(data);
450*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(length < size, "java/io/IOException",
451*89a0ef05SAndroid Build Coastguard Worker               "compressed image byteArray size is less than configured size")
452*89a0ef05SAndroid Build Coastguard Worker   jbyte *body = env->GetByteArrayElements(data, nullptr);
453*89a0ef05SAndroid Build Coastguard Worker   uhdr_compressed_image_t img{body,
454*89a0ef05SAndroid Build Coastguard Worker                               (unsigned int)size,
455*89a0ef05SAndroid Build Coastguard Worker                               (unsigned int)length,
456*89a0ef05SAndroid Build Coastguard Worker                               (uhdr_color_gamut_t)color_gamut,
457*89a0ef05SAndroid Build Coastguard Worker                               (uhdr_color_transfer_t)color_transfer,
458*89a0ef05SAndroid Build Coastguard Worker                               (uhdr_color_range_t)range};
459*89a0ef05SAndroid Build Coastguard Worker   uhdr_error_info_t status = uhdr_dec_set_image((uhdr_codec_private_t *)handle, &img);
460*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(data, body, 0);
461*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
462*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail : "uhdr_dec_set_image() returned with error")
463*89a0ef05SAndroid Build Coastguard Worker }
464*89a0ef05SAndroid Build Coastguard Worker 
465*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setOutputFormatNative(JNIEnv * env,jobject thiz,jint fmt)466*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setOutputFormatNative(JNIEnv *env,
467*89a0ef05SAndroid Build Coastguard Worker                                                                             jobject thiz,
468*89a0ef05SAndroid Build Coastguard Worker                                                                             jint fmt) {
469*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
470*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
471*89a0ef05SAndroid Build Coastguard Worker   uhdr_error_info_t status =
472*89a0ef05SAndroid Build Coastguard Worker       uhdr_dec_set_out_img_format((uhdr_codec_private_t *)handle, (uhdr_img_fmt_t)fmt);
473*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(
474*89a0ef05SAndroid Build Coastguard Worker       status.error_code != UHDR_CODEC_OK, "java/io/IOException",
475*89a0ef05SAndroid Build Coastguard Worker       status.has_detail ? status.detail : "uhdr_dec_set_out_img_format() returned with error")
476*89a0ef05SAndroid Build Coastguard Worker }
477*89a0ef05SAndroid Build Coastguard Worker 
478*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setColorTransferNative(JNIEnv * env,jobject thiz,jint ct)479*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setColorTransferNative(JNIEnv *env,
480*89a0ef05SAndroid Build Coastguard Worker                                                                              jobject thiz,
481*89a0ef05SAndroid Build Coastguard Worker                                                                              jint ct) {
482*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
483*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
484*89a0ef05SAndroid Build Coastguard Worker   uhdr_error_info_t status =
485*89a0ef05SAndroid Build Coastguard Worker       uhdr_dec_set_out_color_transfer((uhdr_codec_private_t *)handle, (uhdr_color_transfer_t)ct);
486*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(
487*89a0ef05SAndroid Build Coastguard Worker       status.error_code != UHDR_CODEC_OK, "java/io/IOException",
488*89a0ef05SAndroid Build Coastguard Worker       status.has_detail ? status.detail : "uhdr_dec_set_out_color_transfer() returned with error")
489*89a0ef05SAndroid Build Coastguard Worker }
490*89a0ef05SAndroid Build Coastguard Worker 
491*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setMaxDisplayBoostNative(JNIEnv * env,jobject thiz,jfloat display_boost)492*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setMaxDisplayBoostNative(
493*89a0ef05SAndroid Build Coastguard Worker     JNIEnv *env, jobject thiz, jfloat display_boost) {
494*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
495*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
496*89a0ef05SAndroid Build Coastguard Worker   uhdr_error_info_t status =
497*89a0ef05SAndroid Build Coastguard Worker       uhdr_dec_set_out_max_display_boost((uhdr_codec_private_t *)handle, (float)display_boost);
498*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
499*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail
500*89a0ef05SAndroid Build Coastguard Worker                                 : "uhdr_dec_set_out_max_display_boost() returned with error")
501*89a0ef05SAndroid Build Coastguard Worker }
502*89a0ef05SAndroid Build Coastguard Worker 
503*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_enableGpuAccelerationNative(JNIEnv * env,jobject thiz,jint enable)504*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_enableGpuAccelerationNative(JNIEnv *env,
505*89a0ef05SAndroid Build Coastguard Worker                                                                                   jobject thiz,
506*89a0ef05SAndroid Build Coastguard Worker                                                                                   jint enable) {
507*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
508*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
509*89a0ef05SAndroid Build Coastguard Worker   uhdr_error_info_t status = uhdr_enable_gpu_acceleration((uhdr_codec_private_t *)handle, enable);
510*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(
511*89a0ef05SAndroid Build Coastguard Worker       status.error_code != UHDR_CODEC_OK, "java/io/IOException",
512*89a0ef05SAndroid Build Coastguard Worker       status.has_detail ? status.detail : "uhdr_enable_gpu_acceleration() returned with error")
513*89a0ef05SAndroid Build Coastguard Worker }
514*89a0ef05SAndroid Build Coastguard Worker 
515*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_probeNative(JNIEnv * env,jobject thiz)516*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_probeNative(JNIEnv *env, jobject thiz) {
517*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
518*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
519*89a0ef05SAndroid Build Coastguard Worker   uhdr_error_info_t status = uhdr_dec_probe((uhdr_codec_private_t *)handle);
520*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
521*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail : "uhdr_dec_probe() returned with error")
522*89a0ef05SAndroid Build Coastguard Worker }
523*89a0ef05SAndroid Build Coastguard Worker 
524*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getImageWidthNative(JNIEnv * env,jobject thiz)525*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getImageWidthNative(JNIEnv *env,
526*89a0ef05SAndroid Build Coastguard Worker                                                                           jobject thiz) {
527*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE_VAL(-1)
528*89a0ef05SAndroid Build Coastguard Worker   auto val = uhdr_dec_get_image_width((uhdr_codec_private_t *)handle);
529*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(val == -1, "java/io/IOException",
530*89a0ef05SAndroid Build Coastguard Worker                   "uhdr_dec_probe() is not yet called or it has returned with error", -1)
531*89a0ef05SAndroid Build Coastguard Worker   return val;
532*89a0ef05SAndroid Build Coastguard Worker }
533*89a0ef05SAndroid Build Coastguard Worker 
534*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getImageHeightNative(JNIEnv * env,jobject thiz)535*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getImageHeightNative(JNIEnv *env,
536*89a0ef05SAndroid Build Coastguard Worker                                                                            jobject thiz) {
537*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE_VAL(-1)
538*89a0ef05SAndroid Build Coastguard Worker   auto val = uhdr_dec_get_image_height((uhdr_codec_private_t *)handle);
539*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(val == -1, "java/io/IOException",
540*89a0ef05SAndroid Build Coastguard Worker                   "uhdr_dec_probe() is not yet called or it has returned with error", -1)
541*89a0ef05SAndroid Build Coastguard Worker   return val;
542*89a0ef05SAndroid Build Coastguard Worker }
543*89a0ef05SAndroid Build Coastguard Worker 
544*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapWidthNative(JNIEnv * env,jobject thiz)545*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapWidthNative(JNIEnv *env,
546*89a0ef05SAndroid Build Coastguard Worker                                                                             jobject thiz) {
547*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE_VAL(-1)
548*89a0ef05SAndroid Build Coastguard Worker   auto val = uhdr_dec_get_gainmap_width((uhdr_codec_private_t *)handle);
549*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(val == -1, "java/io/IOException",
550*89a0ef05SAndroid Build Coastguard Worker                   "uhdr_dec_probe() is not yet called or it has returned with error", -1)
551*89a0ef05SAndroid Build Coastguard Worker   return val;
552*89a0ef05SAndroid Build Coastguard Worker }
553*89a0ef05SAndroid Build Coastguard Worker 
554*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapHeightNative(JNIEnv * env,jobject thiz)555*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapHeightNative(JNIEnv *env,
556*89a0ef05SAndroid Build Coastguard Worker                                                                              jobject thiz) {
557*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE_VAL(-1)
558*89a0ef05SAndroid Build Coastguard Worker   auto val = uhdr_dec_get_gainmap_height((uhdr_codec_private_t *)handle);
559*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(val == -1, "java/io/IOException",
560*89a0ef05SAndroid Build Coastguard Worker                   "uhdr_dec_probe() is not yet called or it has returned with error", -1)
561*89a0ef05SAndroid Build Coastguard Worker   return val;
562*89a0ef05SAndroid Build Coastguard Worker }
563*89a0ef05SAndroid Build Coastguard Worker 
564*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getExifNative(JNIEnv * env,jobject thiz)565*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getExifNative(JNIEnv *env, jobject thiz) {
566*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE_VAL(nullptr)
567*89a0ef05SAndroid Build Coastguard Worker   uhdr_mem_block_t *exifData = uhdr_dec_get_exif((uhdr_codec_private_t *)handle);
568*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(exifData == nullptr, "java/io/IOException",
569*89a0ef05SAndroid Build Coastguard Worker                   "uhdr_dec_probe() is not yet called or it has returned with error", nullptr)
570*89a0ef05SAndroid Build Coastguard Worker   jbyteArray data = env->NewByteArray(exifData->data_sz);
571*89a0ef05SAndroid Build Coastguard Worker   jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
572*89a0ef05SAndroid Build Coastguard Worker   std::memcpy(dataptr, exifData->data, exifData->data_sz);
573*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(data, dataptr, 0);
574*89a0ef05SAndroid Build Coastguard Worker   return data;
575*89a0ef05SAndroid Build Coastguard Worker }
576*89a0ef05SAndroid Build Coastguard Worker 
577*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getIccNative(JNIEnv * env,jobject thiz)578*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getIccNative(JNIEnv *env, jobject thiz) {
579*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE_VAL(nullptr)
580*89a0ef05SAndroid Build Coastguard Worker   uhdr_mem_block_t *iccData = uhdr_dec_get_icc((uhdr_codec_private_t *)handle);
581*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(iccData == nullptr, "java/io/IOException",
582*89a0ef05SAndroid Build Coastguard Worker                   "uhdr_dec_probe() is not yet called or it has returned with error", nullptr)
583*89a0ef05SAndroid Build Coastguard Worker   jbyteArray data = env->NewByteArray(iccData->data_sz);
584*89a0ef05SAndroid Build Coastguard Worker   jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
585*89a0ef05SAndroid Build Coastguard Worker   std::memcpy(dataptr, iccData->data, iccData->data_sz);
586*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(data, dataptr, 0);
587*89a0ef05SAndroid Build Coastguard Worker   return data;
588*89a0ef05SAndroid Build Coastguard Worker }
589*89a0ef05SAndroid Build Coastguard Worker 
590*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getBaseImageNative(JNIEnv * env,jobject thiz)591*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getBaseImageNative(JNIEnv *env,
592*89a0ef05SAndroid Build Coastguard Worker                                                                          jobject thiz) {
593*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE_VAL(nullptr)
594*89a0ef05SAndroid Build Coastguard Worker   uhdr_mem_block_t *baseImgData = uhdr_dec_get_base_image((uhdr_codec_private_t *)handle);
595*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(baseImgData == nullptr, "java/io/IOException",
596*89a0ef05SAndroid Build Coastguard Worker                   "uhdr_dec_probe() is not yet called or it has returned with error", nullptr)
597*89a0ef05SAndroid Build Coastguard Worker   jbyteArray data = env->NewByteArray(baseImgData->data_sz);
598*89a0ef05SAndroid Build Coastguard Worker   jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
599*89a0ef05SAndroid Build Coastguard Worker   std::memcpy(dataptr, baseImgData->data, baseImgData->data_sz);
600*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(data, dataptr, 0);
601*89a0ef05SAndroid Build Coastguard Worker   return data;
602*89a0ef05SAndroid Build Coastguard Worker }
603*89a0ef05SAndroid Build Coastguard Worker 
604*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapImageNative(JNIEnv * env,jobject thiz)605*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapImageNative(JNIEnv *env,
606*89a0ef05SAndroid Build Coastguard Worker                                                                             jobject thiz) {
607*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE_VAL(nullptr)
608*89a0ef05SAndroid Build Coastguard Worker   uhdr_mem_block_t *gainmapImgData = uhdr_dec_get_gainmap_image((uhdr_codec_private_t *)handle);
609*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(gainmapImgData == nullptr, "java/io/IOException",
610*89a0ef05SAndroid Build Coastguard Worker                   "uhdr_dec_probe() is not yet called or it has returned with error", nullptr)
611*89a0ef05SAndroid Build Coastguard Worker   jbyteArray data = env->NewByteArray(gainmapImgData->data_sz);
612*89a0ef05SAndroid Build Coastguard Worker   jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
613*89a0ef05SAndroid Build Coastguard Worker   std::memcpy(dataptr, gainmapImgData->data, gainmapImgData->data_sz);
614*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(data, dataptr, 0);
615*89a0ef05SAndroid Build Coastguard Worker   return data;
616*89a0ef05SAndroid Build Coastguard Worker }
617*89a0ef05SAndroid Build Coastguard Worker 
618*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainmapMetadataNative(JNIEnv * env,jobject thiz)619*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainmapMetadataNative(JNIEnv *env,
620*89a0ef05SAndroid Build Coastguard Worker                                                                                jobject thiz) {
621*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
622*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
623*89a0ef05SAndroid Build Coastguard Worker   uhdr_gainmap_metadata_t *gainmap_metadata =
624*89a0ef05SAndroid Build Coastguard Worker       uhdr_dec_get_gainmap_metadata((uhdr_codec_private_t *)handle);
625*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(gainmap_metadata == nullptr, "java/io/IOException",
626*89a0ef05SAndroid Build Coastguard Worker               "uhdr_dec_probe() is not yet called or it has returned with error")
627*89a0ef05SAndroid Build Coastguard Worker #define SET_FLOAT_FIELD(name, val)                                    \
628*89a0ef05SAndroid Build Coastguard Worker   {                                                                   \
629*89a0ef05SAndroid Build Coastguard Worker     jfieldID fID = env->GetFieldID(clazz, name, "F");                 \
630*89a0ef05SAndroid Build Coastguard Worker     RET_IF_TRUE(fID == nullptr, "java/io/IOException",                \
631*89a0ef05SAndroid Build Coastguard Worker                 "GetFieldID for field " #name " returned with error") \
632*89a0ef05SAndroid Build Coastguard Worker     env->SetFloatField(thiz, fID, (jfloat)val);                       \
633*89a0ef05SAndroid Build Coastguard Worker   }
634*89a0ef05SAndroid Build Coastguard Worker   SET_FLOAT_FIELD("maxContentBoost", gainmap_metadata->max_content_boost)
635*89a0ef05SAndroid Build Coastguard Worker   SET_FLOAT_FIELD("minContentBoost", gainmap_metadata->min_content_boost)
636*89a0ef05SAndroid Build Coastguard Worker   SET_FLOAT_FIELD("gamma", gainmap_metadata->gamma)
637*89a0ef05SAndroid Build Coastguard Worker   SET_FLOAT_FIELD("offsetSdr", gainmap_metadata->offset_sdr)
638*89a0ef05SAndroid Build Coastguard Worker   SET_FLOAT_FIELD("offsetHdr", gainmap_metadata->offset_hdr)
639*89a0ef05SAndroid Build Coastguard Worker   SET_FLOAT_FIELD("hdrCapacityMin", gainmap_metadata->hdr_capacity_min)
640*89a0ef05SAndroid Build Coastguard Worker   SET_FLOAT_FIELD("hdrCapacityMax", gainmap_metadata->hdr_capacity_max)
641*89a0ef05SAndroid Build Coastguard Worker }
642*89a0ef05SAndroid Build Coastguard Worker 
643*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_decodeNative(JNIEnv * env,jobject thiz)644*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_decodeNative(JNIEnv *env, jobject thiz) {
645*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
646*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
647*89a0ef05SAndroid Build Coastguard Worker   auto status = uhdr_decode((uhdr_codec_private_t *)handle);
648*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
649*89a0ef05SAndroid Build Coastguard Worker               status.has_detail ? status.detail : "uhdr_decode() returned with error")
650*89a0ef05SAndroid Build Coastguard Worker }
651*89a0ef05SAndroid Build Coastguard Worker 
652*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getDecodedImageNative(JNIEnv * env,jobject thiz)653*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getDecodedImageNative(JNIEnv *env,
654*89a0ef05SAndroid Build Coastguard Worker                                                                             jobject thiz) {
655*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE_VAL(nullptr)
656*89a0ef05SAndroid Build Coastguard Worker   uhdr_raw_image_t *decodedImg = uhdr_get_decoded_image((uhdr_codec_private_t *)handle);
657*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(decodedImg == nullptr, "java/io/IOException",
658*89a0ef05SAndroid Build Coastguard Worker                   "uhdr_decode() is not yet called or it has returned with error", nullptr)
659*89a0ef05SAndroid Build Coastguard Worker   int bpp = decodedImg->fmt == UHDR_IMG_FMT_64bppRGBAHalfFloat ? 8 : 4;
660*89a0ef05SAndroid Build Coastguard Worker   jbyteArray data = env->NewByteArray(decodedImg->stride[UHDR_PLANE_PACKED] * decodedImg->h * bpp);
661*89a0ef05SAndroid Build Coastguard Worker   jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
662*89a0ef05SAndroid Build Coastguard Worker   std::memcpy(dataptr, decodedImg->planes[UHDR_PLANE_PACKED],
663*89a0ef05SAndroid Build Coastguard Worker               decodedImg->stride[UHDR_PLANE_PACKED] * decodedImg->h * bpp);
664*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(data, dataptr, 0);
665*89a0ef05SAndroid Build Coastguard Worker #define SET_INT_FIELD(name, val)                                                   \
666*89a0ef05SAndroid Build Coastguard Worker   {                                                                                \
667*89a0ef05SAndroid Build Coastguard Worker     jfieldID fID = env->GetFieldID(clazz, name, "I");                              \
668*89a0ef05SAndroid Build Coastguard Worker     RET_VAL_IF_TRUE(fID == nullptr, "java/io/IOException",                         \
669*89a0ef05SAndroid Build Coastguard Worker                     "GetFieldID for field " #name " returned with error", nullptr) \
670*89a0ef05SAndroid Build Coastguard Worker     env->SetIntField(thiz, fID, (jint)val);                                        \
671*89a0ef05SAndroid Build Coastguard Worker   }
672*89a0ef05SAndroid Build Coastguard Worker   SET_INT_FIELD("imgWidth", decodedImg->w)
673*89a0ef05SAndroid Build Coastguard Worker   SET_INT_FIELD("imgHeight", decodedImg->h)
674*89a0ef05SAndroid Build Coastguard Worker   SET_INT_FIELD("imgStride", decodedImg->stride[UHDR_PLANE_PACKED])
675*89a0ef05SAndroid Build Coastguard Worker   SET_INT_FIELD("imgFormat", decodedImg->fmt)
676*89a0ef05SAndroid Build Coastguard Worker   SET_INT_FIELD("imgGamut", decodedImg->cg)
677*89a0ef05SAndroid Build Coastguard Worker   SET_INT_FIELD("imgTransfer", decodedImg->ct)
678*89a0ef05SAndroid Build Coastguard Worker   SET_INT_FIELD("imgRange", decodedImg->range)
679*89a0ef05SAndroid Build Coastguard Worker   return data;
680*89a0ef05SAndroid Build Coastguard Worker }
681*89a0ef05SAndroid Build Coastguard Worker 
682*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getDecodedGainMapImageNative(JNIEnv * env,jobject thiz)683*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getDecodedGainMapImageNative(JNIEnv *env,
684*89a0ef05SAndroid Build Coastguard Worker                                                                                    jobject thiz) {
685*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE_VAL(nullptr)
686*89a0ef05SAndroid Build Coastguard Worker   uhdr_raw_image_t *gainmapImg = uhdr_get_decoded_gainmap_image((uhdr_codec_private_t *)handle);
687*89a0ef05SAndroid Build Coastguard Worker   RET_VAL_IF_TRUE(gainmapImg == nullptr, "java/io/IOException",
688*89a0ef05SAndroid Build Coastguard Worker                   "uhdr_decode() is not yet called or it has returned with error", nullptr)
689*89a0ef05SAndroid Build Coastguard Worker   int bpp = gainmapImg->fmt == UHDR_IMG_FMT_32bppRGBA8888 ? 4 : 1;
690*89a0ef05SAndroid Build Coastguard Worker   jbyteArray data = env->NewByteArray(gainmapImg->stride[UHDR_PLANE_PACKED] * gainmapImg->h * bpp);
691*89a0ef05SAndroid Build Coastguard Worker   jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
692*89a0ef05SAndroid Build Coastguard Worker   std::memcpy(dataptr, gainmapImg->planes[UHDR_PLANE_PACKED],
693*89a0ef05SAndroid Build Coastguard Worker               gainmapImg->stride[UHDR_PLANE_PACKED] * gainmapImg->h * bpp);
694*89a0ef05SAndroid Build Coastguard Worker   env->ReleaseByteArrayElements(data, dataptr, 0);
695*89a0ef05SAndroid Build Coastguard Worker   SET_INT_FIELD("gainmapWidth", gainmapImg->w)
696*89a0ef05SAndroid Build Coastguard Worker   SET_INT_FIELD("gainmapHeight", gainmapImg->h)
697*89a0ef05SAndroid Build Coastguard Worker   SET_INT_FIELD("gainmapStride", gainmapImg->stride[UHDR_PLANE_PACKED])
698*89a0ef05SAndroid Build Coastguard Worker   SET_INT_FIELD("gainmapFormat", gainmapImg->fmt)
699*89a0ef05SAndroid Build Coastguard Worker   return data;
700*89a0ef05SAndroid Build Coastguard Worker }
701*89a0ef05SAndroid Build Coastguard Worker 
702*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_resetNative(JNIEnv * env,jobject thiz)703*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_resetNative(JNIEnv *env, jobject thiz) {
704*89a0ef05SAndroid Build Coastguard Worker   GET_HANDLE()
705*89a0ef05SAndroid Build Coastguard Worker   RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
706*89a0ef05SAndroid Build Coastguard Worker   uhdr_reset_decoder((uhdr_codec_private_t *)handle);
707*89a0ef05SAndroid Build Coastguard Worker }
708*89a0ef05SAndroid Build Coastguard Worker 
709*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jstring JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRCommon_getVersionStringNative(JNIEnv * env,jclass clazz)710*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRCommon_getVersionStringNative(JNIEnv *env,
711*89a0ef05SAndroid Build Coastguard Worker                                                                             jclass clazz) {
712*89a0ef05SAndroid Build Coastguard Worker   std::string version{"v" UHDR_LIB_VERSION_STR};
713*89a0ef05SAndroid Build Coastguard Worker   return env->NewStringUTF(version.c_str());
714*89a0ef05SAndroid Build Coastguard Worker }
715*89a0ef05SAndroid Build Coastguard Worker 
716*89a0ef05SAndroid Build Coastguard Worker extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRCommon_getVersionNative(JNIEnv * env,jclass clazz)717*89a0ef05SAndroid Build Coastguard Worker Java_com_google_media_codecs_ultrahdr_UltraHDRCommon_getVersionNative(JNIEnv *env, jclass clazz) {
718*89a0ef05SAndroid Build Coastguard Worker   return UHDR_LIB_VERSION;
719*89a0ef05SAndroid Build Coastguard Worker }
720