blob: 5f5c19684bdd58027aab6287045ebb18fb619b97 [file] [log] [blame]
Dichen Zhang85b37562022-10-11 11:08:28 -07001/*
2 * Copyright 2022 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
Dichen Zhangdbceb0e2023-04-14 19:03:18 +000017#include <ultrahdr/jpegr.h>
18#include <ultrahdr/jpegrutils.h>
19#include <ultrahdr/gainmapmath.h>
Dichen Zhang36c1e732022-11-23 01:25:34 +000020#include <fcntl.h>
21#include <fstream>
22#include <gtest/gtest.h>
Nick Deakind19e5762023-02-10 15:39:08 -050023#include <sys/time.h>
Dichen Zhang36c1e732022-11-23 01:25:34 +000024#include <utils/Log.h>
25
26#define RAW_P010_IMAGE "/sdcard/Documents/raw_p010_image.p010"
Dichen Zhang66ca6e32023-04-05 12:22:54 -070027#define RAW_P010_IMAGE_WITH_STRIDE "/sdcard/Documents/raw_p010_image_with_stride.p010"
Dichen Zhang7e3ed122022-12-14 22:05:01 +000028#define RAW_YUV420_IMAGE "/sdcard/Documents/raw_yuv420_image.yuv420"
Dichen Zhang36c1e732022-11-23 01:25:34 +000029#define JPEG_IMAGE "/sdcard/Documents/jpeg_image.jpg"
Dichen Zhang7e3ed122022-12-14 22:05:01 +000030#define TEST_IMAGE_WIDTH 1280
31#define TEST_IMAGE_HEIGHT 720
Dichen Zhang66ca6e32023-04-05 12:22:54 -070032#define TEST_IMAGE_STRIDE 1288
Dichen Zhang7e3ed122022-12-14 22:05:01 +000033#define DEFAULT_JPEG_QUALITY 90
Dichen Zhang36c1e732022-11-23 01:25:34 +000034
35#define SAVE_ENCODING_RESULT true
36#define SAVE_DECODING_RESULT true
Harish Mahendrakar1e057282022-12-04 12:47:53 -080037#define SAVE_INPUT_RGBA true
Dichen Zhang85b37562022-10-11 11:08:28 -070038
Dichen Zhangdbceb0e2023-04-14 19:03:18 +000039namespace android::ultrahdr {
Dichen Zhang85b37562022-10-11 11:08:28 -070040
Nick Deakind19e5762023-02-10 15:39:08 -050041struct Timer {
42 struct timeval StartingTime;
43 struct timeval EndingTime;
44 struct timeval ElapsedMicroseconds;
Nick Deakin594a4ca2022-11-16 20:57:42 -050045};
46
Nick Deakind19e5762023-02-10 15:39:08 -050047void timerStart(Timer *t) {
48 gettimeofday(&t->StartingTime, nullptr);
49}
Nick Deakin594a4ca2022-11-16 20:57:42 -050050
Nick Deakind19e5762023-02-10 15:39:08 -050051void timerStop(Timer *t) {
52 gettimeofday(&t->EndingTime, nullptr);
53}
54
55int64_t elapsedTime(Timer *t) {
56 t->ElapsedMicroseconds.tv_sec = t->EndingTime.tv_sec - t->StartingTime.tv_sec;
57 t->ElapsedMicroseconds.tv_usec = t->EndingTime.tv_usec - t->StartingTime.tv_usec;
58 return t->ElapsedMicroseconds.tv_sec * 1000000 + t->ElapsedMicroseconds.tv_usec;
Dichen Zhang36c1e732022-11-23 01:25:34 +000059}
60
61static size_t getFileSize(int fd) {
62 struct stat st;
63 if (fstat(fd, &st) < 0) {
64 ALOGW("%s : fstat failed", __func__);
65 return 0;
66 }
67 return st.st_size; // bytes
68}
69
70static bool loadFile(const char filename[], void*& result, int* fileLength) {
71 int fd = open(filename, O_CLOEXEC);
72 if (fd < 0) {
73 return false;
74 }
75 int length = getFileSize(fd);
76 if (length == 0) {
77 close(fd);
78 return false;
79 }
80 if (fileLength != nullptr) {
81 *fileLength = length;
82 }
83 result = malloc(length);
84 if (read(fd, result, length) != static_cast<ssize_t>(length)) {
85 close(fd);
86 return false;
87 }
88 close(fd);
89 return true;
90}
Nick Deakin594a4ca2022-11-16 20:57:42 -050091
Dichen Zhang761b52d2023-02-10 22:38:38 +000092class JpegRTest : public testing::Test {
Nick Deakind19e5762023-02-10 15:39:08 -050093public:
Dichen Zhang761b52d2023-02-10 22:38:38 +000094 JpegRTest();
95 ~JpegRTest();
Nick Deakind19e5762023-02-10 15:39:08 -050096
97protected:
98 virtual void SetUp();
99 virtual void TearDown();
100
101 struct jpegr_uncompressed_struct mRawP010Image;
Dichen Zhang66ca6e32023-04-05 12:22:54 -0700102 struct jpegr_uncompressed_struct mRawP010ImageWithStride;
Nick Deakind19e5762023-02-10 15:39:08 -0500103 struct jpegr_uncompressed_struct mRawYuv420Image;
104 struct jpegr_compressed_struct mJpegImage;
105};
106
Dichen Zhang761b52d2023-02-10 22:38:38 +0000107JpegRTest::JpegRTest() {}
108JpegRTest::~JpegRTest() {}
Nick Deakind19e5762023-02-10 15:39:08 -0500109
Dichen Zhang761b52d2023-02-10 22:38:38 +0000110void JpegRTest::SetUp() {}
111void JpegRTest::TearDown() {
Nick Deakind19e5762023-02-10 15:39:08 -0500112 free(mRawP010Image.data);
Dichen Zhang66ca6e32023-04-05 12:22:54 -0700113 free(mRawP010ImageWithStride.data);
Nick Deakind19e5762023-02-10 15:39:08 -0500114 free(mRawYuv420Image.data);
115 free(mJpegImage.data);
116}
117
Dichen Zhang761b52d2023-02-10 22:38:38 +0000118class JpegRBenchmark : public JpegR {
Nick Deakind19e5762023-02-10 15:39:08 -0500119public:
Dichen Zhang10959a42023-04-10 16:28:16 -0700120 void BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr p010Image,
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000121 ultrahdr_metadata_ptr metadata, jr_uncompressed_ptr map);
Dichen Zhang10959a42023-04-10 16:28:16 -0700122 void BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr map,
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000123 ultrahdr_metadata_ptr metadata, jr_uncompressed_ptr dest);
Nick Deakind19e5762023-02-10 15:39:08 -0500124private:
125 const int kProfileCount = 10;
126};
127
Dichen Zhang10959a42023-04-10 16:28:16 -0700128void JpegRBenchmark::BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image,
129 jr_uncompressed_ptr p010Image,
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000130 ultrahdr_metadata_ptr metadata,
Dichen Zhang10959a42023-04-10 16:28:16 -0700131 jr_uncompressed_ptr map) {
Nick Deakind19e5762023-02-10 15:39:08 -0500132 ASSERT_EQ(yuv420Image->width, p010Image->width);
133 ASSERT_EQ(yuv420Image->height, p010Image->height);
134
135 Timer genRecMapTime;
136
137 timerStart(&genRecMapTime);
138 for (auto i = 0; i < kProfileCount; i++) {
Dichen Zhang10959a42023-04-10 16:28:16 -0700139 ASSERT_EQ(OK, generateGainMap(
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000140 yuv420Image, p010Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, metadata, map));
Nick Deakind19e5762023-02-10 15:39:08 -0500141 if (i != kProfileCount - 1) delete[] static_cast<uint8_t *>(map->data);
142 }
143 timerStop(&genRecMapTime);
144
Dichen Zhang10959a42023-04-10 16:28:16 -0700145 ALOGE("Generate Gain Map:- Res = %i x %i, time = %f ms",
Nick Deakind19e5762023-02-10 15:39:08 -0500146 yuv420Image->width, yuv420Image->height,
147 elapsedTime(&genRecMapTime) / (kProfileCount * 1000.f));
148
149}
150
Dichen Zhang10959a42023-04-10 16:28:16 -0700151void JpegRBenchmark::BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image,
152 jr_uncompressed_ptr map,
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000153 ultrahdr_metadata_ptr metadata,
Dichen Zhang10959a42023-04-10 16:28:16 -0700154 jr_uncompressed_ptr dest) {
Nick Deakind19e5762023-02-10 15:39:08 -0500155 Timer applyRecMapTime;
156
157 timerStart(&applyRecMapTime);
158 for (auto i = 0; i < kProfileCount; i++) {
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000159 ASSERT_EQ(OK, applyGainMap(yuv420Image, map, metadata, ULTRAHDR_OUTPUT_HDR_HLG,
Dichen Zhang10959a42023-04-10 16:28:16 -0700160 metadata->maxContentBoost /* displayBoost */, dest));
Nick Deakind19e5762023-02-10 15:39:08 -0500161 }
162 timerStop(&applyRecMapTime);
163
Dichen Zhang10959a42023-04-10 16:28:16 -0700164 ALOGE("Apply Gain Map:- Res = %i x %i, time = %f ms",
Nick Deakind19e5762023-02-10 15:39:08 -0500165 yuv420Image->width, yuv420Image->height,
166 elapsedTime(&applyRecMapTime) / (kProfileCount * 1000.f));
167}
168
Dichen Zhang761b52d2023-02-10 22:38:38 +0000169TEST_F(JpegRTest, build) {
Dichen Zhang10959a42023-04-10 16:28:16 -0700170 // Force all of the gain map lib to be linked by calling all public functions.
Dichen Zhang761b52d2023-02-10 22:38:38 +0000171 JpegR jpegRCodec;
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000172 jpegRCodec.encodeJPEGR(nullptr, static_cast<ultrahdr_transfer_function>(0), nullptr, 0, nullptr);
173 jpegRCodec.encodeJPEGR(nullptr, nullptr, static_cast<ultrahdr_transfer_function>(0),
Dichen Zhang761b52d2023-02-10 22:38:38 +0000174 nullptr, 0, nullptr);
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000175 jpegRCodec.encodeJPEGR(nullptr, nullptr, nullptr, static_cast<ultrahdr_transfer_function>(0),
Dichen Zhang761b52d2023-02-10 22:38:38 +0000176 nullptr);
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000177 jpegRCodec.encodeJPEGR(nullptr, nullptr, static_cast<ultrahdr_transfer_function>(0), nullptr);
Dichen Zhangc6605702023-03-15 18:40:55 -0700178 jpegRCodec.decodeJPEGR(nullptr, nullptr);
Nick Deakin594a4ca2022-11-16 20:57:42 -0500179}
180
Ram Mohan35ab3a82023-05-18 18:38:16 +0530181/* Test Encode API-0 invalid arguments */
182TEST_F(JpegRTest, encodeAPI0ForInvalidArgs) {
183 int ret;
184
185 // we are not really compressing anything so lets keep allocs to a minimum
186 jpegr_compressed_struct jpegR;
187 jpegR.maxLength = 16 * sizeof(uint8_t);
188 jpegR.data = malloc(jpegR.maxLength);
189
190 JpegR jpegRCodec;
191
192 // we are not really compressing anything so lets keep allocs to a minimum
193 mRawP010ImageWithStride.data = malloc(16);
194 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
195 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
196 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
197 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
198
199 // test quality factor
200 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
201 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
202 -1, nullptr)) << "fail, API allows bad jpeg quality factor";
203
204 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
205 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
206 101, nullptr)) << "fail, API allows bad jpeg quality factor";
207
208 // test hdr transfer function
209 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
210 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED, &jpegR,
211 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
212
213 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
214 &mRawP010ImageWithStride,
215 static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
216 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
217
218 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
219 &mRawP010ImageWithStride,
220 static_cast<ultrahdr_transfer_function>(-10),
221 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
222
223 // test dest
224 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
225 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr,
226 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr dest";
227
228 // test p010 input
229 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
230 nullptr, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
231 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr p010 image";
232
233 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
234 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
235 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
236 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
237 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
238 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
239
240 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
241 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
242 mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
243 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
244 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
245 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
246 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
247
248 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
249 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
250 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
251 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
252 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
253 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
254
255 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
256 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
257 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
258 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
259 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
260
261 mRawP010ImageWithStride.width = 0;
262 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
263 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
264 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
265 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
266
267 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
268 mRawP010ImageWithStride.height = 0;
269 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
270 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
271 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
272
273 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
274 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
275 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
276 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
277 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
278 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad luma stride";
279
280 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
281 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
282 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
283 mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
284 mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
285 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
286 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
287 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad chroma stride";
288
289 free(jpegR.data);
290}
291
292/* Test Encode API-1 invalid arguments */
293TEST_F(JpegRTest, encodeAPI1ForInvalidArgs) {
294 int ret;
295
296 // we are not really compressing anything so lets keep allocs to a minimum
297 jpegr_compressed_struct jpegR;
298 jpegR.maxLength = 16 * sizeof(uint8_t);
299 jpegR.data = malloc(jpegR.maxLength);
300
301 JpegR jpegRCodec;
302
303 // we are not really compressing anything so lets keep allocs to a minimum
304 mRawP010ImageWithStride.data = malloc(16);
305 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
306 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
307 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
308 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
309
310 // we are not really compressing anything so lets keep allocs to a minimum
311 mRawYuv420Image.data = malloc(16);
312 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
313 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
314 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
315
316 // test quality factor
317 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
318 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
319 &jpegR, -1, nullptr)) << "fail, API allows bad jpeg quality factor";
320
321 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
322 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
323 &jpegR, 101, nullptr)) << "fail, API allows bad jpeg quality factor";
324
325 // test hdr transfer function
326 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
327 &mRawP010ImageWithStride, &mRawYuv420Image,
328 ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED, &jpegR, DEFAULT_JPEG_QUALITY,
329 nullptr)) << "fail, API allows bad hdr transfer function";
330
331 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
332 &mRawP010ImageWithStride, &mRawYuv420Image,
333 static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
334 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
335
336 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
337 &mRawP010ImageWithStride, &mRawYuv420Image,
338 static_cast<ultrahdr_transfer_function>(-10),
339 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
340
341 // test dest
342 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
343 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
344 nullptr, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr dest";
345
346 // test p010 input
347 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
348 nullptr, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
349 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr p010 image";
350
351 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
352 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
353 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
354 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
355 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
356 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
357
358 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
359 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
360 mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
361 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
362 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
363 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
364 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
365
366 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
367 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
368 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
369 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
370 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
371 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
372
373 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
374 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
375 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
376 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
377 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
378
379 mRawP010ImageWithStride.width = 0;
380 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
381 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
382 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
383 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
384
385 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
386 mRawP010ImageWithStride.height = 0;
387 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
388 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
389 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
390
391 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
392 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
393 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
394 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
395 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
396 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad luma stride";
397
398 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
399 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
400 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
401 mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
402 mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
403 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
404 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
405 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad chroma stride";
406
407 // test 420 input
408 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
409 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
410 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
411 mRawP010ImageWithStride.chroma_data = nullptr;
412 mRawP010ImageWithStride.chroma_stride = 0;
413 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
414 &mRawP010ImageWithStride, nullptr, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
415 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr for 420 image";
416
417 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
418 mRawYuv420Image.height = TEST_IMAGE_HEIGHT - 2;
419 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
420 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
421 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 image width";
422
423 mRawYuv420Image.width = TEST_IMAGE_WIDTH - 2;
424 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
425 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
426 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
427 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 image height";
428
429 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
430 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
431 mRawYuv420Image.luma_stride = TEST_IMAGE_STRIDE;
432 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
433 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
434 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad luma stride for 420";
435
436 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
437 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
438 mRawYuv420Image.luma_stride = 0;
439 mRawYuv420Image.chroma_data = mRawYuv420Image.data;
440 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
441 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
442 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows chroma pointer for 420";
443
444 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
445 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
446 mRawYuv420Image.luma_stride = 0;
447 mRawYuv420Image.chroma_data = nullptr;
448 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
449 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
450 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
451 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 color gamut";
452
453 mRawYuv420Image.colorGamut = static_cast<ultrahdr_color_gamut>(
454 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
455 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
456 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
457 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 color gamut";
458
459 free(jpegR.data);
460}
461
462/* Test Encode API-2 invalid arguments */
463TEST_F(JpegRTest, encodeAPI2ForInvalidArgs) {
464 int ret;
465
466 // we are not really compressing anything so lets keep allocs to a minimum
467 jpegr_compressed_struct jpegR;
468 jpegR.maxLength = 16 * sizeof(uint8_t);
469 jpegR.data = malloc(jpegR.maxLength);
470
471 JpegR jpegRCodec;
472
473 // we are not really compressing anything so lets keep allocs to a minimum
474 mRawP010ImageWithStride.data = malloc(16);
475 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
476 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
477 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
478 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
479
480 // we are not really compressing anything so lets keep allocs to a minimum
481 mRawYuv420Image.data = malloc(16);
482 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
483 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
484 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
485
486 // test hdr transfer function
487 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
488 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
489 ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
490 &jpegR)) << "fail, API allows bad hdr transfer function";
491
492 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
493 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
494 static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
495 &jpegR)) << "fail, API allows bad hdr transfer function";
496
497 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
498 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
499 static_cast<ultrahdr_transfer_function>(-10),
500 &jpegR)) << "fail, API allows bad hdr transfer function";
501
502 // test dest
503 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
504 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
505 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr)) << "fail, API allows nullptr dest";
506
507 // test p010 input
508 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
509 nullptr, &mRawYuv420Image, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
510 &jpegR)) << "fail, API allows nullptr p010 image";
511
512 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
513 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
514 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
515 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
516 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
517 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
518 &jpegR)) << "fail, API allows bad p010 color gamut";
519
520 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
521 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
522 mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
523 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
524 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
525 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
526 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
527 &jpegR)) << "fail, API allows bad p010 color gamut";
528
529 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
530 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
531 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
532 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
533 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
534 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image width";
535
536 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
537 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
538 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
539 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
540 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image height";
541
542 mRawP010ImageWithStride.width = 0;
543 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
544 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
545 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
546 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image width";
547
548 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
549 mRawP010ImageWithStride.height = 0;
550 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
551 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
552 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image height";
553
554 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
555 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
556 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
557 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
558 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
559 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad luma stride";
560
561 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
562 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
563 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
564 mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
565 mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
566 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
567 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
568 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
569 &jpegR)) << "fail, API allows bad chroma stride";
570
571 // test 420 input
572 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
573 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
574 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
575 mRawP010ImageWithStride.chroma_data = nullptr;
576 mRawP010ImageWithStride.chroma_stride = 0;
577 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
578 &mRawP010ImageWithStride, nullptr, &jpegR,
579 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
580 &jpegR)) << "fail, API allows nullptr for 420 image";
581
582 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
583 mRawYuv420Image.height = TEST_IMAGE_HEIGHT - 2;
584 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
585 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
586 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
587 &jpegR)) << "fail, API allows bad 420 image width";
588
589 mRawYuv420Image.width = TEST_IMAGE_WIDTH - 2;
590 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
591 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
592 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
593 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
594 &jpegR)) << "fail, API allows bad 420 image height";
595
596 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
597 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
598 mRawYuv420Image.luma_stride = TEST_IMAGE_STRIDE;
599 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
600 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
601 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
602 &jpegR)) << "fail, API allows bad luma stride for 420";
603
604 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
605 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
606 mRawYuv420Image.luma_stride = 0;
607 mRawYuv420Image.chroma_data = mRawYuv420Image.data;
608 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
609 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
610 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
611 &jpegR)) << "fail, API allows chroma pointer for 420";
612
613 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
614 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
615 mRawYuv420Image.luma_stride = 0;
616 mRawYuv420Image.chroma_data = nullptr;
617 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
618 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
619 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
620 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
621 &jpegR)) << "fail, API allows bad 420 color gamut";
622
623 mRawYuv420Image.colorGamut = static_cast<ultrahdr_color_gamut>(
624 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
625 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
626 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
627 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
628 &jpegR)) << "fail, API allows bad 420 color gamut";
629
630 // bad compressed image
631 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
632 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
633 &mRawP010ImageWithStride, &mRawYuv420Image, nullptr,
634 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
635 &jpegR)) << "fail, API allows bad 420 color gamut";
636
637 free(jpegR.data);
638}
639
640/* Test Encode API-3 invalid arguments */
641TEST_F(JpegRTest, encodeAPI3ForInvalidArgs) {
642 int ret;
643
644 // we are not really compressing anything so lets keep allocs to a minimum
645 jpegr_compressed_struct jpegR;
646 jpegR.maxLength = 16 * sizeof(uint8_t);
647 jpegR.data = malloc(jpegR.maxLength);
648
649 JpegR jpegRCodec;
650
651 // we are not really compressing anything so lets keep allocs to a minimum
652 mRawP010ImageWithStride.data = malloc(16);
653 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
654 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
655 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
656 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
657
658 // test hdr transfer function
659 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
660 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
661 &jpegR)) << "fail, API allows bad hdr transfer function";
662
663 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
664 &mRawP010ImageWithStride, &jpegR,
665 static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
666 &jpegR)) << "fail, API allows bad hdr transfer function";
667
668 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
669 &mRawP010ImageWithStride, &jpegR, static_cast<ultrahdr_transfer_function>(-10),
670 &jpegR)) << "fail, API allows bad hdr transfer function";
671
672 // test dest
673 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
674 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
675 nullptr)) << "fail, API allows nullptr dest";
676
677 // test p010 input
678 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
679 nullptr, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
680 &jpegR)) << "fail, API allows nullptr p010 image";
681
682 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
683 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
684 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
685 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
686 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
687 &jpegR)) << "fail, API allows bad p010 color gamut";
688
689 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
690 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
691 mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
692 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
693 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
694 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
695 &jpegR)) << "fail, API allows bad p010 color gamut";
696
697 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
698 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
699 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
700 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
701 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
702 &jpegR)) << "fail, API allows bad image width";
703
704 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
705 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
706 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
707 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
708 &jpegR)) << "fail, API allows bad image height";
709
710 mRawP010ImageWithStride.width = 0;
711 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
712 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
713 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
714 &jpegR)) << "fail, API allows bad image width";
715
716 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
717 mRawP010ImageWithStride.height = 0;
718 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
719 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
720 &jpegR)) << "fail, API allows bad image height";
721
722 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
723 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
724 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
725 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
726 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
727 &jpegR)) << "fail, API allows bad luma stride";
728
729 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
730 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
731 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
732 mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
733 mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
734 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
735 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
736 &jpegR)) << "fail, API allows bad chroma stride";
737
738 // bad compressed image
739 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
740 &mRawP010ImageWithStride, nullptr, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
741 &jpegR)) << "fail, API allows bad 420 color gamut";
742
743 free(jpegR.data);
744}
745
746/* Test Encode API-4 invalid arguments */
747TEST_F(JpegRTest, encodeAPI4ForInvalidArgs) {
748 int ret;
749
750 // we are not really compressing anything so lets keep allocs to a minimum
751 jpegr_compressed_struct jpegR;
752 jpegR.maxLength = 16 * sizeof(uint8_t);
753 jpegR.data = malloc(jpegR.maxLength);
754
755 JpegR jpegRCodec;
756
757 // test dest
758 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
759 &jpegR, &jpegR, nullptr, nullptr)) << "fail, API allows nullptr dest";
760
761 // test primary image
762 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
763 nullptr, &jpegR, nullptr, &jpegR)) << "fail, API allows nullptr primary image";
764
765 // test gain map
766 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
767 &jpegR, nullptr, nullptr, &jpegR)) << "fail, API allows nullptr gainmap image";
768
769 free(jpegR.data);
770}
771
Ram Mohanb0375052023-05-20 04:03:48 +0530772/* Test Decode API invalid arguments */
773TEST_F(JpegRTest, decodeAPIForInvalidArgs) {
774 int ret;
775
776 // we are not really compressing anything so lets keep allocs to a minimum
777 jpegr_compressed_struct jpegR;
778 jpegR.maxLength = 16 * sizeof(uint8_t);
779 jpegR.data = malloc(jpegR.maxLength);
780
781 // we are not really decoding anything so lets keep allocs to a minimum
782 mRawP010Image.data = malloc(16);
783
784 JpegR jpegRCodec;
785
786 // test jpegr image
787 EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
788 nullptr, &mRawP010Image)) << "fail, API allows nullptr for jpegr img";
789
790 // test dest image
791 EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
792 &jpegR, nullptr)) << "fail, API allows nullptr for dest";
793
794 // test max display boost
795 EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
796 &jpegR, &mRawP010Image, 0.5)) << "fail, API allows invalid max display boost";
797
798 // test output format
799 EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
800 &jpegR, &mRawP010Image, 0.5, nullptr,
801 static_cast<ultrahdr_output_format>(-1))) << "fail, API allows invalid output format";
802
803 EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
804 &jpegR, &mRawP010Image, 0.5, nullptr,
805 static_cast<ultrahdr_output_format>(ULTRAHDR_OUTPUT_MAX + 1)))
806 << "fail, API allows invalid output format";
807
808 free(jpegR.data);
809}
810
Dichen Zhang761b52d2023-02-10 22:38:38 +0000811TEST_F(JpegRTest, writeXmpThenRead) {
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000812 ultrahdr_metadata_struct metadata_expected;
Nick Deakin05ceebf2023-04-19 15:27:13 -0400813 metadata_expected.version = "1.0";
Nick Deakin01759062023-02-02 18:21:43 -0500814 metadata_expected.maxContentBoost = 1.25;
Nick Deakin3f89a3e2023-02-14 20:35:42 -0500815 metadata_expected.minContentBoost = 0.75;
Fyodor Kyslov8f46e2a2023-01-20 04:21:56 +0000816 const std::string nameSpace = "http://ns.adobe.com/xap/1.0/\0";
817 const int nameSpaceLength = nameSpace.size() + 1; // need to count the null terminator
818
Dichen Zhang61ede362023-02-22 18:50:13 +0000819 std::string xmp = generateXmpForSecondaryImage(metadata_expected);
Dichen Zhangdc8452b2022-11-23 17:17:56 +0000820
Fyodor Kyslov8f46e2a2023-01-20 04:21:56 +0000821 std::vector<uint8_t> xmpData;
822 xmpData.reserve(nameSpaceLength + xmp.size());
823 xmpData.insert(xmpData.end(), reinterpret_cast<const uint8_t*>(nameSpace.c_str()),
824 reinterpret_cast<const uint8_t*>(nameSpace.c_str()) + nameSpaceLength);
825 xmpData.insert(xmpData.end(), reinterpret_cast<const uint8_t*>(xmp.c_str()),
826 reinterpret_cast<const uint8_t*>(xmp.c_str()) + xmp.size());
827
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000828 ultrahdr_metadata_struct metadata_read;
Fyodor Kyslov8f46e2a2023-01-20 04:21:56 +0000829 EXPECT_TRUE(getMetadataFromXMP(xmpData.data(), xmpData.size(), &metadata_read));
Nick Deakin31f03e32023-03-31 16:00:13 -0400830 EXPECT_FLOAT_EQ(metadata_expected.maxContentBoost, metadata_read.maxContentBoost);
831 EXPECT_FLOAT_EQ(metadata_expected.minContentBoost, metadata_read.minContentBoost);
Dichen Zhangdc8452b2022-11-23 17:17:56 +0000832}
Dichen Zhang7e3ed122022-12-14 22:05:01 +0000833
834/* Test Encode API-0 and decode */
Dichen Zhang761b52d2023-02-10 22:38:38 +0000835TEST_F(JpegRTest, encodeFromP010ThenDecode) {
Dichen Zhangc3437ca2023-01-04 14:00:08 -0800836 int ret;
837
838 // Load input files.
839 if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
840 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
841 }
842 mRawP010Image.width = TEST_IMAGE_WIDTH;
843 mRawP010Image.height = TEST_IMAGE_HEIGHT;
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000844 mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
Dichen Zhangc3437ca2023-01-04 14:00:08 -0800845
Dichen Zhang761b52d2023-02-10 22:38:38 +0000846 JpegR jpegRCodec;
Dichen Zhangc3437ca2023-01-04 14:00:08 -0800847
848 jpegr_compressed_struct jpegR;
849 jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
850 jpegR.data = malloc(jpegR.maxLength);
Dichen Zhang761b52d2023-02-10 22:38:38 +0000851 ret = jpegRCodec.encodeJPEGR(
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000852 &mRawP010Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR, DEFAULT_JPEG_QUALITY,
853 nullptr);
Dichen Zhangc3437ca2023-01-04 14:00:08 -0800854 if (ret != OK) {
855 FAIL() << "Error code is " << ret;
856 }
857 if (SAVE_ENCODING_RESULT) {
858 // Output image data to file
Dichen Zhang61ede362023-02-22 18:50:13 +0000859 std::string filePath = "/sdcard/Documents/encoded_from_p010_input.jpgr";
Dichen Zhangc3437ca2023-01-04 14:00:08 -0800860 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
861 if (!imageFile.is_open()) {
862 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
863 }
864 imageFile.write((const char*)jpegR.data, jpegR.length);
865 }
866
867 jpegr_uncompressed_struct decodedJpegR;
Dichen Zhang3e5798c2023-03-01 22:30:43 +0000868 int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
Dichen Zhangc3437ca2023-01-04 14:00:08 -0800869 decodedJpegR.data = malloc(decodedJpegRSize);
Dichen Zhang761b52d2023-02-10 22:38:38 +0000870 ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
Dichen Zhangc3437ca2023-01-04 14:00:08 -0800871 if (ret != OK) {
872 FAIL() << "Error code is " << ret;
873 }
874 if (SAVE_DECODING_RESULT) {
875 // Output image data to file
Dichen Zhang3e5798c2023-03-01 22:30:43 +0000876 std::string filePath = "/sdcard/Documents/decoded_from_p010_input.rgb";
Dichen Zhangc3437ca2023-01-04 14:00:08 -0800877 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
878 if (!imageFile.is_open()) {
879 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
880 }
881 imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
882 }
883
884 free(jpegR.data);
885 free(decodedJpegR.data);
886}
Dichen Zhang7e3ed122022-12-14 22:05:01 +0000887
Dichen Zhang66ca6e32023-04-05 12:22:54 -0700888/* Test Encode API-0 (with stride) and decode */
889TEST_F(JpegRTest, encodeFromP010WithStrideThenDecode) {
890 int ret;
891
892 // Load input files.
893 if (!loadFile(RAW_P010_IMAGE_WITH_STRIDE, mRawP010ImageWithStride.data, nullptr)) {
894 FAIL() << "Load file " << RAW_P010_IMAGE_WITH_STRIDE << " failed";
895 }
896 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
897 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
898 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000899 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
Dichen Zhang66ca6e32023-04-05 12:22:54 -0700900
901 JpegR jpegRCodec;
902
903 jpegr_compressed_struct jpegR;
904 jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
905 jpegR.data = malloc(jpegR.maxLength);
906 ret = jpegRCodec.encodeJPEGR(
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000907 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
Dichen Zhang66ca6e32023-04-05 12:22:54 -0700908 DEFAULT_JPEG_QUALITY, nullptr);
909 if (ret != OK) {
910 FAIL() << "Error code is " << ret;
911 }
912 if (SAVE_ENCODING_RESULT) {
913 // Output image data to file
914 std::string filePath = "/sdcard/Documents/encoded_from_p010_input.jpgr";
915 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
916 if (!imageFile.is_open()) {
917 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
918 }
919 imageFile.write((const char*)jpegR.data, jpegR.length);
920 }
921
922 jpegr_uncompressed_struct decodedJpegR;
923 int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
924 decodedJpegR.data = malloc(decodedJpegRSize);
925 ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
926 if (ret != OK) {
927 FAIL() << "Error code is " << ret;
928 }
929 if (SAVE_DECODING_RESULT) {
930 // Output image data to file
931 std::string filePath = "/sdcard/Documents/decoded_from_p010_input.rgb";
932 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
933 if (!imageFile.is_open()) {
934 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
935 }
936 imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
937 }
938
939 free(jpegR.data);
940 free(decodedJpegR.data);
941}
942
Dichen Zhang7e3ed122022-12-14 22:05:01 +0000943/* Test Encode API-1 and decode */
Dichen Zhang761b52d2023-02-10 22:38:38 +0000944TEST_F(JpegRTest, encodeFromRawHdrAndSdrThenDecode) {
Dichen Zhang54444382022-12-07 20:57:49 +0000945 int ret;
946
947 // Load input files.
948 if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
949 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
950 }
Dichen Zhang7e3ed122022-12-14 22:05:01 +0000951 mRawP010Image.width = TEST_IMAGE_WIDTH;
952 mRawP010Image.height = TEST_IMAGE_HEIGHT;
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000953 mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
Dichen Zhang54444382022-12-07 20:57:49 +0000954
Dichen Zhang7e3ed122022-12-14 22:05:01 +0000955 if (!loadFile(RAW_YUV420_IMAGE, mRawYuv420Image.data, nullptr)) {
956 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
957 }
958 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
959 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000960 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
Dichen Zhang7e3ed122022-12-14 22:05:01 +0000961
Dichen Zhang761b52d2023-02-10 22:38:38 +0000962 JpegR jpegRCodec;
Dichen Zhang54444382022-12-07 20:57:49 +0000963
964 jpegr_compressed_struct jpegR;
Dichen Zhang7e3ed122022-12-14 22:05:01 +0000965 jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
Dichen Zhang54444382022-12-07 20:57:49 +0000966 jpegR.data = malloc(jpegR.maxLength);
Dichen Zhang761b52d2023-02-10 22:38:38 +0000967 ret = jpegRCodec.encodeJPEGR(
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000968 &mRawP010Image, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
Dichen Zhang7e3ed122022-12-14 22:05:01 +0000969 DEFAULT_JPEG_QUALITY, nullptr);
Dichen Zhang54444382022-12-07 20:57:49 +0000970 if (ret != OK) {
971 FAIL() << "Error code is " << ret;
972 }
973 if (SAVE_ENCODING_RESULT) {
974 // Output image data to file
Dichen Zhang61ede362023-02-22 18:50:13 +0000975 std::string filePath = "/sdcard/Documents/encoded_from_p010_yuv420p_input.jpgr";
Dichen Zhang54444382022-12-07 20:57:49 +0000976 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
977 if (!imageFile.is_open()) {
978 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
979 }
980 imageFile.write((const char*)jpegR.data, jpegR.length);
981 }
982
983 jpegr_uncompressed_struct decodedJpegR;
Dichen Zhang3e5798c2023-03-01 22:30:43 +0000984 int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
Dichen Zhang54444382022-12-07 20:57:49 +0000985 decodedJpegR.data = malloc(decodedJpegRSize);
Dichen Zhang761b52d2023-02-10 22:38:38 +0000986 ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
Dichen Zhang54444382022-12-07 20:57:49 +0000987 if (ret != OK) {
988 FAIL() << "Error code is " << ret;
989 }
990 if (SAVE_DECODING_RESULT) {
991 // Output image data to file
Dichen Zhang3e5798c2023-03-01 22:30:43 +0000992 std::string filePath = "/sdcard/Documents/decoded_from_p010_yuv420p_input.rgb";
Dichen Zhang54444382022-12-07 20:57:49 +0000993 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
994 if (!imageFile.is_open()) {
995 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
996 }
997 imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
998 }
999
1000 free(jpegR.data);
1001 free(decodedJpegR.data);
1002}
1003
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001004/* Test Encode API-2 and decode */
Dichen Zhang761b52d2023-02-10 22:38:38 +00001005TEST_F(JpegRTest, encodeFromRawHdrAndSdrAndJpegThenDecode) {
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001006 int ret;
1007
1008 // Load input files.
1009 if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
1010 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1011 }
1012 mRawP010Image.width = TEST_IMAGE_WIDTH;
1013 mRawP010Image.height = TEST_IMAGE_HEIGHT;
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001014 mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001015
1016 if (!loadFile(RAW_YUV420_IMAGE, mRawYuv420Image.data, nullptr)) {
1017 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1018 }
1019 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
1020 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001021 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001022
1023 if (!loadFile(JPEG_IMAGE, mJpegImage.data, &mJpegImage.length)) {
1024 FAIL() << "Load file " << JPEG_IMAGE << " failed";
1025 }
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001026 mJpegImage.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001027
Dichen Zhang761b52d2023-02-10 22:38:38 +00001028 JpegR jpegRCodec;
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001029
1030 jpegr_compressed_struct jpegR;
1031 jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
1032 jpegR.data = malloc(jpegR.maxLength);
Dichen Zhang761b52d2023-02-10 22:38:38 +00001033 ret = jpegRCodec.encodeJPEGR(
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001034 &mRawP010Image, &mRawYuv420Image, &mJpegImage, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1035 &jpegR);
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001036 if (ret != OK) {
1037 FAIL() << "Error code is " << ret;
1038 }
1039 if (SAVE_ENCODING_RESULT) {
1040 // Output image data to file
Dichen Zhang61ede362023-02-22 18:50:13 +00001041 std::string filePath = "/sdcard/Documents/encoded_from_p010_yuv420p_jpeg_input.jpgr";
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001042 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1043 if (!imageFile.is_open()) {
1044 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1045 }
1046 imageFile.write((const char*)jpegR.data, jpegR.length);
1047 }
1048
1049 jpegr_uncompressed_struct decodedJpegR;
Dichen Zhang3e5798c2023-03-01 22:30:43 +00001050 int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001051 decodedJpegR.data = malloc(decodedJpegRSize);
Dichen Zhang761b52d2023-02-10 22:38:38 +00001052 ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001053 if (ret != OK) {
1054 FAIL() << "Error code is " << ret;
1055 }
1056 if (SAVE_DECODING_RESULT) {
1057 // Output image data to file
Dichen Zhang3e5798c2023-03-01 22:30:43 +00001058 std::string filePath = "/sdcard/Documents/decoded_from_p010_yuv420p_jpeg_input.rgb";
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001059 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1060 if (!imageFile.is_open()) {
1061 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1062 }
1063 imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
1064 }
1065
1066 free(jpegR.data);
1067 free(decodedJpegR.data);
1068}
1069
1070/* Test Encode API-3 and decode */
Dichen Zhang761b52d2023-02-10 22:38:38 +00001071TEST_F(JpegRTest, encodeFromJpegThenDecode) {
Dichen Zhang36c1e732022-11-23 01:25:34 +00001072 int ret;
1073
1074 // Load input files.
1075 if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
1076 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1077 }
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001078 mRawP010Image.width = TEST_IMAGE_WIDTH;
1079 mRawP010Image.height = TEST_IMAGE_HEIGHT;
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001080 mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
Dichen Zhang36c1e732022-11-23 01:25:34 +00001081
Harish Mahendrakar1e057282022-12-04 12:47:53 -08001082 if (SAVE_INPUT_RGBA) {
1083 size_t rgbaSize = mRawP010Image.width * mRawP010Image.height * sizeof(uint32_t);
1084 uint32_t *data = (uint32_t *)malloc(rgbaSize);
1085
1086 for (size_t y = 0; y < mRawP010Image.height; ++y) {
1087 for (size_t x = 0; x < mRawP010Image.width; ++x) {
1088 Color hdr_yuv_gamma = getP010Pixel(&mRawP010Image, x, y);
1089 Color hdr_rgb_gamma = bt2100YuvToRgb(hdr_yuv_gamma);
1090 uint32_t rgba1010102 = colorToRgba1010102(hdr_rgb_gamma);
1091 size_t pixel_idx = x + y * mRawP010Image.width;
1092 reinterpret_cast<uint32_t*>(data)[pixel_idx] = rgba1010102;
1093 }
1094 }
1095
1096 // Output image data to file
1097 std::string filePath = "/sdcard/Documents/input_from_p010.rgb10";
1098 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1099 if (!imageFile.is_open()) {
1100 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1101 }
1102 imageFile.write((const char*)data, rgbaSize);
1103 free(data);
1104 }
Dichen Zhang36c1e732022-11-23 01:25:34 +00001105 if (!loadFile(JPEG_IMAGE, mJpegImage.data, &mJpegImage.length)) {
1106 FAIL() << "Load file " << JPEG_IMAGE << " failed";
1107 }
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001108 mJpegImage.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
Dichen Zhang36c1e732022-11-23 01:25:34 +00001109
Dichen Zhang761b52d2023-02-10 22:38:38 +00001110 JpegR jpegRCodec;
Dichen Zhang36c1e732022-11-23 01:25:34 +00001111
1112 jpegr_compressed_struct jpegR;
Dichen Zhang7e3ed122022-12-14 22:05:01 +00001113 jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
Dichen Zhang36c1e732022-11-23 01:25:34 +00001114 jpegR.data = malloc(jpegR.maxLength);
Dichen Zhang761b52d2023-02-10 22:38:38 +00001115 ret = jpegRCodec.encodeJPEGR(
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001116 &mRawP010Image, &mJpegImage, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR);
Dichen Zhang36c1e732022-11-23 01:25:34 +00001117 if (ret != OK) {
1118 FAIL() << "Error code is " << ret;
1119 }
1120 if (SAVE_ENCODING_RESULT) {
1121 // Output image data to file
Dichen Zhang61ede362023-02-22 18:50:13 +00001122 std::string filePath = "/sdcard/Documents/encoded_from_p010_jpeg_input.jpgr";
Dichen Zhang36c1e732022-11-23 01:25:34 +00001123 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1124 if (!imageFile.is_open()) {
1125 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1126 }
1127 imageFile.write((const char*)jpegR.data, jpegR.length);
1128 }
1129
1130 jpegr_uncompressed_struct decodedJpegR;
Dichen Zhang3e5798c2023-03-01 22:30:43 +00001131 int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
Dichen Zhang36c1e732022-11-23 01:25:34 +00001132 decodedJpegR.data = malloc(decodedJpegRSize);
Dichen Zhang761b52d2023-02-10 22:38:38 +00001133 ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
Dichen Zhang36c1e732022-11-23 01:25:34 +00001134 if (ret != OK) {
1135 FAIL() << "Error code is " << ret;
1136 }
1137 if (SAVE_DECODING_RESULT) {
1138 // Output image data to file
Dichen Zhang3e5798c2023-03-01 22:30:43 +00001139 std::string filePath = "/sdcard/Documents/decoded_from_p010_jpeg_input.rgb";
Dichen Zhang36c1e732022-11-23 01:25:34 +00001140 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1141 if (!imageFile.is_open()) {
1142 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1143 }
1144 imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
1145 }
1146
1147 free(jpegR.data);
1148 free(decodedJpegR.data);
1149}
1150
Dichen Zhang10959a42023-04-10 16:28:16 -07001151TEST_F(JpegRTest, ProfileGainMapFuncs) {
Nick Deakind19e5762023-02-10 15:39:08 -05001152 const size_t kWidth = TEST_IMAGE_WIDTH;
1153 const size_t kHeight = TEST_IMAGE_HEIGHT;
1154
1155 // Load input files.
1156 if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
1157 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1158 }
1159 mRawP010Image.width = kWidth;
1160 mRawP010Image.height = kHeight;
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001161 mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
Nick Deakind19e5762023-02-10 15:39:08 -05001162
1163 if (!loadFile(RAW_YUV420_IMAGE, mRawYuv420Image.data, nullptr)) {
1164 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1165 }
1166 mRawYuv420Image.width = kWidth;
1167 mRawYuv420Image.height = kHeight;
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001168 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
Nick Deakind19e5762023-02-10 15:39:08 -05001169
Dichen Zhang761b52d2023-02-10 22:38:38 +00001170 JpegRBenchmark benchmark;
Nick Deakind19e5762023-02-10 15:39:08 -05001171
Nick Deakin05ceebf2023-04-19 15:27:13 -04001172 ultrahdr_metadata_struct metadata = { .version = "1.0",
Nick Deakind19e5762023-02-10 15:39:08 -05001173 .maxContentBoost = 8.0f,
1174 .minContentBoost = 1.0f / 8.0f };
1175
1176 jpegr_uncompressed_struct map = { .data = NULL,
1177 .width = 0,
1178 .height = 0,
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001179 .colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED };
Nick Deakind19e5762023-02-10 15:39:08 -05001180
Dichen Zhang10959a42023-04-10 16:28:16 -07001181 benchmark.BenchmarkGenerateGainMap(&mRawYuv420Image, &mRawP010Image, &metadata, &map);
Nick Deakind19e5762023-02-10 15:39:08 -05001182
1183 const int dstSize = mRawYuv420Image.width * mRawYuv420Image.height * 4;
1184 auto bufferDst = std::make_unique<uint8_t[]>(dstSize);
1185 jpegr_uncompressed_struct dest = { .data = bufferDst.get(),
1186 .width = 0,
1187 .height = 0,
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001188 .colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED };
Nick Deakind19e5762023-02-10 15:39:08 -05001189
Dichen Zhang10959a42023-04-10 16:28:16 -07001190 benchmark.BenchmarkApplyGainMap(&mRawYuv420Image, &map, &metadata, &dest);
Nick Deakind19e5762023-02-10 15:39:08 -05001191}
1192
Dichen Zhangdbceb0e2023-04-14 19:03:18 +00001193} // namespace android::ultrahdr