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