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,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 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setGainMapImageInfoNative(
236 JNIEnv *env, jobject thiz, jbyteArray data, jint size, jfloat max_content_boost,
237 jfloat min_content_boost, jfloat gainmap_gamma, jfloat offset_sdr, jfloat offset_hdr,
238 jfloat hdr_capacity_min, jfloat hdr_capacity_max) {
239 GET_HANDLE()
240 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
241 jsize length = env->GetArrayLength(data);
242 RET_IF_TRUE(length < size, "java/io/IOException",
243 "compressed image byteArray size is less than configured size")
244 jbyte *body = env->GetByteArrayElements(data, nullptr);
245 uhdr_compressed_image_t img{body,
246 (unsigned int)size,
247 (unsigned int)length,
248 UHDR_CG_UNSPECIFIED,
249 UHDR_CT_UNSPECIFIED,
250 UHDR_CR_UNSPECIFIED};
251 uhdr_gainmap_metadata_t metadata{max_content_boost, min_content_boost, gainmap_gamma,
252 offset_sdr, offset_hdr, hdr_capacity_min,
253 hdr_capacity_max};
254 auto status = uhdr_enc_set_gainmap_image((uhdr_codec_private_t *)handle, &img, &metadata);
255 env->ReleaseByteArrayElements(data, body, 0);
256 RET_IF_TRUE(
257 status.error_code != UHDR_CODEC_OK, "java/io/IOException",
258 status.has_detail ? status.detail : "uhdr_enc_set_gainmap_image() returned with error")
259 }
260
261 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setExifDataNative(JNIEnv * env,jobject thiz,jbyteArray data,jint size)262 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setExifDataNative(JNIEnv *env, jobject thiz,
263 jbyteArray data,
264 jint size) {
265 GET_HANDLE()
266 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
267 jsize length = env->GetArrayLength(data);
268 RET_IF_TRUE(length < size, "java/io/IOException",
269 "compressed image byteArray size is less than configured size")
270 jbyte *body = env->GetByteArrayElements(data, nullptr);
271 uhdr_mem_block_t exif{body, (unsigned int)size, (unsigned int)length};
272 auto status = uhdr_enc_set_exif_data((uhdr_codec_private_t *)handle, &exif);
273 env->ReleaseByteArrayElements(data, body, 0);
274 RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
275 status.has_detail ? status.detail : "uhdr_enc_set_exif_data() returned with error")
276 }
277
278 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setQualityFactorNative(JNIEnv * env,jobject thiz,jint quality_factor,jint intent)279 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setQualityFactorNative(JNIEnv *env,
280 jobject thiz,
281 jint quality_factor,
282 jint intent) {
283 GET_HANDLE()
284 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
285 auto status = uhdr_enc_set_quality((uhdr_codec_private_t *)handle, quality_factor,
286 (uhdr_img_label_t)intent);
287 RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
288 status.has_detail ? status.detail : "uhdr_enc_set_quality() returned with error")
289 }
290
291 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setMultiChannelGainMapEncodingNative(JNIEnv * env,jobject thiz,jboolean enable)292 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setMultiChannelGainMapEncodingNative(
293 JNIEnv *env, jobject thiz, jboolean enable) {
294 GET_HANDLE()
295 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
296 auto status =
297 uhdr_enc_set_using_multi_channel_gainmap((uhdr_codec_private_t *)handle, enable ? 1 : 0);
298 RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
299 status.has_detail ? status.detail
300 : "uhdr_enc_set_using_multi_channel_gainmap() returned with error")
301 }
302
303 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setGainMapScaleFactorNative(JNIEnv * env,jobject thiz,jint scale_factor)304 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setGainMapScaleFactorNative(
305 JNIEnv *env, jobject thiz, jint scale_factor) {
306 GET_HANDLE()
307 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
308 auto status = uhdr_enc_set_gainmap_scale_factor((uhdr_codec_private_t *)handle, scale_factor);
309 RET_IF_TRUE(
310 status.error_code != UHDR_CODEC_OK, "java/io/IOException",
311 status.has_detail ? status.detail : "uhdr_enc_set_gainmap_scale_factor() returned with error")
312 }
313
314 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setGainMapGammaNative(JNIEnv * env,jobject thiz,jfloat gamma)315 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setGainMapGammaNative(JNIEnv *env,
316 jobject thiz,
317 jfloat gamma) {
318 GET_HANDLE()
319 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
320 auto status = uhdr_enc_set_gainmap_gamma((uhdr_codec_private_t *)handle, gamma);
321 RET_IF_TRUE(
322 status.error_code != UHDR_CODEC_OK, "java/io/IOException",
323 status.has_detail ? status.detail : "uhdr_enc_set_gainmap_gamma() returned with error")
324 }
325
326 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setEncPresetNative(JNIEnv * env,jobject thiz,jint preset)327 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setEncPresetNative(JNIEnv *env, jobject thiz,
328 jint preset) {
329 GET_HANDLE()
330 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
331 auto status = uhdr_enc_set_preset((uhdr_codec_private_t *)handle, (uhdr_enc_preset_t)preset);
332 RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
333 status.has_detail ? status.detail : "uhdr_enc_set_preset() returned with error")
334 }
335
336 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setOutputFormatNative(JNIEnv * env,jobject thiz,jint media_type)337 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setOutputFormatNative(JNIEnv *env,
338 jobject thiz,
339 jint media_type) {
340 GET_HANDLE()
341 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
342 auto status =
343 uhdr_enc_set_output_format((uhdr_codec_private_t *)handle, (uhdr_codec_t)media_type);
344 RET_IF_TRUE(
345 status.error_code != UHDR_CODEC_OK, "java/io/IOException",
346 status.has_detail ? status.detail : "uhdr_enc_set_output_format() returned with error")
347 }
348
349 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 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setMinMaxContentBoostNative(
351 JNIEnv *env, jobject thiz, jfloat min_content_boost, jfloat max_content_boost) {
352 GET_HANDLE()
353 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
354 auto status = uhdr_enc_set_min_max_content_boost((uhdr_codec_private_t *)handle,
355 min_content_boost, max_content_boost);
356 RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
357 status.has_detail ? status.detail
358 : "uhdr_enc_set_min_max_content_boost() returned with error")
359 }
360
361 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setTargetDisplayPeakBrightnessNative(JNIEnv * env,jobject thiz,jfloat nits)362 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_setTargetDisplayPeakBrightnessNative(
363 JNIEnv *env, jobject thiz, jfloat nits) {
364 GET_HANDLE()
365 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
366 auto status = uhdr_enc_set_target_display_peak_brightness((uhdr_codec_private_t *)handle, nits);
367 RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
368 status.has_detail
369 ? status.detail
370 : "uhdr_enc_set_target_display_peak_brightness() returned with error")
371 }
372
373 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_encodeNative(JNIEnv * env,jobject thiz)374 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_encodeNative(JNIEnv *env, jobject thiz) {
375 GET_HANDLE()
376 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
377 auto status = uhdr_encode((uhdr_codec_private_t *)handle);
378 RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
379 status.has_detail ? status.detail : "uhdr_encode() returned with error")
380 }
381
382 extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_getOutputNative(JNIEnv * env,jobject thiz)383 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_getOutputNative(JNIEnv *env, jobject thiz) {
384 GET_HANDLE_VAL(nullptr)
385 RET_VAL_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance", nullptr)
386 auto enc_output = uhdr_get_encoded_stream((uhdr_codec_private_t *)handle);
387 RET_VAL_IF_TRUE(enc_output == nullptr, "java/io/IOException",
388 "no output returned, may be call to uhdr_encode() was not made or encountered "
389 "error during encoding process.",
390 nullptr)
391 RET_VAL_IF_TRUE(enc_output->data_sz >= INT32_MAX, "java/lang/OutOfMemoryError",
392 "encoded output size exceeds integer max", nullptr)
393 jbyteArray output = env->NewByteArray(enc_output->data_sz);
394 RET_VAL_IF_TRUE(output == nullptr, "java/io/IOException", "failed to allocate storage for output",
395 nullptr)
396 env->SetByteArrayRegion(output, 0, enc_output->data_sz, (jbyte *)enc_output->data);
397 return output;
398 }
399
400 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_resetNative(JNIEnv * env,jobject thiz)401 Java_com_google_media_codecs_ultrahdr_UltraHDREncoder_resetNative(JNIEnv *env, jobject thiz) {
402 GET_HANDLE()
403 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid encoder instance")
404 uhdr_reset_encoder((uhdr_codec_private_t *)handle);
405 }
406
407 extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_isUHDRImageNative(JNIEnv * env,jclass clazz,jbyteArray data,jint size)408 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_isUHDRImageNative(JNIEnv *env, jclass clazz,
409 jbyteArray data,
410 jint size) {
411 jsize length = env->GetArrayLength(data);
412 RET_VAL_IF_TRUE(length < size, "java/io/IOException",
413 "compressed image byteArray size is less than configured size", 0)
414 jbyte *body = env->GetByteArrayElements(data, nullptr);
415 auto status = is_uhdr_image(body, size);
416 env->ReleaseByteArrayElements(data, body, 0);
417 return status;
418 }
419
420 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_init(JNIEnv * env,jobject thiz)421 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_init(JNIEnv *env, jobject thiz) {
422 jclass clazz = env->GetObjectClass(thiz);
423 RET_IF_TRUE(clazz == nullptr, "java/io/IOException", "GetObjectClass returned with error")
424 jfieldID fid = env->GetFieldID(clazz, "handle", "J");
425 RET_IF_TRUE(fid == nullptr, "java/io/IOException",
426 "GetFieldID for field 'handle' returned with error")
427 uhdr_codec_private_t *handle = uhdr_create_decoder();
428 RET_IF_TRUE(handle == nullptr, "java/lang/OutOfMemoryError",
429 "Unable to allocate decoder instance")
430 env->SetLongField(thiz, fid, (jlong)handle);
431 }
432
433 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_destroy(JNIEnv * env,jobject thiz)434 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_destroy(JNIEnv *env, jobject thiz) {
435 GET_HANDLE()
436 if (!handle) {
437 uhdr_release_decoder((uhdr_codec_private *)handle);
438 env->SetLongField(thiz, fid, (jlong)0);
439 }
440 }
441
442 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 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setCompressedImageNative(
444 JNIEnv *env, jobject thiz, jbyteArray data, jint size, jint color_gamut, jint color_transfer,
445 jint range) {
446 RET_IF_TRUE(size < 0, "java/io/IOException", "invalid compressed image size")
447 GET_HANDLE()
448 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
449 jsize length = env->GetArrayLength(data);
450 RET_IF_TRUE(length < size, "java/io/IOException",
451 "compressed image byteArray size is less than configured size")
452 jbyte *body = env->GetByteArrayElements(data, nullptr);
453 uhdr_compressed_image_t img{body,
454 (unsigned int)size,
455 (unsigned int)length,
456 (uhdr_color_gamut_t)color_gamut,
457 (uhdr_color_transfer_t)color_transfer,
458 (uhdr_color_range_t)range};
459 uhdr_error_info_t status = uhdr_dec_set_image((uhdr_codec_private_t *)handle, &img);
460 env->ReleaseByteArrayElements(data, body, 0);
461 RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
462 status.has_detail ? status.detail : "uhdr_dec_set_image() returned with error")
463 }
464
465 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setOutputFormatNative(JNIEnv * env,jobject thiz,jint fmt)466 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setOutputFormatNative(JNIEnv *env,
467 jobject thiz,
468 jint fmt) {
469 GET_HANDLE()
470 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
471 uhdr_error_info_t status =
472 uhdr_dec_set_out_img_format((uhdr_codec_private_t *)handle, (uhdr_img_fmt_t)fmt);
473 RET_IF_TRUE(
474 status.error_code != UHDR_CODEC_OK, "java/io/IOException",
475 status.has_detail ? status.detail : "uhdr_dec_set_out_img_format() returned with error")
476 }
477
478 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setColorTransferNative(JNIEnv * env,jobject thiz,jint ct)479 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setColorTransferNative(JNIEnv *env,
480 jobject thiz,
481 jint ct) {
482 GET_HANDLE()
483 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
484 uhdr_error_info_t status =
485 uhdr_dec_set_out_color_transfer((uhdr_codec_private_t *)handle, (uhdr_color_transfer_t)ct);
486 RET_IF_TRUE(
487 status.error_code != UHDR_CODEC_OK, "java/io/IOException",
488 status.has_detail ? status.detail : "uhdr_dec_set_out_color_transfer() returned with error")
489 }
490
491 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setMaxDisplayBoostNative(JNIEnv * env,jobject thiz,jfloat display_boost)492 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_setMaxDisplayBoostNative(
493 JNIEnv *env, jobject thiz, jfloat display_boost) {
494 GET_HANDLE()
495 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
496 uhdr_error_info_t status =
497 uhdr_dec_set_out_max_display_boost((uhdr_codec_private_t *)handle, (float)display_boost);
498 RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
499 status.has_detail ? status.detail
500 : "uhdr_dec_set_out_max_display_boost() returned with error")
501 }
502
503 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_enableGpuAccelerationNative(JNIEnv * env,jobject thiz,jint enable)504 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_enableGpuAccelerationNative(JNIEnv *env,
505 jobject thiz,
506 jint enable) {
507 GET_HANDLE()
508 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
509 uhdr_error_info_t status = uhdr_enable_gpu_acceleration((uhdr_codec_private_t *)handle, enable);
510 RET_IF_TRUE(
511 status.error_code != UHDR_CODEC_OK, "java/io/IOException",
512 status.has_detail ? status.detail : "uhdr_enable_gpu_acceleration() returned with error")
513 }
514
515 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_probeNative(JNIEnv * env,jobject thiz)516 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_probeNative(JNIEnv *env, jobject thiz) {
517 GET_HANDLE()
518 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
519 uhdr_error_info_t status = uhdr_dec_probe((uhdr_codec_private_t *)handle);
520 RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
521 status.has_detail ? status.detail : "uhdr_dec_probe() returned with error")
522 }
523
524 extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getImageWidthNative(JNIEnv * env,jobject thiz)525 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getImageWidthNative(JNIEnv *env,
526 jobject thiz) {
527 GET_HANDLE_VAL(-1)
528 auto val = uhdr_dec_get_image_width((uhdr_codec_private_t *)handle);
529 RET_VAL_IF_TRUE(val == -1, "java/io/IOException",
530 "uhdr_dec_probe() is not yet called or it has returned with error", -1)
531 return val;
532 }
533
534 extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getImageHeightNative(JNIEnv * env,jobject thiz)535 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getImageHeightNative(JNIEnv *env,
536 jobject thiz) {
537 GET_HANDLE_VAL(-1)
538 auto val = uhdr_dec_get_image_height((uhdr_codec_private_t *)handle);
539 RET_VAL_IF_TRUE(val == -1, "java/io/IOException",
540 "uhdr_dec_probe() is not yet called or it has returned with error", -1)
541 return val;
542 }
543
544 extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapWidthNative(JNIEnv * env,jobject thiz)545 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapWidthNative(JNIEnv *env,
546 jobject thiz) {
547 GET_HANDLE_VAL(-1)
548 auto val = uhdr_dec_get_gainmap_width((uhdr_codec_private_t *)handle);
549 RET_VAL_IF_TRUE(val == -1, "java/io/IOException",
550 "uhdr_dec_probe() is not yet called or it has returned with error", -1)
551 return val;
552 }
553
554 extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapHeightNative(JNIEnv * env,jobject thiz)555 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapHeightNative(JNIEnv *env,
556 jobject thiz) {
557 GET_HANDLE_VAL(-1)
558 auto val = uhdr_dec_get_gainmap_height((uhdr_codec_private_t *)handle);
559 RET_VAL_IF_TRUE(val == -1, "java/io/IOException",
560 "uhdr_dec_probe() is not yet called or it has returned with error", -1)
561 return val;
562 }
563
564 extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getExifNative(JNIEnv * env,jobject thiz)565 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getExifNative(JNIEnv *env, jobject thiz) {
566 GET_HANDLE_VAL(nullptr)
567 uhdr_mem_block_t *exifData = uhdr_dec_get_exif((uhdr_codec_private_t *)handle);
568 RET_VAL_IF_TRUE(exifData == nullptr, "java/io/IOException",
569 "uhdr_dec_probe() is not yet called or it has returned with error", nullptr)
570 jbyteArray data = env->NewByteArray(exifData->data_sz);
571 jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
572 std::memcpy(dataptr, exifData->data, exifData->data_sz);
573 env->ReleaseByteArrayElements(data, dataptr, 0);
574 return data;
575 }
576
577 extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getIccNative(JNIEnv * env,jobject thiz)578 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getIccNative(JNIEnv *env, jobject thiz) {
579 GET_HANDLE_VAL(nullptr)
580 uhdr_mem_block_t *iccData = uhdr_dec_get_icc((uhdr_codec_private_t *)handle);
581 RET_VAL_IF_TRUE(iccData == nullptr, "java/io/IOException",
582 "uhdr_dec_probe() is not yet called or it has returned with error", nullptr)
583 jbyteArray data = env->NewByteArray(iccData->data_sz);
584 jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
585 std::memcpy(dataptr, iccData->data, iccData->data_sz);
586 env->ReleaseByteArrayElements(data, dataptr, 0);
587 return data;
588 }
589
590 extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getBaseImageNative(JNIEnv * env,jobject thiz)591 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getBaseImageNative(JNIEnv *env,
592 jobject thiz) {
593 GET_HANDLE_VAL(nullptr)
594 uhdr_mem_block_t *baseImgData = uhdr_dec_get_base_image((uhdr_codec_private_t *)handle);
595 RET_VAL_IF_TRUE(baseImgData == nullptr, "java/io/IOException",
596 "uhdr_dec_probe() is not yet called or it has returned with error", nullptr)
597 jbyteArray data = env->NewByteArray(baseImgData->data_sz);
598 jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
599 std::memcpy(dataptr, baseImgData->data, baseImgData->data_sz);
600 env->ReleaseByteArrayElements(data, dataptr, 0);
601 return data;
602 }
603
604 extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapImageNative(JNIEnv * env,jobject thiz)605 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainMapImageNative(JNIEnv *env,
606 jobject thiz) {
607 GET_HANDLE_VAL(nullptr)
608 uhdr_mem_block_t *gainmapImgData = uhdr_dec_get_gainmap_image((uhdr_codec_private_t *)handle);
609 RET_VAL_IF_TRUE(gainmapImgData == nullptr, "java/io/IOException",
610 "uhdr_dec_probe() is not yet called or it has returned with error", nullptr)
611 jbyteArray data = env->NewByteArray(gainmapImgData->data_sz);
612 jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
613 std::memcpy(dataptr, gainmapImgData->data, gainmapImgData->data_sz);
614 env->ReleaseByteArrayElements(data, dataptr, 0);
615 return data;
616 }
617
618 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainmapMetadataNative(JNIEnv * env,jobject thiz)619 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getGainmapMetadataNative(JNIEnv *env,
620 jobject thiz) {
621 GET_HANDLE()
622 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
623 uhdr_gainmap_metadata_t *gainmap_metadata =
624 uhdr_dec_get_gainmap_metadata((uhdr_codec_private_t *)handle);
625 RET_IF_TRUE(gainmap_metadata == nullptr, "java/io/IOException",
626 "uhdr_dec_probe() is not yet called or it has returned with error")
627 #define SET_FLOAT_FIELD(name, val) \
628 { \
629 jfieldID fID = env->GetFieldID(clazz, name, "F"); \
630 RET_IF_TRUE(fID == nullptr, "java/io/IOException", \
631 "GetFieldID for field " #name " returned with error") \
632 env->SetFloatField(thiz, fID, (jfloat)val); \
633 }
634 SET_FLOAT_FIELD("maxContentBoost", gainmap_metadata->max_content_boost)
635 SET_FLOAT_FIELD("minContentBoost", gainmap_metadata->min_content_boost)
636 SET_FLOAT_FIELD("gamma", gainmap_metadata->gamma)
637 SET_FLOAT_FIELD("offsetSdr", gainmap_metadata->offset_sdr)
638 SET_FLOAT_FIELD("offsetHdr", gainmap_metadata->offset_hdr)
639 SET_FLOAT_FIELD("hdrCapacityMin", gainmap_metadata->hdr_capacity_min)
640 SET_FLOAT_FIELD("hdrCapacityMax", gainmap_metadata->hdr_capacity_max)
641 }
642
643 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_decodeNative(JNIEnv * env,jobject thiz)644 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_decodeNative(JNIEnv *env, jobject thiz) {
645 GET_HANDLE()
646 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
647 auto status = uhdr_decode((uhdr_codec_private_t *)handle);
648 RET_IF_TRUE(status.error_code != UHDR_CODEC_OK, "java/io/IOException",
649 status.has_detail ? status.detail : "uhdr_decode() returned with error")
650 }
651
652 extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getDecodedImageNative(JNIEnv * env,jobject thiz)653 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getDecodedImageNative(JNIEnv *env,
654 jobject thiz) {
655 GET_HANDLE_VAL(nullptr)
656 uhdr_raw_image_t *decodedImg = uhdr_get_decoded_image((uhdr_codec_private_t *)handle);
657 RET_VAL_IF_TRUE(decodedImg == nullptr, "java/io/IOException",
658 "uhdr_decode() is not yet called or it has returned with error", nullptr)
659 int bpp = decodedImg->fmt == UHDR_IMG_FMT_64bppRGBAHalfFloat ? 8 : 4;
660 jbyteArray data = env->NewByteArray(decodedImg->stride[UHDR_PLANE_PACKED] * decodedImg->h * bpp);
661 jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
662 std::memcpy(dataptr, decodedImg->planes[UHDR_PLANE_PACKED],
663 decodedImg->stride[UHDR_PLANE_PACKED] * decodedImg->h * bpp);
664 env->ReleaseByteArrayElements(data, dataptr, 0);
665 #define SET_INT_FIELD(name, val) \
666 { \
667 jfieldID fID = env->GetFieldID(clazz, name, "I"); \
668 RET_VAL_IF_TRUE(fID == nullptr, "java/io/IOException", \
669 "GetFieldID for field " #name " returned with error", nullptr) \
670 env->SetIntField(thiz, fID, (jint)val); \
671 }
672 SET_INT_FIELD("imgWidth", decodedImg->w)
673 SET_INT_FIELD("imgHeight", decodedImg->h)
674 SET_INT_FIELD("imgStride", decodedImg->stride[UHDR_PLANE_PACKED])
675 SET_INT_FIELD("imgFormat", decodedImg->fmt)
676 SET_INT_FIELD("imgGamut", decodedImg->cg)
677 SET_INT_FIELD("imgTransfer", decodedImg->ct)
678 SET_INT_FIELD("imgRange", decodedImg->range)
679 return data;
680 }
681
682 extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getDecodedGainMapImageNative(JNIEnv * env,jobject thiz)683 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_getDecodedGainMapImageNative(JNIEnv *env,
684 jobject thiz) {
685 GET_HANDLE_VAL(nullptr)
686 uhdr_raw_image_t *gainmapImg = uhdr_get_decoded_gainmap_image((uhdr_codec_private_t *)handle);
687 RET_VAL_IF_TRUE(gainmapImg == nullptr, "java/io/IOException",
688 "uhdr_decode() is not yet called or it has returned with error", nullptr)
689 int bpp = gainmapImg->fmt == UHDR_IMG_FMT_32bppRGBA8888 ? 4 : 1;
690 jbyteArray data = env->NewByteArray(gainmapImg->stride[UHDR_PLANE_PACKED] * gainmapImg->h * bpp);
691 jbyte *dataptr = env->GetByteArrayElements(data, nullptr);
692 std::memcpy(dataptr, gainmapImg->planes[UHDR_PLANE_PACKED],
693 gainmapImg->stride[UHDR_PLANE_PACKED] * gainmapImg->h * bpp);
694 env->ReleaseByteArrayElements(data, dataptr, 0);
695 SET_INT_FIELD("gainmapWidth", gainmapImg->w)
696 SET_INT_FIELD("gainmapHeight", gainmapImg->h)
697 SET_INT_FIELD("gainmapStride", gainmapImg->stride[UHDR_PLANE_PACKED])
698 SET_INT_FIELD("gainmapFormat", gainmapImg->fmt)
699 return data;
700 }
701
702 extern "C" JNIEXPORT void JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_resetNative(JNIEnv * env,jobject thiz)703 Java_com_google_media_codecs_ultrahdr_UltraHDRDecoder_resetNative(JNIEnv *env, jobject thiz) {
704 GET_HANDLE()
705 RET_IF_TRUE(handle == 0, "java/io/IOException", "invalid decoder instance")
706 uhdr_reset_decoder((uhdr_codec_private_t *)handle);
707 }
708
709 extern "C" JNIEXPORT jstring JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRCommon_getVersionStringNative(JNIEnv * env,jclass clazz)710 Java_com_google_media_codecs_ultrahdr_UltraHDRCommon_getVersionStringNative(JNIEnv *env,
711 jclass clazz) {
712 std::string version{"v" UHDR_LIB_VERSION_STR};
713 return env->NewStringUTF(version.c_str());
714 }
715
716 extern "C" JNIEXPORT jint JNICALL
Java_com_google_media_codecs_ultrahdr_UltraHDRCommon_getVersionNative(JNIEnv * env,jclass clazz)717 Java_com_google_media_codecs_ultrahdr_UltraHDRCommon_getVersionNative(JNIEnv *env, jclass clazz) {
718 return UHDR_LIB_VERSION;
719 }
720