1 /*
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
17 #include <ultrahdr/jpegr.h>
18 #include <ultrahdr/jpegrutils.h>
19 #include <ultrahdr/gainmapmath.h>
20 #include <fcntl.h>
21 #include <fstream>
22 #include <gtest/gtest.h>
23 #include <sys/time.h>
24 #include <utils/Log.h>
25
26 #define RAW_P010_IMAGE "/sdcard/Documents/raw_p010_image.p010"
27 #define RAW_P010_IMAGE_WITH_STRIDE "/sdcard/Documents/raw_p010_image_with_stride.p010"
28 #define RAW_YUV420_IMAGE "/sdcard/Documents/raw_yuv420_image.yuv420"
29 #define JPEG_IMAGE "/sdcard/Documents/jpeg_image.jpg"
30 #define TEST_IMAGE_WIDTH 1280
31 #define TEST_IMAGE_HEIGHT 720
32 #define TEST_IMAGE_STRIDE 1288
33 #define DEFAULT_JPEG_QUALITY 90
34
35 #define SAVE_ENCODING_RESULT true
36 #define SAVE_DECODING_RESULT true
37 #define SAVE_INPUT_RGBA true
38
39 namespace android::ultrahdr {
40
41 struct Timer {
42 struct timeval StartingTime;
43 struct timeval EndingTime;
44 struct timeval ElapsedMicroseconds;
45 };
46
timerStart(Timer * t)47 void timerStart(Timer *t) {
48 gettimeofday(&t->StartingTime, nullptr);
49 }
50
timerStop(Timer * t)51 void timerStop(Timer *t) {
52 gettimeofday(&t->EndingTime, nullptr);
53 }
54
elapsedTime(Timer * t)55 int64_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;
59 }
60
getFileSize(int fd)61 static 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
loadFile(const char filename[],void * & result,int * fileLength)70 static 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 }
91
loadP010Image(const char * filename,jr_uncompressed_ptr img,bool isUVContiguous)92 static bool loadP010Image(const char *filename, jr_uncompressed_ptr img,
93 bool isUVContiguous) {
94 int fd = open(filename, O_CLOEXEC);
95 if (fd < 0) {
96 return false;
97 }
98 const int bpp = 2;
99 int lumaStride = img->luma_stride == 0 ? img->width : img->luma_stride;
100 int lumaSize = bpp * lumaStride * img->height;
101 int chromaSize = bpp * (img->height / 2) *
102 (isUVContiguous ? lumaStride : img->chroma_stride);
103 img->data = malloc(lumaSize + (isUVContiguous ? chromaSize : 0));
104 if (img->data == nullptr) {
105 ALOGE("loadP010Image(): failed to allocate memory for luma data.");
106 return false;
107 }
108 uint8_t *mem = static_cast<uint8_t *>(img->data);
109 for (int i = 0; i < img->height; i++) {
110 if (read(fd, mem, img->width * bpp) != img->width * bpp) {
111 close(fd);
112 return false;
113 }
114 mem += lumaStride * bpp;
115 }
116 int chromaStride = lumaStride;
117 if (!isUVContiguous) {
118 img->chroma_data = malloc(chromaSize);
119 if (img->chroma_data == nullptr) {
120 ALOGE("loadP010Image(): failed to allocate memory for chroma data.");
121 return false;
122 }
123 mem = static_cast<uint8_t *>(img->chroma_data);
124 chromaStride = img->chroma_stride;
125 }
126 for (int i = 0; i < img->height / 2; i++) {
127 if (read(fd, mem, img->width * bpp) != img->width * bpp) {
128 close(fd);
129 return false;
130 }
131 mem += chromaStride * bpp;
132 }
133 close(fd);
134 return true;
135 }
136
137 class JpegRTest : public testing::Test {
138 public:
139 JpegRTest();
140 ~JpegRTest();
141
142 protected:
143 virtual void SetUp();
144 virtual void TearDown();
145
146 struct jpegr_uncompressed_struct mRawP010Image{};
147 struct jpegr_uncompressed_struct mRawP010ImageWithStride{};
148 struct jpegr_uncompressed_struct mRawP010ImageWithChromaData{};
149 struct jpegr_uncompressed_struct mRawYuv420Image{};
150 struct jpegr_compressed_struct mJpegImage{};
151 };
152
JpegRTest()153 JpegRTest::JpegRTest() {}
~JpegRTest()154 JpegRTest::~JpegRTest() {}
155
SetUp()156 void JpegRTest::SetUp() {}
TearDown()157 void JpegRTest::TearDown() {
158 free(mRawP010Image.data);
159 free(mRawP010Image.chroma_data);
160 free(mRawP010ImageWithStride.data);
161 free(mRawP010ImageWithStride.chroma_data);
162 free(mRawP010ImageWithChromaData.data);
163 free(mRawP010ImageWithChromaData.chroma_data);
164 free(mRawYuv420Image.data);
165 free(mJpegImage.data);
166 }
167
168 class JpegRBenchmark : public JpegR {
169 public:
170 void BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr p010Image,
171 ultrahdr_metadata_ptr metadata, jr_uncompressed_ptr map);
172 void BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr map,
173 ultrahdr_metadata_ptr metadata, jr_uncompressed_ptr dest);
174 private:
175 const int kProfileCount = 10;
176 };
177
BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image,jr_uncompressed_ptr p010Image,ultrahdr_metadata_ptr metadata,jr_uncompressed_ptr map)178 void JpegRBenchmark::BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image,
179 jr_uncompressed_ptr p010Image,
180 ultrahdr_metadata_ptr metadata,
181 jr_uncompressed_ptr map) {
182 ASSERT_EQ(yuv420Image->width, p010Image->width);
183 ASSERT_EQ(yuv420Image->height, p010Image->height);
184
185 Timer genRecMapTime;
186
187 timerStart(&genRecMapTime);
188 for (auto i = 0; i < kProfileCount; i++) {
189 ASSERT_EQ(OK, generateGainMap(
190 yuv420Image, p010Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, metadata, map));
191 if (i != kProfileCount - 1) delete[] static_cast<uint8_t *>(map->data);
192 }
193 timerStop(&genRecMapTime);
194
195 ALOGE("Generate Gain Map:- Res = %i x %i, time = %f ms",
196 yuv420Image->width, yuv420Image->height,
197 elapsedTime(&genRecMapTime) / (kProfileCount * 1000.f));
198
199 }
200
BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image,jr_uncompressed_ptr map,ultrahdr_metadata_ptr metadata,jr_uncompressed_ptr dest)201 void JpegRBenchmark::BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image,
202 jr_uncompressed_ptr map,
203 ultrahdr_metadata_ptr metadata,
204 jr_uncompressed_ptr dest) {
205 Timer applyRecMapTime;
206
207 timerStart(&applyRecMapTime);
208 for (auto i = 0; i < kProfileCount; i++) {
209 ASSERT_EQ(OK, applyGainMap(yuv420Image, map, metadata, ULTRAHDR_OUTPUT_HDR_HLG,
210 metadata->maxContentBoost /* displayBoost */, dest));
211 }
212 timerStop(&applyRecMapTime);
213
214 ALOGE("Apply Gain Map:- Res = %i x %i, time = %f ms",
215 yuv420Image->width, yuv420Image->height,
216 elapsedTime(&applyRecMapTime) / (kProfileCount * 1000.f));
217 }
218
TEST_F(JpegRTest,build)219 TEST_F(JpegRTest, build) {
220 // Force all of the gain map lib to be linked by calling all public functions.
221 JpegR jpegRCodec;
222 jpegRCodec.encodeJPEGR(nullptr, static_cast<ultrahdr_transfer_function>(0), nullptr, 0, nullptr);
223 jpegRCodec.encodeJPEGR(nullptr, nullptr, static_cast<ultrahdr_transfer_function>(0),
224 nullptr, 0, nullptr);
225 jpegRCodec.encodeJPEGR(nullptr, nullptr, nullptr, static_cast<ultrahdr_transfer_function>(0),
226 nullptr);
227 jpegRCodec.encodeJPEGR(nullptr, nullptr, static_cast<ultrahdr_transfer_function>(0), nullptr);
228 jpegRCodec.decodeJPEGR(nullptr, nullptr);
229 }
230
231 /* Test Encode API-0 invalid arguments */
TEST_F(JpegRTest,encodeAPI0ForInvalidArgs)232 TEST_F(JpegRTest, encodeAPI0ForInvalidArgs) {
233 int ret;
234
235 // we are not really compressing anything so lets keep allocs to a minimum
236 jpegr_compressed_struct jpegR;
237 jpegR.maxLength = 16 * sizeof(uint8_t);
238 jpegR.data = malloc(jpegR.maxLength);
239
240 JpegR jpegRCodec;
241
242 // we are not really compressing anything so lets keep allocs to a minimum
243 mRawP010ImageWithStride.data = malloc(16);
244 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
245 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
246 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
247 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
248
249 // test quality factor
250 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
251 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
252 -1, nullptr)) << "fail, API allows bad jpeg quality factor";
253
254 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
255 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
256 101, nullptr)) << "fail, API allows bad jpeg quality factor";
257
258 // test hdr transfer function
259 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
260 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED, &jpegR,
261 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
262
263 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
264 &mRawP010ImageWithStride,
265 static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
266 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
267
268 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
269 &mRawP010ImageWithStride,
270 static_cast<ultrahdr_transfer_function>(-10),
271 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
272
273 // test dest
274 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
275 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr,
276 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr dest";
277
278 // test p010 input
279 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
280 nullptr, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
281 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr p010 image";
282
283 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
284 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
285 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
286 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
287 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
288 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
289
290 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
291 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
292 mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
293 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
294 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
295 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
296 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
297
298 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
299 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
300 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
301 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
302 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
303 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
304
305 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
306 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
307 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
308 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
309 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
310
311 mRawP010ImageWithStride.width = 0;
312 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
313 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
314 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
315 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
316
317 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
318 mRawP010ImageWithStride.height = 0;
319 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
320 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
321 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
322
323 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
324 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
325 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
326 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
327 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
328 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad luma stride";
329
330 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
331 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
332 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
333 mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
334 mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
335 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
336 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
337 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad chroma stride";
338
339 mRawP010ImageWithStride.chroma_data = nullptr;
340
341 free(jpegR.data);
342 }
343
344 /* Test Encode API-1 invalid arguments */
TEST_F(JpegRTest,encodeAPI1ForInvalidArgs)345 TEST_F(JpegRTest, encodeAPI1ForInvalidArgs) {
346 int ret;
347
348 // we are not really compressing anything so lets keep allocs to a minimum
349 jpegr_compressed_struct jpegR;
350 jpegR.maxLength = 16 * sizeof(uint8_t);
351 jpegR.data = malloc(jpegR.maxLength);
352
353 JpegR jpegRCodec;
354
355 // we are not really compressing anything so lets keep allocs to a minimum
356 mRawP010ImageWithStride.data = malloc(16);
357 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
358 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
359 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
360 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
361
362 // we are not really compressing anything so lets keep allocs to a minimum
363 mRawYuv420Image.data = malloc(16);
364 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
365 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
366 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
367
368 // test quality factor
369 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
370 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
371 &jpegR, -1, nullptr)) << "fail, API allows bad jpeg quality factor";
372
373 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
374 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
375 &jpegR, 101, nullptr)) << "fail, API allows bad jpeg quality factor";
376
377 // test hdr transfer function
378 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
379 &mRawP010ImageWithStride, &mRawYuv420Image,
380 ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED, &jpegR, DEFAULT_JPEG_QUALITY,
381 nullptr)) << "fail, API allows bad hdr transfer function";
382
383 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
384 &mRawP010ImageWithStride, &mRawYuv420Image,
385 static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
386 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
387
388 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
389 &mRawP010ImageWithStride, &mRawYuv420Image,
390 static_cast<ultrahdr_transfer_function>(-10),
391 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad hdr transfer function";
392
393 // test dest
394 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
395 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
396 nullptr, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr dest";
397
398 // test p010 input
399 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
400 nullptr, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
401 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr p010 image";
402
403 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
404 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
405 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
406 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
407 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
408 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
409
410 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
411 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
412 mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
413 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
414 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
415 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
416 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad p010 color gamut";
417
418 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
419 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
420 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
421 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
422 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
423 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
424
425 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
426 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
427 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
428 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
429 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
430
431 mRawP010ImageWithStride.width = 0;
432 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
433 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
434 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
435 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image width";
436
437 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
438 mRawP010ImageWithStride.height = 0;
439 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
440 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
441 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad image height";
442
443 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
444 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
445 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
446 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
447 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
448 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad luma stride";
449
450 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
451 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
452 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
453 mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
454 mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
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 chroma stride";
458
459 // test 420 input
460 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
461 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
462 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
463 mRawP010ImageWithStride.chroma_data = nullptr;
464 mRawP010ImageWithStride.chroma_stride = 0;
465 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
466 &mRawP010ImageWithStride, nullptr, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
467 DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows nullptr for 420 image";
468
469 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
470 mRawYuv420Image.height = TEST_IMAGE_HEIGHT - 2;
471 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
472 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
473 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 image width";
474
475 mRawYuv420Image.width = TEST_IMAGE_WIDTH - 2;
476 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
477 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
478 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
479 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 image height";
480
481 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
482 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
483 mRawYuv420Image.luma_stride = TEST_IMAGE_STRIDE;
484 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
485 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
486 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad luma stride for 420";
487
488 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
489 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
490 mRawYuv420Image.luma_stride = 0;
491 mRawYuv420Image.chroma_data = mRawYuv420Image.data;
492 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
493 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
494 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows chroma pointer for 420";
495
496 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
497 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
498 mRawYuv420Image.luma_stride = 0;
499 mRawYuv420Image.chroma_data = nullptr;
500 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
501 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
502 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
503 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 color gamut";
504
505 mRawYuv420Image.colorGamut = static_cast<ultrahdr_color_gamut>(
506 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
507 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
508 &mRawP010ImageWithStride, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
509 &jpegR, DEFAULT_JPEG_QUALITY, nullptr)) << "fail, API allows bad 420 color gamut";
510
511 free(jpegR.data);
512 }
513
514 /* Test Encode API-2 invalid arguments */
TEST_F(JpegRTest,encodeAPI2ForInvalidArgs)515 TEST_F(JpegRTest, encodeAPI2ForInvalidArgs) {
516 int ret;
517
518 // we are not really compressing anything so lets keep allocs to a minimum
519 jpegr_compressed_struct jpegR;
520 jpegR.maxLength = 16 * sizeof(uint8_t);
521 jpegR.data = malloc(jpegR.maxLength);
522
523 JpegR jpegRCodec;
524
525 // we are not really compressing anything so lets keep allocs to a minimum
526 mRawP010ImageWithStride.data = malloc(16);
527 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
528 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
529 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
530 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
531
532 // we are not really compressing anything so lets keep allocs to a minimum
533 mRawYuv420Image.data = malloc(16);
534 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
535 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
536 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
537
538 // test hdr transfer function
539 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
540 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
541 ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
542 &jpegR)) << "fail, API allows bad hdr transfer function";
543
544 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
545 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
546 static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
547 &jpegR)) << "fail, API allows bad hdr transfer function";
548
549 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
550 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
551 static_cast<ultrahdr_transfer_function>(-10),
552 &jpegR)) << "fail, API allows bad hdr transfer function";
553
554 // test dest
555 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
556 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
557 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr)) << "fail, API allows nullptr dest";
558
559 // test p010 input
560 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
561 nullptr, &mRawYuv420Image, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
562 &jpegR)) << "fail, API allows nullptr p010 image";
563
564 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
565 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
566 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
567 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
568 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
569 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
570 &jpegR)) << "fail, API allows bad p010 color gamut";
571
572 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
573 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
574 mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
575 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
576 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
577 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
578 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
579 &jpegR)) << "fail, API allows bad p010 color gamut";
580
581 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
582 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
583 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
584 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
585 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
586 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image width";
587
588 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
589 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
590 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
591 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
592 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image height";
593
594 mRawP010ImageWithStride.width = 0;
595 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
596 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
597 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
598 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image width";
599
600 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
601 mRawP010ImageWithStride.height = 0;
602 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
603 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
604 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad image height";
605
606 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
607 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
608 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
609 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
610 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
611 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR)) << "fail, API allows bad luma stride";
612
613 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
614 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
615 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
616 mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
617 mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
618 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
619 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
620 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
621 &jpegR)) << "fail, API allows bad chroma stride";
622
623 // test 420 input
624 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
625 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
626 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
627 mRawP010ImageWithStride.chroma_data = nullptr;
628 mRawP010ImageWithStride.chroma_stride = 0;
629 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
630 &mRawP010ImageWithStride, nullptr, &jpegR,
631 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
632 &jpegR)) << "fail, API allows nullptr for 420 image";
633
634 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
635 mRawYuv420Image.height = TEST_IMAGE_HEIGHT - 2;
636 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
637 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
638 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
639 &jpegR)) << "fail, API allows bad 420 image width";
640
641 mRawYuv420Image.width = TEST_IMAGE_WIDTH - 2;
642 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
643 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
644 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
645 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
646 &jpegR)) << "fail, API allows bad 420 image height";
647
648 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
649 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
650 mRawYuv420Image.luma_stride = TEST_IMAGE_STRIDE;
651 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
652 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
653 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
654 &jpegR)) << "fail, API allows bad luma stride for 420";
655
656 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
657 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
658 mRawYuv420Image.luma_stride = 0;
659 mRawYuv420Image.chroma_data = mRawYuv420Image.data;
660 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
661 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
662 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
663 &jpegR)) << "fail, API allows chroma pointer for 420";
664
665 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
666 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
667 mRawYuv420Image.luma_stride = 0;
668 mRawYuv420Image.chroma_data = nullptr;
669 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
670 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
671 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
672 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
673 &jpegR)) << "fail, API allows bad 420 color gamut";
674
675 mRawYuv420Image.colorGamut = static_cast<ultrahdr_color_gamut>(
676 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
677 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
678 &mRawP010ImageWithStride, &mRawYuv420Image, &jpegR,
679 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
680 &jpegR)) << "fail, API allows bad 420 color gamut";
681
682 // bad compressed image
683 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
684 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
685 &mRawP010ImageWithStride, &mRawYuv420Image, nullptr,
686 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
687 &jpegR)) << "fail, API allows bad 420 color gamut";
688
689 free(jpegR.data);
690 }
691
692 /* Test Encode API-3 invalid arguments */
TEST_F(JpegRTest,encodeAPI3ForInvalidArgs)693 TEST_F(JpegRTest, encodeAPI3ForInvalidArgs) {
694 int ret;
695
696 // we are not really compressing anything so lets keep allocs to a minimum
697 jpegr_compressed_struct jpegR;
698 jpegR.maxLength = 16 * sizeof(uint8_t);
699 jpegR.data = malloc(jpegR.maxLength);
700
701 JpegR jpegRCodec;
702
703 // we are not really compressing anything so lets keep allocs to a minimum
704 mRawP010ImageWithStride.data = malloc(16);
705 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
706 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
707 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
708 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
709
710 // test hdr transfer function
711 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
712 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
713 &jpegR)) << "fail, API allows bad hdr transfer function";
714
715 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
716 &mRawP010ImageWithStride, &jpegR,
717 static_cast<ultrahdr_transfer_function>(ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
718 &jpegR)) << "fail, API allows bad hdr transfer function";
719
720 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
721 &mRawP010ImageWithStride, &jpegR, static_cast<ultrahdr_transfer_function>(-10),
722 &jpegR)) << "fail, API allows bad hdr transfer function";
723
724 // test dest
725 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
726 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
727 nullptr)) << "fail, API allows nullptr dest";
728
729 // test p010 input
730 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
731 nullptr, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
732 &jpegR)) << "fail, API allows nullptr p010 image";
733
734 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
735 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
736 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
737 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
738 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
739 &jpegR)) << "fail, API allows bad p010 color gamut";
740
741 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
742 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
743 mRawP010ImageWithStride.colorGamut = static_cast<ultrahdr_color_gamut>(
744 ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
745 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
746 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
747 &jpegR)) << "fail, API allows bad p010 color gamut";
748
749 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH - 1;
750 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
751 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
752 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
753 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
754 &jpegR)) << "fail, API allows bad image width";
755
756 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
757 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT - 1;
758 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
759 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
760 &jpegR)) << "fail, API allows bad image height";
761
762 mRawP010ImageWithStride.width = 0;
763 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
764 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
765 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
766 &jpegR)) << "fail, API allows bad image width";
767
768 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
769 mRawP010ImageWithStride.height = 0;
770 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
771 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
772 &jpegR)) << "fail, API allows bad image height";
773
774 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
775 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
776 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH - 2;
777 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
778 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
779 &jpegR)) << "fail, API allows bad luma stride";
780
781 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
782 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
783 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
784 mRawP010ImageWithStride.chroma_data = mRawP010ImageWithStride.data;
785 mRawP010ImageWithStride.chroma_stride = TEST_IMAGE_WIDTH - 2;
786 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
787 &mRawP010ImageWithStride, &jpegR, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
788 &jpegR)) << "fail, API allows bad chroma stride";
789 mRawP010ImageWithStride.chroma_data = nullptr;
790
791 // bad compressed image
792 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
793 &mRawP010ImageWithStride, nullptr, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
794 &jpegR)) << "fail, API allows bad 420 color gamut";
795
796 free(jpegR.data);
797 }
798
799 /* Test Encode API-4 invalid arguments */
TEST_F(JpegRTest,encodeAPI4ForInvalidArgs)800 TEST_F(JpegRTest, encodeAPI4ForInvalidArgs) {
801 int ret;
802
803 // we are not really compressing anything so lets keep allocs to a minimum
804 jpegr_compressed_struct jpegR;
805 jpegR.maxLength = 16 * sizeof(uint8_t);
806 jpegR.data = malloc(jpegR.maxLength);
807
808 JpegR jpegRCodec;
809
810 // test dest
811 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
812 &jpegR, &jpegR, nullptr, nullptr)) << "fail, API allows nullptr dest";
813
814 // test primary image
815 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
816 nullptr, &jpegR, nullptr, &jpegR)) << "fail, API allows nullptr primary image";
817
818 // test gain map
819 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
820 &jpegR, nullptr, nullptr, &jpegR)) << "fail, API allows nullptr gainmap image";
821
822 // test metadata
823 ultrahdr_metadata_struct good_metadata;
824 good_metadata.version = "1.0";
825 good_metadata.minContentBoost = 1.0f;
826 good_metadata.maxContentBoost = 2.0f;
827 good_metadata.gamma = 1.0f;
828 good_metadata.offsetSdr = 0.0f;
829 good_metadata.offsetHdr = 0.0f;
830 good_metadata.hdrCapacityMin = 1.0f;
831 good_metadata.hdrCapacityMax = 2.0f;
832
833 ultrahdr_metadata_struct metadata = good_metadata;
834 metadata.version = "1.1";
835 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
836 &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata version";
837
838 metadata = good_metadata;
839 metadata.minContentBoost = 3.0f;
840 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
841 &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata content boost";
842
843 metadata = good_metadata;
844 metadata.gamma = -0.1f;
845 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
846 &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata gamma";
847
848 metadata = good_metadata;
849 metadata.offsetSdr = -0.1f;
850 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
851 &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata offset sdr";
852
853 metadata = good_metadata;
854 metadata.offsetHdr = -0.1f;
855 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
856 &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata offset hdr";
857
858 metadata = good_metadata;
859 metadata.hdrCapacityMax = 0.5f;
860 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
861 &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata hdr capacity max";
862
863 metadata = good_metadata;
864 metadata.hdrCapacityMin = 0.5f;
865 EXPECT_NE(OK, jpegRCodec.encodeJPEGR(
866 &jpegR, nullptr, &metadata, &jpegR)) << "fail, API allows bad metadata hdr capacity min";
867
868 free(jpegR.data);
869 }
870
871 /* Test Decode API invalid arguments */
TEST_F(JpegRTest,decodeAPIForInvalidArgs)872 TEST_F(JpegRTest, decodeAPIForInvalidArgs) {
873 int ret;
874
875 // we are not really compressing anything so lets keep allocs to a minimum
876 jpegr_compressed_struct jpegR;
877 jpegR.maxLength = 16 * sizeof(uint8_t);
878 jpegR.data = malloc(jpegR.maxLength);
879
880 // we are not really decoding anything so lets keep allocs to a minimum
881 mRawP010Image.data = malloc(16);
882
883 JpegR jpegRCodec;
884
885 // test jpegr image
886 EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
887 nullptr, &mRawP010Image)) << "fail, API allows nullptr for jpegr img";
888
889 // test dest image
890 EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
891 &jpegR, nullptr)) << "fail, API allows nullptr for dest";
892
893 // test max display boost
894 EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
895 &jpegR, &mRawP010Image, 0.5)) << "fail, API allows invalid max display boost";
896
897 // test output format
898 EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
899 &jpegR, &mRawP010Image, 0.5, nullptr,
900 static_cast<ultrahdr_output_format>(-1))) << "fail, API allows invalid output format";
901
902 EXPECT_NE(OK, jpegRCodec.decodeJPEGR(
903 &jpegR, &mRawP010Image, 0.5, nullptr,
904 static_cast<ultrahdr_output_format>(ULTRAHDR_OUTPUT_MAX + 1)))
905 << "fail, API allows invalid output format";
906
907 free(jpegR.data);
908 }
909
TEST_F(JpegRTest,writeXmpThenRead)910 TEST_F(JpegRTest, writeXmpThenRead) {
911 ultrahdr_metadata_struct metadata_expected;
912 metadata_expected.version = "1.0";
913 metadata_expected.maxContentBoost = 1.25f;
914 metadata_expected.minContentBoost = 0.75f;
915 metadata_expected.gamma = 1.0f;
916 metadata_expected.offsetSdr = 0.0f;
917 metadata_expected.offsetHdr = 0.0f;
918 metadata_expected.hdrCapacityMin = 1.0f;
919 metadata_expected.hdrCapacityMax = metadata_expected.maxContentBoost;
920 const std::string nameSpace = "http://ns.adobe.com/xap/1.0/\0";
921 const int nameSpaceLength = nameSpace.size() + 1; // need to count the null terminator
922
923 std::string xmp = generateXmpForSecondaryImage(metadata_expected);
924
925 std::vector<uint8_t> xmpData;
926 xmpData.reserve(nameSpaceLength + xmp.size());
927 xmpData.insert(xmpData.end(), reinterpret_cast<const uint8_t*>(nameSpace.c_str()),
928 reinterpret_cast<const uint8_t*>(nameSpace.c_str()) + nameSpaceLength);
929 xmpData.insert(xmpData.end(), reinterpret_cast<const uint8_t*>(xmp.c_str()),
930 reinterpret_cast<const uint8_t*>(xmp.c_str()) + xmp.size());
931
932 ultrahdr_metadata_struct metadata_read;
933 EXPECT_TRUE(getMetadataFromXMP(xmpData.data(), xmpData.size(), &metadata_read));
934 EXPECT_FLOAT_EQ(metadata_expected.maxContentBoost, metadata_read.maxContentBoost);
935 EXPECT_FLOAT_EQ(metadata_expected.minContentBoost, metadata_read.minContentBoost);
936 EXPECT_FLOAT_EQ(metadata_expected.gamma, metadata_read.gamma);
937 EXPECT_FLOAT_EQ(metadata_expected.offsetSdr, metadata_read.offsetSdr);
938 EXPECT_FLOAT_EQ(metadata_expected.offsetHdr, metadata_read.offsetHdr);
939 EXPECT_FLOAT_EQ(metadata_expected.hdrCapacityMin, metadata_read.hdrCapacityMin);
940 EXPECT_FLOAT_EQ(metadata_expected.hdrCapacityMax, metadata_read.hdrCapacityMax);
941 }
942
943 /* Test Encode API-0 */
TEST_F(JpegRTest,encodeFromP010)944 TEST_F(JpegRTest, encodeFromP010) {
945 int ret;
946
947 mRawP010Image.width = TEST_IMAGE_WIDTH;
948 mRawP010Image.height = TEST_IMAGE_HEIGHT;
949 mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
950 // Load input files.
951 if (!loadP010Image(RAW_P010_IMAGE, &mRawP010Image, true)) {
952 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
953 }
954
955 JpegR jpegRCodec;
956
957 jpegr_compressed_struct jpegR;
958 jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
959 jpegR.data = malloc(jpegR.maxLength);
960 ret = jpegRCodec.encodeJPEGR(
961 &mRawP010Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR, DEFAULT_JPEG_QUALITY,
962 nullptr);
963 if (ret != OK) {
964 FAIL() << "Error code is " << ret;
965 }
966
967 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
968 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
969 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_WIDTH + 128;
970 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
971 // Load input files.
972 if (!loadP010Image(RAW_P010_IMAGE, &mRawP010ImageWithStride, true)) {
973 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
974 }
975
976 jpegr_compressed_struct jpegRWithStride;
977 jpegRWithStride.maxLength = jpegR.length;
978 jpegRWithStride.data = malloc(jpegRWithStride.maxLength);
979 ret = jpegRCodec.encodeJPEGR(
980 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegRWithStride,
981 DEFAULT_JPEG_QUALITY, nullptr);
982 if (ret != OK) {
983 FAIL() << "Error code is " << ret;
984 }
985 ASSERT_EQ(jpegR.length, jpegRWithStride.length)
986 << "Same input is yielding different output";
987 ASSERT_EQ(0, memcmp(jpegR.data, jpegRWithStride.data, jpegR.length))
988 << "Same input is yielding different output";
989
990 mRawP010ImageWithChromaData.width = TEST_IMAGE_WIDTH;
991 mRawP010ImageWithChromaData.height = TEST_IMAGE_HEIGHT;
992 mRawP010ImageWithChromaData.luma_stride = TEST_IMAGE_WIDTH + 64;
993 mRawP010ImageWithChromaData.chroma_stride = TEST_IMAGE_WIDTH + 256;
994 mRawP010ImageWithChromaData.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
995 // Load input files.
996 if (!loadP010Image(RAW_P010_IMAGE, &mRawP010ImageWithChromaData, false)) {
997 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
998 }
999 jpegr_compressed_struct jpegRWithChromaData;
1000 jpegRWithChromaData.maxLength = jpegR.length;
1001 jpegRWithChromaData.data = malloc(jpegRWithChromaData.maxLength);
1002 ret = jpegRCodec.encodeJPEGR(
1003 &mRawP010ImageWithChromaData, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1004 &jpegRWithChromaData, DEFAULT_JPEG_QUALITY, nullptr);
1005 if (ret != OK) {
1006 FAIL() << "Error code is " << ret;
1007 }
1008 ASSERT_EQ(jpegR.length, jpegRWithChromaData.length)
1009 << "Same input is yielding different output";
1010 ASSERT_EQ(0, memcmp(jpegR.data, jpegRWithChromaData.data, jpegR.length))
1011 << "Same input is yielding different output";
1012
1013 free(jpegR.data);
1014 free(jpegRWithStride.data);
1015 free(jpegRWithChromaData.data);
1016 }
1017
1018 /* Test Encode API-0 and decode */
TEST_F(JpegRTest,encodeFromP010ThenDecode)1019 TEST_F(JpegRTest, encodeFromP010ThenDecode) {
1020 int ret;
1021
1022 // Load input files.
1023 if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
1024 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1025 }
1026 mRawP010Image.width = TEST_IMAGE_WIDTH;
1027 mRawP010Image.height = TEST_IMAGE_HEIGHT;
1028 mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
1029
1030 JpegR jpegRCodec;
1031
1032 jpegr_compressed_struct jpegR;
1033 jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
1034 jpegR.data = malloc(jpegR.maxLength);
1035 ret = jpegRCodec.encodeJPEGR(
1036 &mRawP010Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR, DEFAULT_JPEG_QUALITY,
1037 nullptr);
1038 if (ret != OK) {
1039 FAIL() << "Error code is " << ret;
1040 }
1041 if (SAVE_ENCODING_RESULT) {
1042 // Output image data to file
1043 std::string filePath = "/sdcard/Documents/encoded_from_p010_input.jpgr";
1044 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1045 if (!imageFile.is_open()) {
1046 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1047 }
1048 imageFile.write((const char*)jpegR.data, jpegR.length);
1049 }
1050
1051 jpegr_uncompressed_struct decodedJpegR;
1052 int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
1053 decodedJpegR.data = malloc(decodedJpegRSize);
1054 ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
1055 if (ret != OK) {
1056 FAIL() << "Error code is " << ret;
1057 }
1058 if (SAVE_DECODING_RESULT) {
1059 // Output image data to file
1060 std::string filePath = "/sdcard/Documents/decoded_from_p010_input.rgb";
1061 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1062 if (!imageFile.is_open()) {
1063 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1064 }
1065 imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
1066 }
1067
1068 free(jpegR.data);
1069 free(decodedJpegR.data);
1070 }
1071
1072 /* Test Encode API-0 (with stride) and decode */
TEST_F(JpegRTest,encodeFromP010WithStrideThenDecode)1073 TEST_F(JpegRTest, encodeFromP010WithStrideThenDecode) {
1074 int ret;
1075
1076 // Load input files.
1077 if (!loadFile(RAW_P010_IMAGE_WITH_STRIDE, mRawP010ImageWithStride.data, nullptr)) {
1078 FAIL() << "Load file " << RAW_P010_IMAGE_WITH_STRIDE << " failed";
1079 }
1080 mRawP010ImageWithStride.width = TEST_IMAGE_WIDTH;
1081 mRawP010ImageWithStride.height = TEST_IMAGE_HEIGHT;
1082 mRawP010ImageWithStride.luma_stride = TEST_IMAGE_STRIDE;
1083 mRawP010ImageWithStride.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
1084
1085 JpegR jpegRCodec;
1086
1087 jpegr_compressed_struct jpegR;
1088 jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
1089 jpegR.data = malloc(jpegR.maxLength);
1090 ret = jpegRCodec.encodeJPEGR(
1091 &mRawP010ImageWithStride, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
1092 DEFAULT_JPEG_QUALITY, nullptr);
1093 if (ret != OK) {
1094 FAIL() << "Error code is " << ret;
1095 }
1096 if (SAVE_ENCODING_RESULT) {
1097 // Output image data to file
1098 std::string filePath = "/sdcard/Documents/encoded_from_p010_input.jpgr";
1099 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1100 if (!imageFile.is_open()) {
1101 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1102 }
1103 imageFile.write((const char*)jpegR.data, jpegR.length);
1104 }
1105
1106 jpegr_uncompressed_struct decodedJpegR;
1107 int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
1108 decodedJpegR.data = malloc(decodedJpegRSize);
1109 ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
1110 if (ret != OK) {
1111 FAIL() << "Error code is " << ret;
1112 }
1113 if (SAVE_DECODING_RESULT) {
1114 // Output image data to file
1115 std::string filePath = "/sdcard/Documents/decoded_from_p010_input.rgb";
1116 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1117 if (!imageFile.is_open()) {
1118 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1119 }
1120 imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
1121 }
1122
1123 free(jpegR.data);
1124 free(decodedJpegR.data);
1125 }
1126
1127 /* Test Encode API-1 and decode */
TEST_F(JpegRTest,encodeFromRawHdrAndSdrThenDecode)1128 TEST_F(JpegRTest, encodeFromRawHdrAndSdrThenDecode) {
1129 int ret;
1130
1131 // Load input files.
1132 if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
1133 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1134 }
1135 mRawP010Image.width = TEST_IMAGE_WIDTH;
1136 mRawP010Image.height = TEST_IMAGE_HEIGHT;
1137 mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
1138
1139 if (!loadFile(RAW_YUV420_IMAGE, mRawYuv420Image.data, nullptr)) {
1140 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1141 }
1142 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
1143 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
1144 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
1145
1146 JpegR jpegRCodec;
1147
1148 jpegr_compressed_struct jpegR;
1149 jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
1150 jpegR.data = malloc(jpegR.maxLength);
1151 ret = jpegRCodec.encodeJPEGR(
1152 &mRawP010Image, &mRawYuv420Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR,
1153 DEFAULT_JPEG_QUALITY, nullptr);
1154 if (ret != OK) {
1155 FAIL() << "Error code is " << ret;
1156 }
1157 if (SAVE_ENCODING_RESULT) {
1158 // Output image data to file
1159 std::string filePath = "/sdcard/Documents/encoded_from_p010_yuv420p_input.jpgr";
1160 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1161 if (!imageFile.is_open()) {
1162 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1163 }
1164 imageFile.write((const char*)jpegR.data, jpegR.length);
1165 }
1166
1167 jpegr_uncompressed_struct decodedJpegR;
1168 int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
1169 decodedJpegR.data = malloc(decodedJpegRSize);
1170 ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
1171 if (ret != OK) {
1172 FAIL() << "Error code is " << ret;
1173 }
1174 if (SAVE_DECODING_RESULT) {
1175 // Output image data to file
1176 std::string filePath = "/sdcard/Documents/decoded_from_p010_yuv420p_input.rgb";
1177 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1178 if (!imageFile.is_open()) {
1179 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1180 }
1181 imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
1182 }
1183
1184 free(jpegR.data);
1185 free(decodedJpegR.data);
1186 }
1187
1188 /* Test Encode API-2 and decode */
TEST_F(JpegRTest,encodeFromRawHdrAndSdrAndJpegThenDecode)1189 TEST_F(JpegRTest, encodeFromRawHdrAndSdrAndJpegThenDecode) {
1190 int ret;
1191
1192 // Load input files.
1193 if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
1194 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1195 }
1196 mRawP010Image.width = TEST_IMAGE_WIDTH;
1197 mRawP010Image.height = TEST_IMAGE_HEIGHT;
1198 mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
1199
1200 if (!loadFile(RAW_YUV420_IMAGE, mRawYuv420Image.data, nullptr)) {
1201 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1202 }
1203 mRawYuv420Image.width = TEST_IMAGE_WIDTH;
1204 mRawYuv420Image.height = TEST_IMAGE_HEIGHT;
1205 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
1206
1207 if (!loadFile(JPEG_IMAGE, mJpegImage.data, &mJpegImage.length)) {
1208 FAIL() << "Load file " << JPEG_IMAGE << " failed";
1209 }
1210 mJpegImage.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
1211
1212 JpegR jpegRCodec;
1213
1214 jpegr_compressed_struct jpegR;
1215 jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
1216 jpegR.data = malloc(jpegR.maxLength);
1217 ret = jpegRCodec.encodeJPEGR(
1218 &mRawP010Image, &mRawYuv420Image, &mJpegImage, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1219 &jpegR);
1220 if (ret != OK) {
1221 FAIL() << "Error code is " << ret;
1222 }
1223 if (SAVE_ENCODING_RESULT) {
1224 // Output image data to file
1225 std::string filePath = "/sdcard/Documents/encoded_from_p010_yuv420p_jpeg_input.jpgr";
1226 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1227 if (!imageFile.is_open()) {
1228 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1229 }
1230 imageFile.write((const char*)jpegR.data, jpegR.length);
1231 }
1232
1233 jpegr_uncompressed_struct decodedJpegR;
1234 int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
1235 decodedJpegR.data = malloc(decodedJpegRSize);
1236 ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
1237 if (ret != OK) {
1238 FAIL() << "Error code is " << ret;
1239 }
1240 if (SAVE_DECODING_RESULT) {
1241 // Output image data to file
1242 std::string filePath = "/sdcard/Documents/decoded_from_p010_yuv420p_jpeg_input.rgb";
1243 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1244 if (!imageFile.is_open()) {
1245 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1246 }
1247 imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
1248 }
1249
1250 free(jpegR.data);
1251 free(decodedJpegR.data);
1252 }
1253
1254 /* Test Encode API-3 and decode */
TEST_F(JpegRTest,encodeFromJpegThenDecode)1255 TEST_F(JpegRTest, encodeFromJpegThenDecode) {
1256 int ret;
1257
1258 // Load input files.
1259 if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
1260 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1261 }
1262 mRawP010Image.width = TEST_IMAGE_WIDTH;
1263 mRawP010Image.height = TEST_IMAGE_HEIGHT;
1264 mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
1265
1266 if (SAVE_INPUT_RGBA) {
1267 size_t rgbaSize = mRawP010Image.width * mRawP010Image.height * sizeof(uint32_t);
1268 uint32_t *data = (uint32_t *)malloc(rgbaSize);
1269
1270 for (size_t y = 0; y < mRawP010Image.height; ++y) {
1271 for (size_t x = 0; x < mRawP010Image.width; ++x) {
1272 Color hdr_yuv_gamma = getP010Pixel(&mRawP010Image, x, y);
1273 Color hdr_rgb_gamma = bt2100YuvToRgb(hdr_yuv_gamma);
1274 uint32_t rgba1010102 = colorToRgba1010102(hdr_rgb_gamma);
1275 size_t pixel_idx = x + y * mRawP010Image.width;
1276 reinterpret_cast<uint32_t*>(data)[pixel_idx] = rgba1010102;
1277 }
1278 }
1279
1280 // Output image data to file
1281 std::string filePath = "/sdcard/Documents/input_from_p010.rgb10";
1282 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1283 if (!imageFile.is_open()) {
1284 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1285 }
1286 imageFile.write((const char*)data, rgbaSize);
1287 free(data);
1288 }
1289 if (!loadFile(JPEG_IMAGE, mJpegImage.data, &mJpegImage.length)) {
1290 FAIL() << "Load file " << JPEG_IMAGE << " failed";
1291 }
1292 mJpegImage.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
1293
1294 JpegR jpegRCodec;
1295
1296 jpegr_compressed_struct jpegR;
1297 jpegR.maxLength = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * sizeof(uint8_t);
1298 jpegR.data = malloc(jpegR.maxLength);
1299 ret = jpegRCodec.encodeJPEGR(
1300 &mRawP010Image, &mJpegImage, ultrahdr_transfer_function::ULTRAHDR_TF_HLG, &jpegR);
1301 if (ret != OK) {
1302 FAIL() << "Error code is " << ret;
1303 }
1304 if (SAVE_ENCODING_RESULT) {
1305 // Output image data to file
1306 std::string filePath = "/sdcard/Documents/encoded_from_p010_jpeg_input.jpgr";
1307 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1308 if (!imageFile.is_open()) {
1309 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1310 }
1311 imageFile.write((const char*)jpegR.data, jpegR.length);
1312 }
1313
1314 jpegr_uncompressed_struct decodedJpegR;
1315 int decodedJpegRSize = TEST_IMAGE_WIDTH * TEST_IMAGE_HEIGHT * 8;
1316 decodedJpegR.data = malloc(decodedJpegRSize);
1317 ret = jpegRCodec.decodeJPEGR(&jpegR, &decodedJpegR);
1318 if (ret != OK) {
1319 FAIL() << "Error code is " << ret;
1320 }
1321 if (SAVE_DECODING_RESULT) {
1322 // Output image data to file
1323 std::string filePath = "/sdcard/Documents/decoded_from_p010_jpeg_input.rgb";
1324 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1325 if (!imageFile.is_open()) {
1326 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1327 }
1328 imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
1329 }
1330
1331 free(jpegR.data);
1332 free(decodedJpegR.data);
1333 }
1334
TEST_F(JpegRTest,ProfileGainMapFuncs)1335 TEST_F(JpegRTest, ProfileGainMapFuncs) {
1336 const size_t kWidth = TEST_IMAGE_WIDTH;
1337 const size_t kHeight = TEST_IMAGE_HEIGHT;
1338
1339 // Load input files.
1340 if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
1341 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1342 }
1343 mRawP010Image.width = kWidth;
1344 mRawP010Image.height = kHeight;
1345 mRawP010Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
1346
1347 if (!loadFile(RAW_YUV420_IMAGE, mRawYuv420Image.data, nullptr)) {
1348 FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
1349 }
1350 mRawYuv420Image.width = kWidth;
1351 mRawYuv420Image.height = kHeight;
1352 mRawYuv420Image.colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
1353
1354 JpegRBenchmark benchmark;
1355
1356 ultrahdr_metadata_struct metadata = { .version = "1.0" };
1357
1358 jpegr_uncompressed_struct map = { .data = NULL,
1359 .width = 0,
1360 .height = 0,
1361 .colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED };
1362
1363 benchmark.BenchmarkGenerateGainMap(&mRawYuv420Image, &mRawP010Image, &metadata, &map);
1364
1365 const int dstSize = mRawYuv420Image.width * mRawYuv420Image.height * 4;
1366 auto bufferDst = std::make_unique<uint8_t[]>(dstSize);
1367 jpegr_uncompressed_struct dest = { .data = bufferDst.get(),
1368 .width = 0,
1369 .height = 0,
1370 .colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED };
1371
1372 benchmark.BenchmarkApplyGainMap(&mRawYuv420Image, &map, &metadata, &dest);
1373 }
1374
1375 } // namespace android::ultrahdr
1376