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 #ifdef _WIN32
18 #include <windows.h>
19 #else
20 #include <sys/time.h>
21 #endif
22 #include <gtest/gtest.h>
23
24 #include <fstream>
25 #include <iostream>
26
27 #include "ultrahdr_api.h"
28
29 #include "ultrahdr/ultrahdrcommon.h"
30 #include "ultrahdr/jpegr.h"
31 #include "ultrahdr/jpegrutils.h"
32
33 //#define DUMP_OUTPUT
34
35 namespace ultrahdr {
36
37 // resources used by unit tests
38 #ifdef __ANDROID__
39 const char* kYCbCrP010FileName = "/data/local/tmp/raw_p010_image.p010";
40 const char* kYCbCr420FileName = "/data/local/tmp/raw_yuv420_image.yuv420";
41 const char* kSdrJpgFileName = "/data/local/tmp/jpeg_image.jpg";
42 #else
43 const char* kYCbCrP010FileName = "./data/raw_p010_image.p010";
44 const char* kYCbCr420FileName = "./data/raw_yuv420_image.yuv420";
45 const char* kSdrJpgFileName = "./data/jpeg_image.jpg";
46 #endif
47 const size_t kImageWidth = 1280;
48 const size_t kImageHeight = 720;
49 const int kQuality = 90;
50
51 // Wrapper to describe the input type
52 typedef enum {
53 YCbCr_p010 = 0,
54 YCbCr_420 = 1,
55 } UhdrInputFormat;
56
57 /**
58 * Wrapper class for raw resource
59 * Sample usage:
60 * UhdrUnCompressedStructWrapper rawImg(width, height, YCbCr_p010);
61 * rawImg.setImageColorGamut(colorGamut));
62 * rawImg.setImageStride(strideLuma, strideChroma); // optional
63 * rawImg.setChromaMode(false); // optional
64 * rawImg.allocateMemory();
65 * rawImg.loadRawResource(kYCbCrP010FileName);
66 */
67 class UhdrUnCompressedStructWrapper {
68 public:
69 UhdrUnCompressedStructWrapper(size_t width, size_t height, UhdrInputFormat format);
70 ~UhdrUnCompressedStructWrapper() = default;
71
72 bool setChromaMode(bool isChromaContiguous);
73 bool setImageStride(size_t lumaStride, size_t chromaStride);
74 bool setImageColorGamut(ultrahdr_color_gamut colorGamut);
75 bool allocateMemory();
76 bool loadRawResource(const char* fileName);
77 jr_uncompressed_ptr getImageHandle();
78
79 private:
80 std::unique_ptr<uint8_t[]> mLumaData;
81 std::unique_ptr<uint8_t[]> mChromaData;
82 jpegr_uncompressed_struct mImg;
83 UhdrInputFormat mFormat;
84 bool mIsChromaContiguous;
85 };
86
87 /**
88 * Wrapper class for compressed resource
89 * Sample usage:
90 * UhdrCompressedStructWrapper jpgImg(width, height);
91 * rawImg.allocateMemory();
92 */
93 class UhdrCompressedStructWrapper {
94 public:
95 UhdrCompressedStructWrapper(size_t width, size_t height);
96 ~UhdrCompressedStructWrapper() = default;
97
98 bool allocateMemory();
99 jr_compressed_ptr getImageHandle();
100
101 private:
102 std::unique_ptr<uint8_t[]> mData;
103 jpegr_compressed_struct mImg{};
104 size_t mWidth;
105 size_t mHeight;
106 };
107
UhdrUnCompressedStructWrapper(size_t width,size_t height,UhdrInputFormat format)108 UhdrUnCompressedStructWrapper::UhdrUnCompressedStructWrapper(size_t width, size_t height,
109 UhdrInputFormat format) {
110 mImg.data = nullptr;
111 mImg.width = width;
112 mImg.height = height;
113 mImg.colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED;
114 mImg.chroma_data = nullptr;
115 mImg.luma_stride = 0;
116 mImg.chroma_stride = 0;
117 mFormat = format;
118 mIsChromaContiguous = true;
119 }
120
setChromaMode(bool isChromaContiguous)121 bool UhdrUnCompressedStructWrapper::setChromaMode(bool isChromaContiguous) {
122 if (mLumaData.get() != nullptr) {
123 std::cerr << "Object has sailed, no further modifications are allowed" << std::endl;
124 return false;
125 }
126 mIsChromaContiguous = isChromaContiguous;
127 return true;
128 }
129
setImageStride(size_t lumaStride,size_t chromaStride)130 bool UhdrUnCompressedStructWrapper::setImageStride(size_t lumaStride, size_t chromaStride) {
131 if (mLumaData.get() != nullptr) {
132 std::cerr << "Object has sailed, no further modifications are allowed" << std::endl;
133 return false;
134 }
135 if (lumaStride != 0) {
136 if (lumaStride < mImg.width) {
137 std::cerr << "Bad luma stride received" << std::endl;
138 return false;
139 }
140 mImg.luma_stride = lumaStride;
141 }
142 if (chromaStride != 0) {
143 if (mFormat == YCbCr_p010 && chromaStride < mImg.width) {
144 std::cerr << "Bad chroma stride received for format YCbCrP010" << std::endl;
145 return false;
146 }
147 if (mFormat == YCbCr_420 && chromaStride < (mImg.width >> 1)) {
148 std::cerr << "Bad chroma stride received for format YCbCr420" << std::endl;
149 return false;
150 }
151 mImg.chroma_stride = chromaStride;
152 }
153 return true;
154 }
155
setImageColorGamut(ultrahdr_color_gamut colorGamut)156 bool UhdrUnCompressedStructWrapper::setImageColorGamut(ultrahdr_color_gamut colorGamut) {
157 if (mLumaData.get() != nullptr) {
158 std::cerr << "Object has sailed, no further modifications are allowed" << std::endl;
159 return false;
160 }
161 mImg.colorGamut = colorGamut;
162 return true;
163 }
164
allocateMemory()165 bool UhdrUnCompressedStructWrapper::allocateMemory() {
166 if (mImg.width == 0 || (mImg.width % 2 != 0) || mImg.height == 0 || (mImg.height % 2 != 0) ||
167 (mFormat != YCbCr_p010 && mFormat != YCbCr_420)) {
168 std::cerr << "Object in bad state, mem alloc failed" << std::endl;
169 return false;
170 }
171 int lumaStride = mImg.luma_stride == 0 ? mImg.width : mImg.luma_stride;
172 int lumaSize = lumaStride * mImg.height * (mFormat == YCbCr_p010 ? 2 : 1);
173 int chromaSize = (mImg.height >> 1) * (mFormat == YCbCr_p010 ? 2 : 1);
174 if (mIsChromaContiguous) {
175 chromaSize *= lumaStride;
176 } else {
177 if (mImg.chroma_stride == 0) {
178 std::cerr << "Object in bad state, mem alloc failed" << std::endl;
179 return false;
180 }
181 if (mFormat == YCbCr_p010) {
182 chromaSize *= mImg.chroma_stride;
183 } else {
184 chromaSize *= (mImg.chroma_stride * 2);
185 }
186 }
187 if (mIsChromaContiguous) {
188 mLumaData = std::make_unique<uint8_t[]>(lumaSize + chromaSize);
189 mImg.data = mLumaData.get();
190 mImg.chroma_data = nullptr;
191 } else {
192 mLumaData = std::make_unique<uint8_t[]>(lumaSize);
193 mImg.data = mLumaData.get();
194 mChromaData = std::make_unique<uint8_t[]>(chromaSize);
195 mImg.chroma_data = mChromaData.get();
196 }
197 return true;
198 }
199
loadRawResource(const char * fileName)200 bool UhdrUnCompressedStructWrapper::loadRawResource(const char* fileName) {
201 if (!mImg.data) {
202 std::cerr << "memory is not allocated, read not possible" << std::endl;
203 return false;
204 }
205 std::ifstream ifd(fileName, std::ios::binary | std::ios::ate);
206 if (ifd.good()) {
207 int bpp = mFormat == YCbCr_p010 ? 2 : 1;
208 int size = ifd.tellg();
209 int length = mImg.width * mImg.height * bpp * 3 / 2; // 2x2 subsampling
210 if (size < length) {
211 std::cerr << "requested to read " << length << " bytes from file : " << fileName
212 << ", file contains only " << length << " bytes" << std::endl;
213 return false;
214 }
215 ifd.seekg(0, std::ios::beg);
216 size_t lumaStride = mImg.luma_stride == 0 ? mImg.width : mImg.luma_stride;
217 char* mem = static_cast<char*>(mImg.data);
218 for (size_t i = 0; i < mImg.height; i++) {
219 ifd.read(mem, mImg.width * bpp);
220 mem += lumaStride * bpp;
221 }
222 if (!mIsChromaContiguous) {
223 mem = static_cast<char*>(mImg.chroma_data);
224 }
225 size_t chromaStride;
226 if (mIsChromaContiguous) {
227 chromaStride = mFormat == YCbCr_p010 ? lumaStride : lumaStride / 2;
228 } else {
229 if (mFormat == YCbCr_p010) {
230 chromaStride = mImg.chroma_stride == 0 ? lumaStride : mImg.chroma_stride;
231 } else {
232 chromaStride = mImg.chroma_stride == 0 ? (lumaStride / 2) : mImg.chroma_stride;
233 }
234 }
235 if (mFormat == YCbCr_p010) {
236 for (size_t i = 0; i < mImg.height / 2; i++) {
237 ifd.read(mem, mImg.width * 2);
238 mem += chromaStride * 2;
239 }
240 } else {
241 for (size_t i = 0; i < mImg.height / 2; i++) {
242 ifd.read(mem, (mImg.width / 2));
243 mem += chromaStride;
244 }
245 for (size_t i = 0; i < mImg.height / 2; i++) {
246 ifd.read(mem, (mImg.width / 2));
247 mem += chromaStride;
248 }
249 }
250 return true;
251 }
252 std::cerr << "unable to open file : " << fileName << std::endl;
253 return false;
254 }
255
getImageHandle()256 jr_uncompressed_ptr UhdrUnCompressedStructWrapper::getImageHandle() { return &mImg; }
257
UhdrCompressedStructWrapper(size_t width,size_t height)258 UhdrCompressedStructWrapper::UhdrCompressedStructWrapper(size_t width, size_t height) {
259 mWidth = width;
260 mHeight = height;
261 }
262
allocateMemory()263 bool UhdrCompressedStructWrapper::allocateMemory() {
264 if (mWidth == 0 || (mWidth % 2 != 0) || mHeight == 0 || (mHeight % 2 != 0)) {
265 std::cerr << "Object in bad state, mem alloc failed" << std::endl;
266 return false;
267 }
268 int maxLength = (std::max)(8 * 1024 /* min size 8kb */, (int)(mWidth * mHeight * 3 * 2));
269 mData = std::make_unique<uint8_t[]>(maxLength);
270 mImg.data = mData.get();
271 mImg.length = 0;
272 mImg.maxLength = maxLength;
273 return true;
274 }
275
getImageHandle()276 jr_compressed_ptr UhdrCompressedStructWrapper::getImageHandle() { return &mImg; }
277
278 #ifdef DUMP_OUTPUT
writeFile(const char * filename,void * & result,int length)279 static bool writeFile(const char* filename, void*& result, int length) {
280 std::ofstream ofd(filename, std::ios::binary);
281 if (ofd.is_open()) {
282 ofd.write(static_cast<char*>(result), length);
283 return true;
284 }
285 std::cerr << "unable to write to file : " << filename << std::endl;
286 return false;
287 }
288 #endif
289
readFile(const char * fileName,void * & result,int maxLength,int & length)290 static bool readFile(const char* fileName, void*& result, int maxLength, int& length) {
291 std::ifstream ifd(fileName, std::ios::binary | std::ios::ate);
292 if (ifd.good()) {
293 length = ifd.tellg();
294 if (length > maxLength) {
295 std::cerr << "not enough space to read file" << std::endl;
296 return false;
297 }
298 ifd.seekg(0, std::ios::beg);
299 ifd.read(static_cast<char*>(result), length);
300 return true;
301 }
302 std::cerr << "unable to read file : " << fileName << std::endl;
303 return false;
304 }
305
map_internal_cg_to_cg(ultrahdr::ultrahdr_color_gamut cg)306 uhdr_color_gamut_t map_internal_cg_to_cg(ultrahdr::ultrahdr_color_gamut cg) {
307 switch (cg) {
308 case ultrahdr::ULTRAHDR_COLORGAMUT_BT2100:
309 return UHDR_CG_BT_2100;
310 case ultrahdr::ULTRAHDR_COLORGAMUT_BT709:
311 return UHDR_CG_BT_709;
312 case ultrahdr::ULTRAHDR_COLORGAMUT_P3:
313 return UHDR_CG_DISPLAY_P3;
314 default:
315 return UHDR_CG_UNSPECIFIED;
316 }
317 }
318
map_internal_ct_to_ct(ultrahdr::ultrahdr_transfer_function ct)319 uhdr_color_transfer_t map_internal_ct_to_ct(ultrahdr::ultrahdr_transfer_function ct) {
320 switch (ct) {
321 case ultrahdr::ULTRAHDR_TF_HLG:
322 return UHDR_CT_HLG;
323 case ultrahdr::ULTRAHDR_TF_PQ:
324 return UHDR_CT_PQ;
325 case ultrahdr::ULTRAHDR_TF_LINEAR:
326 return UHDR_CT_LINEAR;
327 case ultrahdr::ULTRAHDR_TF_SRGB:
328 return UHDR_CT_SRGB;
329 default:
330 return UHDR_CT_UNSPECIFIED;
331 }
332 }
333
decodeJpegRImg(jr_compressed_ptr img,const char * outFileName)334 void decodeJpegRImg(jr_compressed_ptr img, [[maybe_unused]] const char* outFileName) {
335 jpegr_info_struct info{};
336 JpegR jpegHdr;
337 ASSERT_EQ(JPEGR_NO_ERROR, jpegHdr.getJPEGRInfo(img, &info));
338 ASSERT_EQ(kImageWidth, info.width);
339 ASSERT_EQ(kImageHeight, info.height);
340 size_t outSize = info.width * info.height * 8;
341 std::unique_ptr<uint8_t[]> data = std::make_unique<uint8_t[]>(outSize);
342 jpegr_uncompressed_struct destImage{};
343 destImage.data = data.get();
344 ASSERT_EQ(JPEGR_NO_ERROR, jpegHdr.decodeJPEGR(img, &destImage));
345 ASSERT_EQ(kImageWidth, destImage.width);
346 ASSERT_EQ(kImageHeight, destImage.height);
347 #ifdef DUMP_OUTPUT
348 if (!writeFile(outFileName, destImage.data, outSize)) {
349 std::cerr << "unable to write output file" << std::endl;
350 }
351 #endif
352 uhdr_codec_private_t* obj = uhdr_create_decoder();
353 uhdr_compressed_image_t uhdr_image{};
354 uhdr_image.data = img->data;
355 uhdr_image.data_sz = img->length;
356 uhdr_image.capacity = img->length;
357 uhdr_image.cg = UHDR_CG_UNSPECIFIED;
358 uhdr_image.ct = UHDR_CT_UNSPECIFIED;
359 uhdr_image.range = UHDR_CR_UNSPECIFIED;
360 uhdr_error_info_t status = uhdr_dec_set_image(obj, &uhdr_image);
361 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
362 status = uhdr_decode(obj);
363 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
364 uhdr_raw_image_t* raw_image = uhdr_get_decoded_image(obj);
365 ASSERT_NE(nullptr, raw_image);
366 ASSERT_EQ(map_internal_cg_to_cg(destImage.colorGamut), raw_image->cg);
367 ASSERT_EQ(destImage.width, raw_image->w);
368 ASSERT_EQ(destImage.height, raw_image->h);
369 char* testData = static_cast<char*>(raw_image->planes[UHDR_PLANE_PACKED]);
370 char* refData = static_cast<char*>(destImage.data);
371 int bpp = (raw_image->fmt == UHDR_IMG_FMT_64bppRGBAHalfFloat) ? 8 : 4;
372 const size_t testStride = raw_image->stride[UHDR_PLANE_PACKED] * bpp;
373 const size_t refStride = destImage.width * bpp;
374 const size_t length = destImage.width * bpp;
375 for (unsigned i = 0; i < destImage.height; i++, testData += testStride, refData += refStride) {
376 ASSERT_EQ(0, memcmp(testData, refData, length));
377 }
378 uhdr_release_decoder(obj);
379 }
380
381 // ============================================================================
382 // Unit Tests
383 // ============================================================================
384
385 // Test Encode API-0 invalid arguments
TEST(JpegRTest,EncodeAPI0WithInvalidArgs)386 TEST(JpegRTest, EncodeAPI0WithInvalidArgs) {
387 JpegR uHdrLib;
388
389 UhdrCompressedStructWrapper jpgImg(16, 16);
390 ASSERT_TRUE(jpgImg.allocateMemory());
391
392 // test quality factor and transfer function
393 {
394 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
395 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
396 ASSERT_TRUE(rawImg.allocateMemory());
397
398 ASSERT_NE(
399 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
400 jpgImg.getImageHandle(), -1, nullptr),
401 JPEGR_NO_ERROR)
402 << "fail, API allows bad jpeg quality factor";
403 ASSERT_NE(
404 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
405 jpgImg.getImageHandle(), 101, nullptr),
406 JPEGR_NO_ERROR)
407 << "fail, API allows bad jpeg quality factor";
408
409 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
410 ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
411 jpgImg.getImageHandle(), kQuality, nullptr),
412 JPEGR_NO_ERROR)
413 << "fail, API allows bad hdr transfer function";
414 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(),
415 static_cast<ultrahdr_transfer_function>(
416 ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
417 jpgImg.getImageHandle(), kQuality, nullptr),
418 JPEGR_NO_ERROR)
419 << "fail, API allows bad hdr transfer function";
420 ASSERT_NE(
421 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), static_cast<ultrahdr_transfer_function>(-10),
422 jpgImg.getImageHandle(), kQuality, nullptr),
423 JPEGR_NO_ERROR)
424 << "fail, API allows bad hdr transfer function";
425 }
426
427 // test dest
428 {
429 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
430 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
431 ASSERT_TRUE(rawImg.allocateMemory());
432
433 ASSERT_NE(
434 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
435 nullptr, kQuality, nullptr),
436 JPEGR_NO_ERROR)
437 << "fail, API allows nullptr dest";
438 UhdrCompressedStructWrapper jpgImg2(16, 16);
439 ASSERT_NE(
440 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
441 jpgImg2.getImageHandle(), kQuality, nullptr),
442 JPEGR_NO_ERROR)
443 << "fail, API allows nullptr dest";
444 }
445
446 // test p010 input
447 {
448 ASSERT_NE(uHdrLib.encodeJPEGR(nullptr, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
449 jpgImg.getImageHandle(), kQuality, nullptr),
450 JPEGR_NO_ERROR)
451 << "fail, API allows nullptr p010 image";
452
453 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
454 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
455 ASSERT_NE(
456 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
457 jpgImg.getImageHandle(), kQuality, nullptr),
458 JPEGR_NO_ERROR)
459 << "fail, API allows nullptr p010 image";
460 }
461
462 {
463 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
464 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED));
465 ASSERT_TRUE(rawImg.allocateMemory());
466 ASSERT_NE(
467 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
468 jpgImg.getImageHandle(), kQuality, nullptr),
469 JPEGR_NO_ERROR)
470 << "fail, API allows bad p010 color gamut";
471
472 UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_p010);
473 ASSERT_TRUE(rawImg2.setImageColorGamut(
474 static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1)));
475 ASSERT_TRUE(rawImg2.allocateMemory());
476 ASSERT_NE(
477 uHdrLib.encodeJPEGR(rawImg2.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
478 jpgImg.getImageHandle(), kQuality, nullptr),
479 JPEGR_NO_ERROR)
480 << "fail, API allows bad p010 color gamut";
481 }
482
483 {
484 const int kWidth = 32, kHeight = 32;
485 UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
486 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
487 ASSERT_TRUE(rawImg.allocateMemory());
488 auto rawImgP010 = rawImg.getImageHandle();
489
490 rawImgP010->width = kWidth - 1;
491 rawImgP010->height = kHeight;
492 ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
493 jpgImg.getImageHandle(), kQuality, nullptr),
494 JPEGR_NO_ERROR)
495 << "fail, API allows bad image width";
496
497 rawImgP010->width = kWidth;
498 rawImgP010->height = kHeight - 1;
499 ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
500 jpgImg.getImageHandle(), kQuality, nullptr),
501 JPEGR_NO_ERROR)
502 << "fail, API allows bad image height";
503
504 rawImgP010->width = 0;
505 rawImgP010->height = kHeight;
506 ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
507 jpgImg.getImageHandle(), kQuality, nullptr),
508 JPEGR_NO_ERROR)
509 << "fail, API allows bad image width";
510
511 rawImgP010->width = kWidth;
512 rawImgP010->height = 0;
513 ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
514 jpgImg.getImageHandle(), kQuality, nullptr),
515 JPEGR_NO_ERROR)
516 << "fail, API allows bad image height";
517
518 rawImgP010->width = kWidth;
519 rawImgP010->height = kHeight;
520 rawImgP010->luma_stride = kWidth - 2;
521 ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
522 jpgImg.getImageHandle(), kQuality, nullptr),
523 JPEGR_NO_ERROR)
524 << "fail, API allows bad luma stride";
525
526 rawImgP010->width = kWidth;
527 rawImgP010->height = kHeight;
528 rawImgP010->luma_stride = kWidth + 64;
529 rawImgP010->chroma_data = rawImgP010->data;
530 rawImgP010->chroma_stride = kWidth - 2;
531 ASSERT_NE(uHdrLib.encodeJPEGR(rawImgP010, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
532 jpgImg.getImageHandle(), kQuality, nullptr),
533 JPEGR_NO_ERROR)
534 << "fail, API allows bad chroma stride";
535 }
536 }
537
538 /* Test Encode API-1 invalid arguments */
TEST(JpegRTest,EncodeAPI1WithInvalidArgs)539 TEST(JpegRTest, EncodeAPI1WithInvalidArgs) {
540 JpegR uHdrLib;
541
542 UhdrCompressedStructWrapper jpgImg(16, 16);
543 ASSERT_TRUE(jpgImg.allocateMemory());
544
545 // test quality factor and transfer function
546 {
547 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
548 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
549 ASSERT_TRUE(rawImg.allocateMemory());
550 UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
551 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
552 ASSERT_TRUE(rawImg2.allocateMemory());
553
554 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
555 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
556 jpgImg.getImageHandle(), -1, nullptr),
557 JPEGR_NO_ERROR)
558 << "fail, API allows bad jpeg quality factor";
559 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
560 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
561 jpgImg.getImageHandle(), 101, nullptr),
562 JPEGR_NO_ERROR)
563 << "fail, API allows bad jpeg quality factor";
564
565 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
566 ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
567 jpgImg.getImageHandle(), kQuality, nullptr),
568 JPEGR_NO_ERROR)
569 << "fail, API allows bad hdr transfer function";
570 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
571 static_cast<ultrahdr_transfer_function>(
572 ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
573 jpgImg.getImageHandle(), kQuality, nullptr),
574 JPEGR_NO_ERROR)
575 << "fail, API allows bad hdr transfer function";
576 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
577 static_cast<ultrahdr_transfer_function>(-10),
578 jpgImg.getImageHandle(), kQuality, nullptr),
579 JPEGR_NO_ERROR)
580 << "fail, API allows bad hdr transfer function";
581 }
582
583 // test dest
584 {
585 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
586 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
587 ASSERT_TRUE(rawImg.allocateMemory());
588 UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
589 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
590 ASSERT_TRUE(rawImg2.allocateMemory());
591
592 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
593 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr, kQuality,
594 nullptr),
595 JPEGR_NO_ERROR)
596 << "fail, API allows nullptr dest";
597 UhdrCompressedStructWrapper jpgImg2(16, 16);
598 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
599 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
600 jpgImg2.getImageHandle(), kQuality, nullptr),
601 JPEGR_NO_ERROR)
602 << "fail, API allows nullptr dest";
603 }
604
605 // test p010 input
606 {
607 UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
608 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
609 ASSERT_TRUE(rawImg2.allocateMemory());
610 ASSERT_NE(uHdrLib.encodeJPEGR(nullptr, rawImg2.getImageHandle(),
611 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
612 jpgImg.getImageHandle(), kQuality, nullptr),
613 JPEGR_NO_ERROR)
614 << "fail, API allows nullptr p010 image";
615
616 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
617 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
618 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
619 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
620 jpgImg.getImageHandle(), kQuality, nullptr),
621 JPEGR_NO_ERROR)
622 << "fail, API allows nullptr p010 image";
623 }
624
625 {
626 const int kWidth = 32, kHeight = 32;
627 UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
628 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
629 ASSERT_TRUE(rawImg.allocateMemory());
630 auto rawImgP010 = rawImg.getImageHandle();
631 UhdrUnCompressedStructWrapper rawImg2(kWidth, kHeight, YCbCr_420);
632 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
633 ASSERT_TRUE(rawImg2.allocateMemory());
634 auto rawImg420 = rawImg2.getImageHandle();
635
636 rawImgP010->width = kWidth;
637 rawImgP010->height = kHeight;
638 rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
639 ASSERT_NE(
640 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
641 jpgImg.getImageHandle(), kQuality, nullptr),
642 JPEGR_NO_ERROR)
643 << "fail, API allows bad p010 color gamut";
644
645 rawImgP010->width = kWidth;
646 rawImgP010->height = kHeight;
647 rawImgP010->colorGamut =
648 static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
649 ASSERT_NE(
650 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
651 jpgImg.getImageHandle(), kQuality, nullptr),
652 JPEGR_NO_ERROR)
653 << "fail, API allows bad p010 color gamut";
654
655 rawImgP010->width = kWidth - 1;
656 rawImgP010->height = kHeight;
657 rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
658 ASSERT_NE(
659 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
660 jpgImg.getImageHandle(), kQuality, nullptr),
661 JPEGR_NO_ERROR)
662 << "fail, API allows bad image width";
663
664 rawImgP010->width = kWidth;
665 rawImgP010->height = kHeight - 1;
666 ASSERT_NE(
667 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
668 jpgImg.getImageHandle(), kQuality, nullptr),
669 JPEGR_NO_ERROR)
670 << "fail, API allows bad image height";
671
672 rawImgP010->width = 0;
673 rawImgP010->height = kHeight;
674 ASSERT_NE(
675 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
676 jpgImg.getImageHandle(), kQuality, nullptr),
677 JPEGR_NO_ERROR)
678 << "fail, API allows bad image width";
679
680 rawImgP010->width = kWidth;
681 rawImgP010->height = 0;
682 ASSERT_NE(
683 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
684 jpgImg.getImageHandle(), kQuality, nullptr),
685 JPEGR_NO_ERROR)
686 << "fail, API allows bad image height";
687
688 rawImgP010->width = kWidth;
689 rawImgP010->height = kHeight;
690 rawImgP010->luma_stride = kWidth - 2;
691 ASSERT_NE(
692 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
693 jpgImg.getImageHandle(), kQuality, nullptr),
694 JPEGR_NO_ERROR)
695 << "fail, API allows bad luma stride";
696
697 rawImgP010->width = kWidth;
698 rawImgP010->height = kHeight;
699 rawImgP010->luma_stride = kWidth + 64;
700 rawImgP010->chroma_data = rawImgP010->data;
701 rawImgP010->chroma_stride = kWidth - 2;
702 ASSERT_NE(
703 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
704 jpgImg.getImageHandle(), kQuality, nullptr),
705 JPEGR_NO_ERROR)
706 << "fail, API allows bad chroma stride";
707 }
708
709 // test 420 input
710 {
711 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
712 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
713 ASSERT_TRUE(rawImg.allocateMemory());
714 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), nullptr,
715 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
716 jpgImg.getImageHandle(), kQuality, nullptr),
717 JPEGR_NO_ERROR)
718 << "fail, API allows nullptr 420 image";
719
720 UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
721 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
722 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
723 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
724 jpgImg.getImageHandle(), kQuality, nullptr),
725 JPEGR_NO_ERROR)
726 << "fail, API allows nullptr 420 image";
727 }
728 {
729 const int kWidth = 32, kHeight = 32;
730 UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
731 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
732 ASSERT_TRUE(rawImg.allocateMemory());
733 auto rawImgP010 = rawImg.getImageHandle();
734 UhdrUnCompressedStructWrapper rawImg2(kWidth, kHeight, YCbCr_420);
735 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
736 ASSERT_TRUE(rawImg2.allocateMemory());
737 auto rawImg420 = rawImg2.getImageHandle();
738
739 rawImg420->width = kWidth;
740 rawImg420->height = kHeight;
741 rawImg420->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
742 ASSERT_NE(
743 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
744 jpgImg.getImageHandle(), kQuality, nullptr),
745 JPEGR_NO_ERROR)
746 << "fail, API allows bad 420 color gamut";
747
748 rawImg420->width = kWidth;
749 rawImg420->height = kHeight;
750 rawImg420->colorGamut =
751 static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
752 ASSERT_NE(
753 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
754 jpgImg.getImageHandle(), kQuality, nullptr),
755 JPEGR_NO_ERROR)
756 << "fail, API allows bad 420 color gamut";
757
758 rawImg420->width = kWidth - 1;
759 rawImg420->height = kHeight;
760 rawImg420->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
761 ASSERT_NE(
762 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
763 jpgImg.getImageHandle(), kQuality, nullptr),
764 JPEGR_NO_ERROR)
765 << "fail, API allows bad image width for 420";
766
767 rawImg420->width = kWidth;
768 rawImg420->height = kHeight - 1;
769 ASSERT_NE(
770 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
771 jpgImg.getImageHandle(), kQuality, nullptr),
772 JPEGR_NO_ERROR)
773 << "fail, API allows bad image height for 420";
774
775 rawImg420->width = 0;
776 rawImg420->height = kHeight;
777 ASSERT_NE(
778 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
779 jpgImg.getImageHandle(), kQuality, nullptr),
780 JPEGR_NO_ERROR)
781 << "fail, API allows bad image width for 420";
782
783 rawImg420->width = kWidth;
784 rawImg420->height = 0;
785 ASSERT_NE(
786 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
787 jpgImg.getImageHandle(), kQuality, nullptr),
788 JPEGR_NO_ERROR)
789 << "fail, API allows bad image height for 420";
790
791 rawImg420->width = kWidth;
792 rawImg420->height = kHeight;
793 rawImg420->luma_stride = kWidth - 2;
794 ASSERT_NE(
795 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
796 jpgImg.getImageHandle(), kQuality, nullptr),
797 JPEGR_NO_ERROR)
798 << "fail, API allows bad luma stride for 420";
799
800 rawImg420->width = kWidth;
801 rawImg420->height = kHeight;
802 rawImg420->luma_stride = 0;
803 rawImg420->chroma_data = rawImgP010->data;
804 rawImg420->chroma_stride = kWidth / 2 - 2;
805 ASSERT_NE(
806 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
807 jpgImg.getImageHandle(), kQuality, nullptr),
808 JPEGR_NO_ERROR)
809 << "fail, API allows bad chroma stride for 420";
810 }
811 }
812
813 /* Test Encode API-2 invalid arguments */
TEST(JpegRTest,EncodeAPI2WithInvalidArgs)814 TEST(JpegRTest, EncodeAPI2WithInvalidArgs) {
815 JpegR uHdrLib;
816
817 UhdrCompressedStructWrapper jpgImg(16, 16);
818 ASSERT_TRUE(jpgImg.allocateMemory());
819
820 // test quality factor and transfer function
821 {
822 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
823 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
824 ASSERT_TRUE(rawImg.allocateMemory());
825 UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
826 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
827 ASSERT_TRUE(rawImg2.allocateMemory());
828
829 ASSERT_NE(uHdrLib.encodeJPEGR(
830 rawImg.getImageHandle(), rawImg2.getImageHandle(), jpgImg.getImageHandle(),
831 ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED, jpgImg.getImageHandle()),
832 JPEGR_NO_ERROR)
833 << "fail, API allows bad hdr transfer function";
834 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
835 jpgImg.getImageHandle(),
836 static_cast<ultrahdr_transfer_function>(
837 ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
838 jpgImg.getImageHandle()),
839 JPEGR_NO_ERROR)
840 << "fail, API allows bad hdr transfer function";
841 ASSERT_NE(uHdrLib.encodeJPEGR(
842 rawImg.getImageHandle(), rawImg2.getImageHandle(), jpgImg.getImageHandle(),
843 static_cast<ultrahdr_transfer_function>(-10), jpgImg.getImageHandle()),
844 JPEGR_NO_ERROR)
845 << "fail, API allows bad hdr transfer function";
846 }
847
848 // test dest
849 {
850 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
851 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
852 ASSERT_TRUE(rawImg.allocateMemory());
853 UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
854 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
855 ASSERT_TRUE(rawImg2.allocateMemory());
856
857 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(),
858 jpgImg.getImageHandle(),
859 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr),
860 JPEGR_NO_ERROR)
861 << "fail, API allows nullptr dest";
862 UhdrCompressedStructWrapper jpgImg2(16, 16);
863 ASSERT_NE(uHdrLib.encodeJPEGR(
864 rawImg.getImageHandle(), rawImg2.getImageHandle(), jpgImg.getImageHandle(),
865 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
866 JPEGR_NO_ERROR)
867 << "fail, API allows nullptr dest";
868 }
869
870 // test compressed image
871 {
872 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
873 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
874 ASSERT_TRUE(rawImg.allocateMemory());
875 UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
876 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
877 ASSERT_TRUE(rawImg2.allocateMemory());
878
879 ASSERT_NE(
880 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), rawImg2.getImageHandle(), nullptr,
881 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
882 JPEGR_NO_ERROR)
883 << "fail, API allows nullptr for compressed image";
884 UhdrCompressedStructWrapper jpgImg2(16, 16);
885 ASSERT_NE(uHdrLib.encodeJPEGR(
886 rawImg.getImageHandle(), rawImg2.getImageHandle(), jpgImg2.getImageHandle(),
887 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
888 JPEGR_NO_ERROR)
889 << "fail, API allows nullptr for compressed image";
890 }
891
892 // test p010 input
893 {
894 UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
895 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
896 ASSERT_TRUE(rawImg2.allocateMemory());
897 ASSERT_NE(
898 uHdrLib.encodeJPEGR(nullptr, rawImg2.getImageHandle(), jpgImg.getImageHandle(),
899 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
900 JPEGR_NO_ERROR)
901 << "fail, API allows nullptr p010 image";
902
903 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
904 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
905 ASSERT_NE(uHdrLib.encodeJPEGR(
906 rawImg.getImageHandle(), rawImg2.getImageHandle(), jpgImg.getImageHandle(),
907 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
908 JPEGR_NO_ERROR)
909 << "fail, API allows nullptr p010 image";
910 }
911
912 {
913 const int kWidth = 32, kHeight = 32;
914 UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
915 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
916 ASSERT_TRUE(rawImg.allocateMemory());
917 auto rawImgP010 = rawImg.getImageHandle();
918 UhdrUnCompressedStructWrapper rawImg2(kWidth, kHeight, YCbCr_420);
919 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
920 ASSERT_TRUE(rawImg2.allocateMemory());
921 auto rawImg420 = rawImg2.getImageHandle();
922
923 rawImgP010->width = kWidth;
924 rawImgP010->height = kHeight;
925 rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
926 ASSERT_NE(
927 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
928 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
929 JPEGR_NO_ERROR)
930 << "fail, API allows bad p010 color gamut";
931
932 rawImgP010->width = kWidth;
933 rawImgP010->height = kHeight;
934 rawImgP010->colorGamut =
935 static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
936 ASSERT_NE(
937 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
938 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
939 JPEGR_NO_ERROR)
940 << "fail, API allows bad p010 color gamut";
941
942 rawImgP010->width = kWidth - 1;
943 rawImgP010->height = kHeight;
944 rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
945 ASSERT_NE(
946 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
947 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
948 JPEGR_NO_ERROR)
949 << "fail, API allows bad image width";
950
951 rawImgP010->width = kWidth;
952 rawImgP010->height = kHeight - 1;
953 ASSERT_NE(
954 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
955 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
956 JPEGR_NO_ERROR)
957 << "fail, API allows bad image height";
958
959 rawImgP010->width = 0;
960 rawImgP010->height = kHeight;
961 ASSERT_NE(
962 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
963 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
964 JPEGR_NO_ERROR)
965 << "fail, API allows bad image width";
966
967 rawImgP010->width = kWidth;
968 rawImgP010->height = 0;
969 ASSERT_NE(
970 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
971 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
972 JPEGR_NO_ERROR)
973 << "fail, API allows bad image height";
974
975 rawImgP010->width = kWidth;
976 rawImgP010->height = kHeight;
977 rawImgP010->luma_stride = kWidth - 2;
978 ASSERT_NE(
979 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
980 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
981 JPEGR_NO_ERROR)
982 << "fail, API allows bad luma stride";
983
984 rawImgP010->width = kWidth;
985 rawImgP010->height = kHeight;
986 rawImgP010->luma_stride = kWidth + 64;
987 rawImgP010->chroma_data = rawImgP010->data;
988 rawImgP010->chroma_stride = kWidth - 2;
989 ASSERT_NE(
990 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
991 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
992 JPEGR_NO_ERROR)
993 << "fail, API allows bad chroma stride";
994 }
995
996 // test 420 input
997 {
998 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
999 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
1000 ASSERT_TRUE(rawImg.allocateMemory());
1001 ASSERT_NE(
1002 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), nullptr, jpgImg.getImageHandle(),
1003 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1004 JPEGR_NO_ERROR)
1005 << "fail, API allows nullptr 420 image";
1006
1007 UhdrUnCompressedStructWrapper rawImg2(16, 16, YCbCr_420);
1008 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
1009 ASSERT_NE(uHdrLib.encodeJPEGR(
1010 rawImg.getImageHandle(), rawImg2.getImageHandle(), jpgImg.getImageHandle(),
1011 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1012 JPEGR_NO_ERROR)
1013 << "fail, API allows nullptr 420 image";
1014 }
1015 {
1016 const int kWidth = 32, kHeight = 32;
1017 UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
1018 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
1019 ASSERT_TRUE(rawImg.allocateMemory());
1020 auto rawImgP010 = rawImg.getImageHandle();
1021 UhdrUnCompressedStructWrapper rawImg2(kWidth, kHeight, YCbCr_420);
1022 ASSERT_TRUE(rawImg2.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
1023 ASSERT_TRUE(rawImg2.allocateMemory());
1024 auto rawImg420 = rawImg2.getImageHandle();
1025
1026 rawImg420->width = kWidth;
1027 rawImg420->height = kHeight;
1028 rawImg420->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
1029 ASSERT_NE(
1030 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
1031 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1032 JPEGR_NO_ERROR)
1033 << "fail, API allows bad 420 color gamut";
1034
1035 rawImg420->width = kWidth;
1036 rawImg420->height = kHeight;
1037 rawImg420->colorGamut =
1038 static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
1039 ASSERT_NE(
1040 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
1041 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1042 JPEGR_NO_ERROR)
1043 << "fail, API allows bad 420 color gamut";
1044
1045 rawImg420->width = kWidth - 1;
1046 rawImg420->height = kHeight;
1047 rawImg420->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709;
1048 ASSERT_NE(
1049 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
1050 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1051 JPEGR_NO_ERROR)
1052 << "fail, API allows bad image width for 420";
1053
1054 rawImg420->width = kWidth;
1055 rawImg420->height = kHeight - 1;
1056 ASSERT_NE(
1057 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
1058 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1059 JPEGR_NO_ERROR)
1060 << "fail, API allows bad image height for 420";
1061
1062 rawImg420->width = 0;
1063 rawImg420->height = kHeight;
1064 ASSERT_NE(
1065 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
1066 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1067 JPEGR_NO_ERROR)
1068 << "fail, API allows bad image width for 420";
1069
1070 rawImg420->width = kWidth;
1071 rawImg420->height = 0;
1072 ASSERT_NE(
1073 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
1074 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1075 JPEGR_NO_ERROR)
1076 << "fail, API allows bad image height for 420";
1077
1078 rawImg420->width = kWidth;
1079 rawImg420->height = kHeight;
1080 rawImg420->luma_stride = kWidth - 2;
1081 ASSERT_NE(
1082 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
1083 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1084 JPEGR_NO_ERROR)
1085 << "fail, API allows bad luma stride for 420";
1086
1087 rawImg420->width = kWidth;
1088 rawImg420->height = kHeight;
1089 rawImg420->luma_stride = 0;
1090 rawImg420->chroma_data = rawImgP010->data;
1091 rawImg420->chroma_stride = kWidth / 2 - 2;
1092 ASSERT_NE(
1093 uHdrLib.encodeJPEGR(rawImgP010, rawImg420, jpgImg.getImageHandle(),
1094 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1095 JPEGR_NO_ERROR)
1096 << "fail, API allows bad chroma stride for 420";
1097 }
1098 }
1099
1100 /* Test Encode API-3 invalid arguments */
TEST(JpegRTest,EncodeAPI3WithInvalidArgs)1101 TEST(JpegRTest, EncodeAPI3WithInvalidArgs) {
1102 JpegR uHdrLib;
1103
1104 UhdrCompressedStructWrapper jpgImg(16, 16);
1105 ASSERT_TRUE(jpgImg.allocateMemory());
1106
1107 // test quality factor and transfer function
1108 {
1109 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
1110 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
1111 ASSERT_TRUE(rawImg.allocateMemory());
1112
1113 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
1114 ultrahdr_transfer_function::ULTRAHDR_TF_UNSPECIFIED,
1115 jpgImg.getImageHandle()),
1116 JPEGR_NO_ERROR)
1117 << "fail, API allows bad hdr transfer function";
1118 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
1119 static_cast<ultrahdr_transfer_function>(
1120 ultrahdr_transfer_function::ULTRAHDR_TF_MAX + 1),
1121 jpgImg.getImageHandle()),
1122 JPEGR_NO_ERROR)
1123 << "fail, API allows bad hdr transfer function";
1124 ASSERT_NE(
1125 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
1126 static_cast<ultrahdr_transfer_function>(-10), jpgImg.getImageHandle()),
1127 JPEGR_NO_ERROR)
1128 << "fail, API allows bad hdr transfer function";
1129 }
1130
1131 // test dest
1132 {
1133 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
1134 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
1135 ASSERT_TRUE(rawImg.allocateMemory());
1136
1137 ASSERT_NE(uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
1138 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, nullptr),
1139 JPEGR_NO_ERROR)
1140 << "fail, API allows nullptr dest";
1141 UhdrCompressedStructWrapper jpgImg2(16, 16);
1142 ASSERT_NE(
1143 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
1144 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
1145 JPEGR_NO_ERROR)
1146 << "fail, API allows nullptr dest";
1147 }
1148
1149 // test compressed image
1150 {
1151 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
1152 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
1153 ASSERT_TRUE(rawImg.allocateMemory());
1154
1155 ASSERT_NE(
1156 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), nullptr,
1157 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1158 JPEGR_NO_ERROR)
1159 << "fail, API allows nullptr for compressed image";
1160 UhdrCompressedStructWrapper jpgImg2(16, 16);
1161 ASSERT_NE(
1162 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg2.getImageHandle(),
1163 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1164 JPEGR_NO_ERROR)
1165 << "fail, API allows nullptr for compressed image";
1166 }
1167
1168 // test p010 input
1169 {
1170 ASSERT_NE(
1171 uHdrLib.encodeJPEGR(nullptr, jpgImg.getImageHandle(),
1172 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1173 JPEGR_NO_ERROR)
1174 << "fail, API allows nullptr p010 image";
1175
1176 UhdrUnCompressedStructWrapper rawImg(16, 16, YCbCr_p010);
1177 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
1178 ASSERT_NE(
1179 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), jpgImg.getImageHandle(),
1180 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1181 JPEGR_NO_ERROR)
1182 << "fail, API allows nullptr p010 image";
1183 }
1184
1185 {
1186 const int kWidth = 32, kHeight = 32;
1187 UhdrUnCompressedStructWrapper rawImg(kWidth, kHeight, YCbCr_p010);
1188 ASSERT_TRUE(rawImg.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
1189 ASSERT_TRUE(rawImg.allocateMemory());
1190 auto rawImgP010 = rawImg.getImageHandle();
1191
1192 rawImgP010->width = kWidth;
1193 rawImgP010->height = kHeight;
1194 rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_UNSPECIFIED;
1195 ASSERT_NE(
1196 uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
1197 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1198 JPEGR_NO_ERROR)
1199 << "fail, API allows bad p010 color gamut";
1200
1201 rawImgP010->width = kWidth;
1202 rawImgP010->height = kHeight;
1203 rawImgP010->colorGamut =
1204 static_cast<ultrahdr_color_gamut>(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_MAX + 1);
1205 ASSERT_NE(
1206 uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
1207 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1208 JPEGR_NO_ERROR)
1209 << "fail, API allows bad p010 color gamut";
1210
1211 rawImgP010->width = kWidth - 1;
1212 rawImgP010->height = kHeight;
1213 rawImgP010->colorGamut = ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100;
1214 ASSERT_NE(
1215 uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
1216 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1217 JPEGR_NO_ERROR)
1218 << "fail, API allows bad image width";
1219
1220 rawImgP010->width = kWidth;
1221 rawImgP010->height = kHeight - 1;
1222 ASSERT_NE(
1223 uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
1224 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1225 JPEGR_NO_ERROR)
1226 << "fail, API allows bad image height";
1227
1228 rawImgP010->width = 0;
1229 rawImgP010->height = kHeight;
1230 ASSERT_NE(
1231 uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
1232 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1233 JPEGR_NO_ERROR)
1234 << "fail, API allows bad image width";
1235
1236 rawImgP010->width = kWidth;
1237 rawImgP010->height = 0;
1238 ASSERT_NE(
1239 uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
1240 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1241 JPEGR_NO_ERROR)
1242 << "fail, API allows bad image height";
1243
1244 rawImgP010->width = kWidth;
1245 rawImgP010->height = kHeight;
1246 rawImgP010->luma_stride = kWidth - 2;
1247 ASSERT_NE(
1248 uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
1249 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1250 JPEGR_NO_ERROR)
1251 << "fail, API allows bad luma stride";
1252
1253 rawImgP010->width = kWidth;
1254 rawImgP010->height = kHeight;
1255 rawImgP010->luma_stride = kWidth + 64;
1256 rawImgP010->chroma_data = rawImgP010->data;
1257 rawImgP010->chroma_stride = kWidth - 2;
1258 ASSERT_NE(
1259 uHdrLib.encodeJPEGR(rawImgP010, jpgImg.getImageHandle(),
1260 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1261 JPEGR_NO_ERROR)
1262 << "fail, API allows bad chroma stride";
1263 }
1264 }
1265
1266 /* Test Encode API-4 invalid arguments */
TEST(JpegRTest,EncodeAPI4WithInvalidArgs)1267 TEST(JpegRTest, EncodeAPI4WithInvalidArgs) {
1268 UhdrCompressedStructWrapper jpgImg(16, 16);
1269 ASSERT_TRUE(jpgImg.allocateMemory());
1270 UhdrCompressedStructWrapper jpgImg2(16, 16);
1271 JpegR uHdrLib;
1272
1273 // test dest
1274 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), nullptr, nullptr),
1275 JPEGR_NO_ERROR)
1276 << "fail, API allows nullptr dest";
1277 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), nullptr,
1278 jpgImg2.getImageHandle()),
1279 JPEGR_NO_ERROR)
1280 << "fail, API allows nullptr dest";
1281
1282 // test primary image
1283 ASSERT_NE(uHdrLib.encodeJPEGR(nullptr, jpgImg.getImageHandle(), nullptr, jpgImg.getImageHandle()),
1284 JPEGR_NO_ERROR)
1285 << "fail, API allows nullptr primary image";
1286 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg2.getImageHandle(), jpgImg.getImageHandle(), nullptr,
1287 jpgImg.getImageHandle()),
1288 JPEGR_NO_ERROR)
1289 << "fail, API allows nullptr primary image";
1290
1291 // test gain map
1292 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), nullptr, nullptr, jpgImg.getImageHandle()),
1293 JPEGR_NO_ERROR)
1294 << "fail, API allows nullptr gain map image";
1295 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg2.getImageHandle(), nullptr,
1296 jpgImg.getImageHandle()),
1297 JPEGR_NO_ERROR)
1298 << "fail, API allows nullptr gain map image";
1299
1300 // test metadata
1301 ultrahdr_metadata_struct good_metadata;
1302 good_metadata.version = "1.0";
1303 good_metadata.minContentBoost = 1.0f;
1304 good_metadata.maxContentBoost = 2.0f;
1305 good_metadata.gamma = 1.0f;
1306 good_metadata.offsetSdr = 0.0f;
1307 good_metadata.offsetHdr = 0.0f;
1308 good_metadata.hdrCapacityMin = 1.0f;
1309 good_metadata.hdrCapacityMax = 2.0f;
1310
1311 ultrahdr_metadata_struct metadata = good_metadata;
1312 metadata.version = "1.1";
1313 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
1314 jpgImg.getImageHandle()),
1315 JPEGR_NO_ERROR)
1316 << "fail, API allows bad metadata version";
1317
1318 metadata = good_metadata;
1319 metadata.minContentBoost = 3.0f;
1320 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
1321 jpgImg.getImageHandle()),
1322 JPEGR_NO_ERROR)
1323 << "fail, API allows bad metadata content boost";
1324
1325 metadata = good_metadata;
1326 metadata.gamma = -0.1f;
1327 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
1328 jpgImg.getImageHandle()),
1329 JPEGR_NO_ERROR)
1330 << "fail, API allows bad metadata gamma";
1331
1332 metadata = good_metadata;
1333 metadata.offsetSdr = -0.1f;
1334 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
1335 jpgImg.getImageHandle()),
1336 JPEGR_NO_ERROR)
1337 << "fail, API allows bad metadata offset sdr";
1338
1339 metadata = good_metadata;
1340 metadata.offsetHdr = -0.1f;
1341 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
1342 jpgImg.getImageHandle()),
1343 JPEGR_NO_ERROR)
1344 << "fail, API allows bad metadata offset hdr";
1345
1346 metadata = good_metadata;
1347 metadata.hdrCapacityMax = 0.5f;
1348 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
1349 jpgImg.getImageHandle()),
1350 JPEGR_NO_ERROR)
1351 << "fail, API allows bad metadata hdr capacity max";
1352
1353 metadata = good_metadata;
1354 metadata.hdrCapacityMin = 0.5f;
1355 ASSERT_NE(uHdrLib.encodeJPEGR(jpgImg.getImageHandle(), jpgImg.getImageHandle(), &metadata,
1356 jpgImg.getImageHandle()),
1357 JPEGR_NO_ERROR)
1358 << "fail, API allows bad metadata hdr capacity min";
1359 }
1360
1361 /* Test Decode API invalid arguments */
TEST(JpegRTest,DecodeAPIWithInvalidArgs)1362 TEST(JpegRTest, DecodeAPIWithInvalidArgs) {
1363 JpegR uHdrLib;
1364
1365 UhdrCompressedStructWrapper jpgImg(16, 16);
1366 jpegr_uncompressed_struct destImage{};
1367 size_t outSize = 16 * 16 * 8;
1368 std::unique_ptr<uint8_t[]> data = std::make_unique<uint8_t[]>(outSize);
1369 destImage.data = data.get();
1370
1371 // test jpegr image
1372 ASSERT_NE(uHdrLib.decodeJPEGR(nullptr, &destImage), JPEGR_NO_ERROR)
1373 << "fail, API allows nullptr for jpegr img";
1374 ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), &destImage), JPEGR_NO_ERROR)
1375 << "fail, API allows nullptr for jpegr img";
1376 ASSERT_TRUE(jpgImg.allocateMemory());
1377
1378 // test dest image
1379 ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), nullptr), JPEGR_NO_ERROR)
1380 << "fail, API allows nullptr for dest";
1381 destImage.data = nullptr;
1382 ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), &destImage), JPEGR_NO_ERROR)
1383 << "fail, API allows nullptr for dest";
1384 destImage.data = data.get();
1385
1386 // test max display boost
1387 ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), &destImage, 0.5), JPEGR_NO_ERROR)
1388 << "fail, API allows invalid max display boost";
1389
1390 // test output format
1391 ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), &destImage, FLT_MAX, nullptr,
1392 static_cast<ultrahdr_output_format>(-1)),
1393 JPEGR_NO_ERROR)
1394 << "fail, API allows invalid output format";
1395 ASSERT_NE(uHdrLib.decodeJPEGR(jpgImg.getImageHandle(), &destImage, FLT_MAX, nullptr,
1396 static_cast<ultrahdr_output_format>(ULTRAHDR_OUTPUT_MAX + 1)),
1397 JPEGR_NO_ERROR)
1398 << "fail, API allows invalid output format";
1399 }
1400
TEST(JpegRTest,writeXmpThenRead)1401 TEST(JpegRTest, writeXmpThenRead) {
1402 ultrahdr_metadata_struct metadata_expected;
1403 metadata_expected.version = "1.0";
1404 metadata_expected.maxContentBoost = 1.25f;
1405 metadata_expected.minContentBoost = 0.75f;
1406 metadata_expected.gamma = 1.0f;
1407 metadata_expected.offsetSdr = 0.0f;
1408 metadata_expected.offsetHdr = 0.0f;
1409 metadata_expected.hdrCapacityMin = 1.0f;
1410 metadata_expected.hdrCapacityMax = metadata_expected.maxContentBoost;
1411 const std::string nameSpace = "http://ns.adobe.com/xap/1.0/\0";
1412 const int nameSpaceLength = nameSpace.size() + 1; // need to count the null terminator
1413
1414 std::string xmp = generateXmpForSecondaryImage(metadata_expected);
1415
1416 std::vector<uint8_t> xmpData;
1417 xmpData.reserve(nameSpaceLength + xmp.size());
1418 xmpData.insert(xmpData.end(), reinterpret_cast<const uint8_t*>(nameSpace.c_str()),
1419 reinterpret_cast<const uint8_t*>(nameSpace.c_str()) + nameSpaceLength);
1420 xmpData.insert(xmpData.end(), reinterpret_cast<const uint8_t*>(xmp.c_str()),
1421 reinterpret_cast<const uint8_t*>(xmp.c_str()) + xmp.size());
1422
1423 ultrahdr_metadata_struct metadata_read;
1424 EXPECT_TRUE(getMetadataFromXMP(xmpData.data(), xmpData.size(), &metadata_read));
1425 EXPECT_FLOAT_EQ(metadata_expected.maxContentBoost, metadata_read.maxContentBoost);
1426 EXPECT_FLOAT_EQ(metadata_expected.minContentBoost, metadata_read.minContentBoost);
1427 EXPECT_FLOAT_EQ(metadata_expected.gamma, metadata_read.gamma);
1428 EXPECT_FLOAT_EQ(metadata_expected.offsetSdr, metadata_read.offsetSdr);
1429 EXPECT_FLOAT_EQ(metadata_expected.offsetHdr, metadata_read.offsetHdr);
1430 EXPECT_FLOAT_EQ(metadata_expected.hdrCapacityMin, metadata_read.hdrCapacityMin);
1431 EXPECT_FLOAT_EQ(metadata_expected.hdrCapacityMax, metadata_read.hdrCapacityMax);
1432 }
1433
1434 class JpegRAPIEncodeAndDecodeTest
1435 : public ::testing::TestWithParam<std::tuple<ultrahdr_color_gamut, ultrahdr_color_gamut>> {
1436 public:
JpegRAPIEncodeAndDecodeTest()1437 JpegRAPIEncodeAndDecodeTest()
1438 : mP010ColorGamut(std::get<0>(GetParam())), mYuv420ColorGamut(std::get<1>(GetParam())){};
1439
1440 const ultrahdr_color_gamut mP010ColorGamut;
1441 const ultrahdr_color_gamut mYuv420ColorGamut;
1442 };
1443
1444 /* Test Encode API-0 and Decode */
TEST_P(JpegRAPIEncodeAndDecodeTest,EncodeAPI0AndDecodeTest)1445 TEST_P(JpegRAPIEncodeAndDecodeTest, EncodeAPI0AndDecodeTest) {
1446 // reference encode
1447 UhdrUnCompressedStructWrapper rawImg(kImageWidth, kImageHeight, YCbCr_p010);
1448 ASSERT_TRUE(rawImg.setImageColorGamut(mP010ColorGamut));
1449 ASSERT_TRUE(rawImg.allocateMemory());
1450 ASSERT_TRUE(rawImg.loadRawResource(kYCbCrP010FileName));
1451 UhdrCompressedStructWrapper jpgImg(kImageWidth, kImageHeight);
1452 ASSERT_TRUE(jpgImg.allocateMemory());
1453 JpegR uHdrLib;
1454 ASSERT_EQ(
1455 uHdrLib.encodeJPEGR(rawImg.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1456 jpgImg.getImageHandle(), kQuality, nullptr),
1457 JPEGR_NO_ERROR);
1458
1459 uhdr_codec_private_t* obj = uhdr_create_encoder();
1460 uhdr_raw_image_t uhdrRawImg{};
1461 uhdrRawImg.fmt = UHDR_IMG_FMT_24bppYCbCrP010;
1462 uhdrRawImg.cg = map_internal_cg_to_cg(mP010ColorGamut);
1463 uhdrRawImg.ct = map_internal_ct_to_ct(ultrahdr_transfer_function::ULTRAHDR_TF_HLG);
1464 uhdrRawImg.range = UHDR_CR_UNSPECIFIED;
1465 uhdrRawImg.w = kImageWidth;
1466 uhdrRawImg.h = kImageHeight;
1467 uhdrRawImg.planes[UHDR_PLANE_Y] = rawImg.getImageHandle()->data;
1468 uhdrRawImg.stride[UHDR_PLANE_Y] = kImageWidth;
1469 uhdrRawImg.planes[UHDR_PLANE_UV] =
1470 ((uint8_t*)(rawImg.getImageHandle()->data)) + kImageWidth * kImageHeight * 2;
1471 uhdrRawImg.stride[UHDR_PLANE_UV] = kImageWidth;
1472 uhdr_error_info_t status = uhdr_enc_set_raw_image(obj, &uhdrRawImg, UHDR_HDR_IMG);
1473 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1474 status = uhdr_enc_set_quality(obj, kQuality, UHDR_BASE_IMG);
1475 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1476 status = uhdr_encode(obj);
1477 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1478 uhdr_compressed_image_t* compressedImage = uhdr_get_encoded_stream(obj);
1479 ASSERT_NE(nullptr, compressedImage);
1480 ASSERT_EQ(jpgImg.getImageHandle()->length, compressedImage->data_sz);
1481 ASSERT_EQ(0,
1482 memcmp(jpgImg.getImageHandle()->data, compressedImage->data, compressedImage->data_sz));
1483 uhdr_release_encoder(obj);
1484
1485 // encode with luma stride set
1486 {
1487 UhdrUnCompressedStructWrapper rawImg2(kImageWidth, kImageHeight, YCbCr_p010);
1488 ASSERT_TRUE(rawImg2.setImageColorGamut(mP010ColorGamut));
1489 ASSERT_TRUE(rawImg2.setImageStride(kImageWidth + 18, 0));
1490 ASSERT_TRUE(rawImg2.allocateMemory());
1491 ASSERT_TRUE(rawImg2.loadRawResource(kYCbCrP010FileName));
1492 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1493 ASSERT_TRUE(jpgImg2.allocateMemory());
1494 ASSERT_EQ(
1495 uHdrLib.encodeJPEGR(rawImg2.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1496 jpgImg2.getImageHandle(), kQuality, nullptr),
1497 JPEGR_NO_ERROR);
1498 auto jpg1 = jpgImg.getImageHandle();
1499 auto jpg2 = jpgImg2.getImageHandle();
1500 ASSERT_EQ(jpg1->length, jpg2->length);
1501 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1502 }
1503 // encode with luma and chroma stride set
1504 {
1505 UhdrUnCompressedStructWrapper rawImg2(kImageWidth, kImageHeight, YCbCr_p010);
1506 ASSERT_TRUE(rawImg2.setImageColorGamut(mP010ColorGamut));
1507 ASSERT_TRUE(rawImg2.setImageStride(kImageWidth + 18, kImageWidth + 28));
1508 ASSERT_TRUE(rawImg2.setChromaMode(false));
1509 ASSERT_TRUE(rawImg2.allocateMemory());
1510 ASSERT_TRUE(rawImg2.loadRawResource(kYCbCrP010FileName));
1511 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1512 ASSERT_TRUE(jpgImg2.allocateMemory());
1513 ASSERT_EQ(
1514 uHdrLib.encodeJPEGR(rawImg2.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1515 jpgImg2.getImageHandle(), kQuality, nullptr),
1516 JPEGR_NO_ERROR);
1517 auto jpg1 = jpgImg.getImageHandle();
1518 auto jpg2 = jpgImg2.getImageHandle();
1519 ASSERT_EQ(jpg1->length, jpg2->length);
1520 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1521
1522 uhdr_codec_private_t* obj = uhdr_create_encoder();
1523 uhdr_raw_image_t uhdrRawImg{};
1524 uhdrRawImg.fmt = UHDR_IMG_FMT_24bppYCbCrP010;
1525 uhdrRawImg.cg = map_internal_cg_to_cg(mP010ColorGamut);
1526 uhdrRawImg.ct = map_internal_ct_to_ct(ultrahdr_transfer_function::ULTRAHDR_TF_HLG);
1527 uhdrRawImg.range = UHDR_CR_UNSPECIFIED;
1528 uhdrRawImg.w = kImageWidth;
1529 uhdrRawImg.h = kImageHeight;
1530 uhdrRawImg.planes[UHDR_PLANE_Y] = rawImg2.getImageHandle()->data;
1531 uhdrRawImg.stride[UHDR_PLANE_Y] = rawImg2.getImageHandle()->luma_stride;
1532 uhdrRawImg.planes[UHDR_PLANE_UV] = rawImg2.getImageHandle()->chroma_data;
1533 uhdrRawImg.stride[UHDR_PLANE_UV] = rawImg2.getImageHandle()->chroma_stride;
1534 uhdr_error_info_t status = uhdr_enc_set_raw_image(obj, &uhdrRawImg, UHDR_HDR_IMG);
1535 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1536 status = uhdr_enc_set_quality(obj, kQuality, UHDR_BASE_IMG);
1537 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1538 status = uhdr_encode(obj);
1539 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1540 uhdr_compressed_image_t* compressedImage = uhdr_get_encoded_stream(obj);
1541 ASSERT_NE(nullptr, compressedImage);
1542 ASSERT_EQ(jpg1->length, compressedImage->data_sz);
1543 ASSERT_EQ(0, memcmp(jpg1->data, compressedImage->data, jpg1->length));
1544 uhdr_release_encoder(obj);
1545 }
1546 // encode with chroma stride set
1547 {
1548 UhdrUnCompressedStructWrapper rawImg2(kImageWidth, kImageHeight, YCbCr_p010);
1549 ASSERT_TRUE(rawImg2.setImageColorGamut(mP010ColorGamut));
1550 ASSERT_TRUE(rawImg2.setImageStride(0, kImageWidth + 34));
1551 ASSERT_TRUE(rawImg2.setChromaMode(false));
1552 ASSERT_TRUE(rawImg2.allocateMemory());
1553 ASSERT_TRUE(rawImg2.loadRawResource(kYCbCrP010FileName));
1554 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1555 ASSERT_TRUE(jpgImg2.allocateMemory());
1556 ASSERT_EQ(
1557 uHdrLib.encodeJPEGR(rawImg2.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1558 jpgImg2.getImageHandle(), kQuality, nullptr),
1559 JPEGR_NO_ERROR);
1560 auto jpg1 = jpgImg.getImageHandle();
1561 auto jpg2 = jpgImg2.getImageHandle();
1562 ASSERT_EQ(jpg1->length, jpg2->length);
1563 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1564 }
1565 // encode with luma and chroma stride set but no chroma ptr
1566 {
1567 UhdrUnCompressedStructWrapper rawImg2(kImageWidth, kImageHeight, YCbCr_p010);
1568 ASSERT_TRUE(rawImg2.setImageColorGamut(mP010ColorGamut));
1569 ASSERT_TRUE(rawImg2.setImageStride(kImageWidth, kImageWidth + 38));
1570 ASSERT_TRUE(rawImg2.allocateMemory());
1571 ASSERT_TRUE(rawImg2.loadRawResource(kYCbCrP010FileName));
1572 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1573 ASSERT_TRUE(jpgImg2.allocateMemory());
1574 ASSERT_EQ(
1575 uHdrLib.encodeJPEGR(rawImg2.getImageHandle(), ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1576 jpgImg2.getImageHandle(), kQuality, nullptr),
1577 JPEGR_NO_ERROR);
1578 auto jpg1 = jpgImg.getImageHandle();
1579 auto jpg2 = jpgImg2.getImageHandle();
1580 ASSERT_EQ(jpg1->length, jpg2->length);
1581 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1582 }
1583
1584 auto jpg1 = jpgImg.getImageHandle();
1585 #ifdef DUMP_OUTPUT
1586 if (!writeFile("encode_api0_output.jpeg", jpg1->data, jpg1->length)) {
1587 std::cerr << "unable to write output file" << std::endl;
1588 }
1589 #endif
1590
1591 ASSERT_NO_FATAL_FAILURE(decodeJpegRImg(jpg1, "decode_api0_output.rgb"));
1592 }
1593
1594 /* Test Encode API-1 and Decode */
TEST_P(JpegRAPIEncodeAndDecodeTest,EncodeAPI1AndDecodeTest)1595 TEST_P(JpegRAPIEncodeAndDecodeTest, EncodeAPI1AndDecodeTest) {
1596 UhdrUnCompressedStructWrapper rawImgP010(kImageWidth, kImageHeight, YCbCr_p010);
1597 ASSERT_TRUE(rawImgP010.setImageColorGamut(mP010ColorGamut));
1598 ASSERT_TRUE(rawImgP010.allocateMemory());
1599 ASSERT_TRUE(rawImgP010.loadRawResource(kYCbCrP010FileName));
1600 UhdrUnCompressedStructWrapper rawImg420(kImageWidth, kImageHeight, YCbCr_420);
1601 ASSERT_TRUE(rawImg420.setImageColorGamut(mYuv420ColorGamut));
1602 ASSERT_TRUE(rawImg420.allocateMemory());
1603 ASSERT_TRUE(rawImg420.loadRawResource(kYCbCr420FileName));
1604 UhdrCompressedStructWrapper jpgImg(kImageWidth, kImageHeight);
1605 ASSERT_TRUE(jpgImg.allocateMemory());
1606 JpegR uHdrLib;
1607 ASSERT_EQ(uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), rawImg420.getImageHandle(),
1608 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1609 jpgImg.getImageHandle(), kQuality, nullptr),
1610 JPEGR_NO_ERROR);
1611 // encode with luma stride set p010
1612 {
1613 UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
1614 ASSERT_TRUE(rawImg2P010.setImageColorGamut(mP010ColorGamut));
1615 ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, 0));
1616 ASSERT_TRUE(rawImg2P010.allocateMemory());
1617 ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
1618 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1619 ASSERT_TRUE(jpgImg2.allocateMemory());
1620 ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(),
1621 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1622 jpgImg2.getImageHandle(), kQuality, nullptr),
1623 JPEGR_NO_ERROR);
1624 auto jpg1 = jpgImg.getImageHandle();
1625 auto jpg2 = jpgImg2.getImageHandle();
1626 ASSERT_EQ(jpg1->length, jpg2->length);
1627 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1628 }
1629 // encode with luma and chroma stride set p010
1630 {
1631 UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
1632 ASSERT_TRUE(rawImg2P010.setImageColorGamut(mP010ColorGamut));
1633 ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, kImageWidth + 256));
1634 ASSERT_TRUE(rawImg2P010.setChromaMode(false));
1635 ASSERT_TRUE(rawImg2P010.allocateMemory());
1636 ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
1637 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1638 ASSERT_TRUE(jpgImg2.allocateMemory());
1639 ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(),
1640 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1641 jpgImg2.getImageHandle(), kQuality, nullptr),
1642 JPEGR_NO_ERROR);
1643 auto jpg1 = jpgImg.getImageHandle();
1644 auto jpg2 = jpgImg2.getImageHandle();
1645 ASSERT_EQ(jpg1->length, jpg2->length);
1646 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1647 }
1648 // encode with chroma stride set p010
1649 {
1650 UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
1651 ASSERT_TRUE(rawImg2P010.setImageColorGamut(mP010ColorGamut));
1652 ASSERT_TRUE(rawImg2P010.setImageStride(0, kImageWidth + 64));
1653 ASSERT_TRUE(rawImg2P010.setChromaMode(false));
1654 ASSERT_TRUE(rawImg2P010.allocateMemory());
1655 ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
1656 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1657 ASSERT_TRUE(jpgImg2.allocateMemory());
1658 ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(),
1659 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1660 jpgImg2.getImageHandle(), kQuality, nullptr),
1661 JPEGR_NO_ERROR);
1662 auto jpg1 = jpgImg.getImageHandle();
1663 auto jpg2 = jpgImg2.getImageHandle();
1664 ASSERT_EQ(jpg1->length, jpg2->length);
1665 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1666 }
1667 // encode with luma and chroma stride set but no chroma ptr p010
1668 {
1669 UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
1670 ASSERT_TRUE(rawImg2P010.setImageColorGamut(mP010ColorGamut));
1671 ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 64, kImageWidth + 256));
1672 ASSERT_TRUE(rawImg2P010.allocateMemory());
1673 ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
1674 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1675 ASSERT_TRUE(jpgImg2.allocateMemory());
1676 ASSERT_EQ(uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(),
1677 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1678 jpgImg2.getImageHandle(), kQuality, nullptr),
1679 JPEGR_NO_ERROR);
1680 auto jpg1 = jpgImg.getImageHandle();
1681 auto jpg2 = jpgImg2.getImageHandle();
1682 ASSERT_EQ(jpg1->length, jpg2->length);
1683 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1684 }
1685 // encode with luma stride set 420
1686 {
1687 UhdrUnCompressedStructWrapper rawImg2420(kImageWidth, kImageHeight, YCbCr_420);
1688 ASSERT_TRUE(rawImg2420.setImageColorGamut(mYuv420ColorGamut));
1689 ASSERT_TRUE(rawImg2420.setImageStride(kImageWidth + 14, 0));
1690 ASSERT_TRUE(rawImg2420.allocateMemory());
1691 ASSERT_TRUE(rawImg2420.loadRawResource(kYCbCr420FileName));
1692 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1693 ASSERT_TRUE(jpgImg2.allocateMemory());
1694 ASSERT_EQ(uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), rawImg2420.getImageHandle(),
1695 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1696 jpgImg2.getImageHandle(), kQuality, nullptr),
1697 JPEGR_NO_ERROR);
1698 auto jpg1 = jpgImg.getImageHandle();
1699 auto jpg2 = jpgImg2.getImageHandle();
1700 ASSERT_EQ(jpg1->length, jpg2->length);
1701 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1702 }
1703 // encode with luma and chroma stride set 420
1704 {
1705 UhdrUnCompressedStructWrapper rawImg2420(kImageWidth, kImageHeight, YCbCr_420);
1706 ASSERT_TRUE(rawImg2420.setImageColorGamut(mYuv420ColorGamut));
1707 ASSERT_TRUE(rawImg2420.setImageStride(kImageWidth + 46, kImageWidth / 2 + 34));
1708 ASSERT_TRUE(rawImg2420.setChromaMode(false));
1709 ASSERT_TRUE(rawImg2420.allocateMemory());
1710 ASSERT_TRUE(rawImg2420.loadRawResource(kYCbCr420FileName));
1711 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1712 ASSERT_TRUE(jpgImg2.allocateMemory());
1713 ASSERT_EQ(uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), rawImg2420.getImageHandle(),
1714 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1715 jpgImg2.getImageHandle(), kQuality, nullptr),
1716 JPEGR_NO_ERROR);
1717 auto jpg1 = jpgImg.getImageHandle();
1718 auto jpg2 = jpgImg2.getImageHandle();
1719 ASSERT_EQ(jpg1->length, jpg2->length);
1720 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1721
1722 uhdr_codec_private_t* obj = uhdr_create_encoder();
1723 uhdr_raw_image_t uhdrRawImg{};
1724 uhdrRawImg.fmt = UHDR_IMG_FMT_24bppYCbCrP010;
1725 uhdrRawImg.cg = map_internal_cg_to_cg(mP010ColorGamut);
1726 uhdrRawImg.ct = map_internal_ct_to_ct(ultrahdr_transfer_function::ULTRAHDR_TF_HLG);
1727 uhdrRawImg.range = UHDR_CR_UNSPECIFIED;
1728 uhdrRawImg.w = kImageWidth;
1729 uhdrRawImg.h = kImageHeight;
1730 uhdrRawImg.planes[UHDR_PLANE_Y] = rawImgP010.getImageHandle()->data;
1731 uhdrRawImg.stride[UHDR_PLANE_Y] = kImageWidth;
1732 uhdrRawImg.planes[UHDR_PLANE_UV] =
1733 ((uint8_t*)(rawImgP010.getImageHandle()->data)) + kImageWidth * kImageHeight * 2;
1734 uhdrRawImg.stride[UHDR_PLANE_UV] = kImageWidth;
1735 uhdr_error_info_t status = uhdr_enc_set_raw_image(obj, &uhdrRawImg, UHDR_HDR_IMG);
1736 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1737
1738 uhdrRawImg.fmt = UHDR_IMG_FMT_12bppYCbCr420;
1739 uhdrRawImg.cg = map_internal_cg_to_cg(mYuv420ColorGamut);
1740 uhdrRawImg.ct = map_internal_ct_to_ct(ultrahdr_transfer_function::ULTRAHDR_TF_SRGB);
1741 uhdrRawImg.range = UHDR_CR_UNSPECIFIED;
1742 uhdrRawImg.w = kImageWidth;
1743 uhdrRawImg.h = kImageHeight;
1744 uhdrRawImg.planes[UHDR_PLANE_Y] = rawImg2420.getImageHandle()->data;
1745 uhdrRawImg.stride[UHDR_PLANE_Y] = rawImg2420.getImageHandle()->luma_stride;
1746 uhdrRawImg.planes[UHDR_PLANE_U] = rawImg2420.getImageHandle()->chroma_data;
1747 uhdrRawImg.stride[UHDR_PLANE_U] = rawImg2420.getImageHandle()->chroma_stride;
1748 uhdrRawImg.planes[UHDR_PLANE_V] = ((uint8_t*)(rawImg2420.getImageHandle()->chroma_data)) +
1749 rawImg2420.getImageHandle()->chroma_stride * kImageHeight / 2;
1750 uhdrRawImg.stride[UHDR_PLANE_V] = rawImg2420.getImageHandle()->chroma_stride;
1751 status = uhdr_enc_set_raw_image(obj, &uhdrRawImg, UHDR_SDR_IMG);
1752 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1753
1754 status = uhdr_enc_set_quality(obj, kQuality, UHDR_BASE_IMG);
1755 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1756 status = uhdr_encode(obj);
1757 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1758 uhdr_compressed_image_t* compressedImage = uhdr_get_encoded_stream(obj);
1759 ASSERT_NE(nullptr, compressedImage);
1760 ASSERT_EQ(jpgImg.getImageHandle()->length, compressedImage->data_sz);
1761 ASSERT_EQ(
1762 0, memcmp(jpgImg.getImageHandle()->data, compressedImage->data, compressedImage->data_sz));
1763 uhdr_release_encoder(obj);
1764 }
1765 // encode with chroma stride set 420
1766 {
1767 UhdrUnCompressedStructWrapper rawImg2420(kImageWidth, kImageHeight, YCbCr_420);
1768 ASSERT_TRUE(rawImg2420.setImageColorGamut(mYuv420ColorGamut));
1769 ASSERT_TRUE(rawImg2420.setImageStride(0, kImageWidth / 2 + 38));
1770 ASSERT_TRUE(rawImg2420.setChromaMode(false));
1771 ASSERT_TRUE(rawImg2420.allocateMemory());
1772 ASSERT_TRUE(rawImg2420.loadRawResource(kYCbCr420FileName));
1773 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1774 ASSERT_TRUE(jpgImg2.allocateMemory());
1775 ASSERT_EQ(uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), rawImg2420.getImageHandle(),
1776 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1777 jpgImg2.getImageHandle(), kQuality, nullptr),
1778 JPEGR_NO_ERROR);
1779 auto jpg1 = jpgImg.getImageHandle();
1780 auto jpg2 = jpgImg2.getImageHandle();
1781 ASSERT_EQ(jpg1->length, jpg2->length);
1782 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1783 }
1784 // encode with luma and chroma stride set but no chroma ptr 420
1785 {
1786 UhdrUnCompressedStructWrapper rawImg2420(kImageWidth, kImageHeight, YCbCr_420);
1787 ASSERT_TRUE(rawImg2420.setImageColorGamut(mYuv420ColorGamut));
1788 ASSERT_TRUE(rawImg2420.setImageStride(kImageWidth + 26, kImageWidth / 2 + 44));
1789 ASSERT_TRUE(rawImg2420.allocateMemory());
1790 ASSERT_TRUE(rawImg2420.loadRawResource(kYCbCr420FileName));
1791 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1792 ASSERT_TRUE(jpgImg2.allocateMemory());
1793 ASSERT_EQ(uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), rawImg2420.getImageHandle(),
1794 ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
1795 jpgImg2.getImageHandle(), kQuality, nullptr),
1796 JPEGR_NO_ERROR);
1797 auto jpg1 = jpgImg.getImageHandle();
1798 auto jpg2 = jpgImg2.getImageHandle();
1799 ASSERT_EQ(jpg1->length, jpg2->length);
1800 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1801 }
1802
1803 auto jpg1 = jpgImg.getImageHandle();
1804
1805 #ifdef DUMP_OUTPUT
1806 if (!writeFile("encode_api1_output.jpeg", jpg1->data, jpg1->length)) {
1807 std::cerr << "unable to write output file" << std::endl;
1808 }
1809 #endif
1810
1811 ASSERT_NO_FATAL_FAILURE(decodeJpegRImg(jpg1, "decode_api1_output.rgb"));
1812 }
1813
1814 /* Test Encode API-2 and Decode */
TEST_P(JpegRAPIEncodeAndDecodeTest,EncodeAPI2AndDecodeTest)1815 TEST_P(JpegRAPIEncodeAndDecodeTest, EncodeAPI2AndDecodeTest) {
1816 UhdrUnCompressedStructWrapper rawImgP010(kImageWidth, kImageHeight, YCbCr_p010);
1817 ASSERT_TRUE(rawImgP010.setImageColorGamut(mP010ColorGamut));
1818 ASSERT_TRUE(rawImgP010.allocateMemory());
1819 ASSERT_TRUE(rawImgP010.loadRawResource(kYCbCrP010FileName));
1820 UhdrUnCompressedStructWrapper rawImg420(kImageWidth, kImageHeight, YCbCr_420);
1821 ASSERT_TRUE(rawImg420.setImageColorGamut(mYuv420ColorGamut));
1822 ASSERT_TRUE(rawImg420.allocateMemory());
1823 ASSERT_TRUE(rawImg420.loadRawResource(kYCbCr420FileName));
1824 UhdrCompressedStructWrapper jpgImg(kImageWidth, kImageHeight);
1825 ASSERT_TRUE(jpgImg.allocateMemory());
1826 UhdrCompressedStructWrapper jpgSdr(kImageWidth, kImageHeight);
1827 ASSERT_TRUE(jpgSdr.allocateMemory());
1828 auto sdr = jpgSdr.getImageHandle();
1829 ASSERT_TRUE(readFile(kSdrJpgFileName, sdr->data, sdr->maxLength, sdr->length));
1830 JpegR uHdrLib;
1831 ASSERT_EQ(
1832 uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), rawImg420.getImageHandle(), sdr,
1833 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
1834 JPEGR_NO_ERROR);
1835 // encode with luma stride set
1836 {
1837 UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
1838 ASSERT_TRUE(rawImg2P010.setImageColorGamut(mP010ColorGamut));
1839 ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, 0));
1840 ASSERT_TRUE(rawImg2P010.allocateMemory());
1841 ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
1842 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1843 ASSERT_TRUE(jpgImg2.allocateMemory());
1844 ASSERT_EQ(
1845 uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(), sdr,
1846 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
1847 JPEGR_NO_ERROR);
1848 auto jpg1 = jpgImg.getImageHandle();
1849 auto jpg2 = jpgImg2.getImageHandle();
1850 ASSERT_EQ(jpg1->length, jpg2->length);
1851 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1852 }
1853 // encode with luma and chroma stride set
1854 {
1855 UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
1856 ASSERT_TRUE(rawImg2P010.setImageColorGamut(mP010ColorGamut));
1857 ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, kImageWidth + 256));
1858 ASSERT_TRUE(rawImg2P010.setChromaMode(false));
1859 ASSERT_TRUE(rawImg2P010.allocateMemory());
1860 ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
1861 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1862 ASSERT_TRUE(jpgImg2.allocateMemory());
1863 ASSERT_EQ(
1864 uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(), sdr,
1865 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
1866 JPEGR_NO_ERROR);
1867 auto jpg1 = jpgImg.getImageHandle();
1868 auto jpg2 = jpgImg2.getImageHandle();
1869 ASSERT_EQ(jpg1->length, jpg2->length);
1870 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1871 }
1872 // encode with chroma stride set
1873 {
1874 UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
1875 ASSERT_TRUE(rawImg2P010.setImageColorGamut(mP010ColorGamut));
1876 ASSERT_TRUE(rawImg2P010.setImageStride(0, kImageWidth + 64));
1877 ASSERT_TRUE(rawImg2P010.setChromaMode(false));
1878 ASSERT_TRUE(rawImg2P010.allocateMemory());
1879 ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
1880 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1881 ASSERT_TRUE(jpgImg2.allocateMemory());
1882 ASSERT_EQ(
1883 uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), rawImg420.getImageHandle(), sdr,
1884 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
1885 JPEGR_NO_ERROR);
1886 auto jpg1 = jpgImg.getImageHandle();
1887 auto jpg2 = jpgImg2.getImageHandle();
1888 ASSERT_EQ(jpg1->length, jpg2->length);
1889 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1890 }
1891 // encode with luma stride set
1892 {
1893 UhdrUnCompressedStructWrapper rawImg2420(kImageWidth, kImageHeight, YCbCr_420);
1894 ASSERT_TRUE(rawImg2420.setImageColorGamut(mYuv420ColorGamut));
1895 ASSERT_TRUE(rawImg2420.setImageStride(kImageWidth + 128, 0));
1896 ASSERT_TRUE(rawImg2420.allocateMemory());
1897 ASSERT_TRUE(rawImg2420.loadRawResource(kYCbCr420FileName));
1898 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1899 ASSERT_TRUE(jpgImg2.allocateMemory());
1900 ASSERT_EQ(
1901 uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), rawImg2420.getImageHandle(), sdr,
1902 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
1903 JPEGR_NO_ERROR);
1904 auto jpg1 = jpgImg.getImageHandle();
1905 auto jpg2 = jpgImg2.getImageHandle();
1906 ASSERT_EQ(jpg1->length, jpg2->length);
1907 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1908 }
1909 // encode with luma and chroma stride set
1910 {
1911 UhdrUnCompressedStructWrapper rawImg2420(kImageWidth, kImageHeight, YCbCr_420);
1912 ASSERT_TRUE(rawImg2420.setImageColorGamut(mYuv420ColorGamut));
1913 ASSERT_TRUE(rawImg2420.setImageStride(kImageWidth + 128, kImageWidth + 256));
1914 ASSERT_TRUE(rawImg2420.setChromaMode(false));
1915 ASSERT_TRUE(rawImg2420.allocateMemory());
1916 ASSERT_TRUE(rawImg2420.loadRawResource(kYCbCr420FileName));
1917 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1918 ASSERT_TRUE(jpgImg2.allocateMemory());
1919 ASSERT_EQ(
1920 uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), rawImg2420.getImageHandle(), sdr,
1921 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
1922 JPEGR_NO_ERROR);
1923 auto jpg1 = jpgImg.getImageHandle();
1924 auto jpg2 = jpgImg2.getImageHandle();
1925 ASSERT_EQ(jpg1->length, jpg2->length);
1926 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1927
1928 uhdr_codec_private_t* obj = uhdr_create_encoder();
1929 uhdr_raw_image_t uhdrRawImg{};
1930 uhdrRawImg.fmt = UHDR_IMG_FMT_24bppYCbCrP010;
1931 uhdrRawImg.cg = map_internal_cg_to_cg(mP010ColorGamut);
1932 uhdrRawImg.ct = map_internal_ct_to_ct(ultrahdr_transfer_function::ULTRAHDR_TF_HLG);
1933 uhdrRawImg.range = UHDR_CR_UNSPECIFIED;
1934 uhdrRawImg.w = kImageWidth;
1935 uhdrRawImg.h = kImageHeight;
1936 uhdrRawImg.planes[UHDR_PLANE_Y] = rawImgP010.getImageHandle()->data;
1937 uhdrRawImg.stride[UHDR_PLANE_Y] = kImageWidth;
1938 uhdrRawImg.planes[UHDR_PLANE_UV] =
1939 ((uint8_t*)(rawImgP010.getImageHandle()->data)) + kImageWidth * kImageHeight * 2;
1940 uhdrRawImg.stride[UHDR_PLANE_UV] = kImageWidth;
1941 uhdr_error_info_t status = uhdr_enc_set_raw_image(obj, &uhdrRawImg, UHDR_HDR_IMG);
1942 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1943
1944 uhdrRawImg.fmt = UHDR_IMG_FMT_12bppYCbCr420;
1945 uhdrRawImg.cg = map_internal_cg_to_cg(mYuv420ColorGamut);
1946 uhdrRawImg.ct = map_internal_ct_to_ct(ultrahdr_transfer_function::ULTRAHDR_TF_SRGB);
1947 uhdrRawImg.range = UHDR_CR_UNSPECIFIED;
1948 uhdrRawImg.w = kImageWidth;
1949 uhdrRawImg.h = kImageHeight;
1950 uhdrRawImg.planes[UHDR_PLANE_Y] = rawImg2420.getImageHandle()->data;
1951 uhdrRawImg.stride[UHDR_PLANE_Y] = rawImg2420.getImageHandle()->luma_stride;
1952 uhdrRawImg.planes[UHDR_PLANE_U] = rawImg2420.getImageHandle()->chroma_data;
1953 uhdrRawImg.stride[UHDR_PLANE_U] = rawImg2420.getImageHandle()->chroma_stride;
1954 uhdrRawImg.planes[UHDR_PLANE_V] = ((uint8_t*)(rawImg2420.getImageHandle()->chroma_data)) +
1955 rawImg2420.getImageHandle()->chroma_stride * kImageHeight / 2;
1956 uhdrRawImg.stride[UHDR_PLANE_V] = rawImg2420.getImageHandle()->chroma_stride;
1957 status = uhdr_enc_set_raw_image(obj, &uhdrRawImg, UHDR_SDR_IMG);
1958 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1959
1960 uhdr_compressed_image_t uhdrCompressedImg;
1961 uhdrCompressedImg.data = sdr->data;
1962 uhdrCompressedImg.data_sz = sdr->length;
1963 uhdrCompressedImg.capacity = sdr->length;
1964 uhdrCompressedImg.cg = map_internal_cg_to_cg(sdr->colorGamut);
1965 uhdrCompressedImg.ct = UHDR_CT_UNSPECIFIED;
1966 uhdrCompressedImg.range = UHDR_CR_UNSPECIFIED;
1967 status = uhdr_enc_set_compressed_image(obj, &uhdrCompressedImg, UHDR_SDR_IMG);
1968 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1969
1970 status = uhdr_enc_set_quality(obj, kQuality, UHDR_BASE_IMG);
1971 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1972 status = uhdr_encode(obj);
1973 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
1974 uhdr_compressed_image_t* compressedImage = uhdr_get_encoded_stream(obj);
1975 ASSERT_NE(nullptr, compressedImage);
1976 ASSERT_EQ(jpgImg.getImageHandle()->length, compressedImage->data_sz);
1977 ASSERT_EQ(
1978 0, memcmp(jpgImg.getImageHandle()->data, compressedImage->data, compressedImage->data_sz));
1979 uhdr_release_encoder(obj);
1980 }
1981 // encode with chroma stride set
1982 {
1983 UhdrUnCompressedStructWrapper rawImg2420(kImageWidth, kImageHeight, YCbCr_420);
1984 ASSERT_TRUE(rawImg2420.setImageColorGamut(mYuv420ColorGamut));
1985 ASSERT_TRUE(rawImg2420.setImageStride(0, kImageWidth + 64));
1986 ASSERT_TRUE(rawImg2420.setChromaMode(false));
1987 ASSERT_TRUE(rawImg2420.allocateMemory());
1988 ASSERT_TRUE(rawImg2420.loadRawResource(kYCbCr420FileName));
1989 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
1990 ASSERT_TRUE(jpgImg2.allocateMemory());
1991 ASSERT_EQ(
1992 uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), rawImg2420.getImageHandle(), sdr,
1993 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
1994 JPEGR_NO_ERROR);
1995 auto jpg1 = jpgImg.getImageHandle();
1996 auto jpg2 = jpgImg2.getImageHandle();
1997 ASSERT_EQ(jpg1->length, jpg2->length);
1998 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
1999 }
2000
2001 auto jpg1 = jpgImg.getImageHandle();
2002
2003 #ifdef DUMP_OUTPUT
2004 if (!writeFile("encode_api2_output.jpeg", jpg1->data, jpg1->length)) {
2005 std::cerr << "unable to write output file" << std::endl;
2006 }
2007 #endif
2008
2009 ASSERT_NO_FATAL_FAILURE(decodeJpegRImg(jpg1, "decode_api2_output.rgb"));
2010 }
2011
2012 /* Test Encode API-3 and Decode */
TEST_P(JpegRAPIEncodeAndDecodeTest,EncodeAPI3AndDecodeTest)2013 TEST_P(JpegRAPIEncodeAndDecodeTest, EncodeAPI3AndDecodeTest) {
2014 UhdrUnCompressedStructWrapper rawImgP010(kImageWidth, kImageHeight, YCbCr_p010);
2015 ASSERT_TRUE(rawImgP010.setImageColorGamut(mP010ColorGamut));
2016 ASSERT_TRUE(rawImgP010.allocateMemory());
2017 ASSERT_TRUE(rawImgP010.loadRawResource(kYCbCrP010FileName));
2018 UhdrCompressedStructWrapper jpgImg(kImageWidth, kImageHeight);
2019 ASSERT_TRUE(jpgImg.allocateMemory());
2020 UhdrCompressedStructWrapper jpgSdr(kImageWidth, kImageHeight);
2021 ASSERT_TRUE(jpgSdr.allocateMemory());
2022 auto sdr = jpgSdr.getImageHandle();
2023 ASSERT_TRUE(readFile(kSdrJpgFileName, sdr->data, sdr->maxLength, sdr->length));
2024 JpegR uHdrLib;
2025 ASSERT_EQ(
2026 uHdrLib.encodeJPEGR(rawImgP010.getImageHandle(), sdr,
2027 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg.getImageHandle()),
2028 JPEGR_NO_ERROR);
2029 // encode with luma stride set
2030 {
2031 UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
2032 ASSERT_TRUE(rawImg2P010.setImageColorGamut(mP010ColorGamut));
2033 ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, 0));
2034 ASSERT_TRUE(rawImg2P010.allocateMemory());
2035 ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
2036 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
2037 ASSERT_TRUE(jpgImg2.allocateMemory());
2038 ASSERT_EQ(
2039 uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), sdr,
2040 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
2041 JPEGR_NO_ERROR);
2042 auto jpg1 = jpgImg.getImageHandle();
2043 auto jpg2 = jpgImg2.getImageHandle();
2044 ASSERT_EQ(jpg1->length, jpg2->length);
2045 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
2046 }
2047 // encode with luma and chroma stride set
2048 {
2049 UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
2050 ASSERT_TRUE(rawImg2P010.setImageColorGamut(mP010ColorGamut));
2051 ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 128, kImageWidth + 256));
2052 ASSERT_TRUE(rawImg2P010.setChromaMode(false));
2053 ASSERT_TRUE(rawImg2P010.allocateMemory());
2054 ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
2055 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
2056 ASSERT_TRUE(jpgImg2.allocateMemory());
2057 ASSERT_EQ(
2058 uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), sdr,
2059 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
2060 JPEGR_NO_ERROR);
2061 auto jpg1 = jpgImg.getImageHandle();
2062 auto jpg2 = jpgImg2.getImageHandle();
2063 ASSERT_EQ(jpg1->length, jpg2->length);
2064 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
2065 }
2066 // encode with chroma stride set
2067 {
2068 UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
2069 ASSERT_TRUE(rawImg2P010.setImageColorGamut(mP010ColorGamut));
2070 ASSERT_TRUE(rawImg2P010.setImageStride(0, kImageWidth + 64));
2071 ASSERT_TRUE(rawImg2P010.setChromaMode(false));
2072 ASSERT_TRUE(rawImg2P010.allocateMemory());
2073 ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
2074 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
2075 ASSERT_TRUE(jpgImg2.allocateMemory());
2076 ASSERT_EQ(
2077 uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), sdr,
2078 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
2079 JPEGR_NO_ERROR);
2080 auto jpg1 = jpgImg.getImageHandle();
2081 auto jpg2 = jpgImg2.getImageHandle();
2082 ASSERT_EQ(jpg1->length, jpg2->length);
2083 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
2084 }
2085 // encode with luma and chroma stride set and no chroma ptr
2086 {
2087 UhdrUnCompressedStructWrapper rawImg2P010(kImageWidth, kImageHeight, YCbCr_p010);
2088 ASSERT_TRUE(rawImg2P010.setImageColorGamut(mP010ColorGamut));
2089 ASSERT_TRUE(rawImg2P010.setImageStride(kImageWidth + 32, kImageWidth + 256));
2090 ASSERT_TRUE(rawImg2P010.allocateMemory());
2091 ASSERT_TRUE(rawImg2P010.loadRawResource(kYCbCrP010FileName));
2092 UhdrCompressedStructWrapper jpgImg2(kImageWidth, kImageHeight);
2093 ASSERT_TRUE(jpgImg2.allocateMemory());
2094 ASSERT_EQ(
2095 uHdrLib.encodeJPEGR(rawImg2P010.getImageHandle(), sdr,
2096 ultrahdr_transfer_function::ULTRAHDR_TF_HLG, jpgImg2.getImageHandle()),
2097 JPEGR_NO_ERROR);
2098 auto jpg1 = jpgImg.getImageHandle();
2099 auto jpg2 = jpgImg2.getImageHandle();
2100 ASSERT_EQ(jpg1->length, jpg2->length);
2101 ASSERT_EQ(0, memcmp(jpg1->data, jpg2->data, jpg1->length));
2102 }
2103
2104 {
2105 uhdr_codec_private_t* obj = uhdr_create_encoder();
2106 uhdr_raw_image_t uhdrRawImg{};
2107 uhdrRawImg.fmt = UHDR_IMG_FMT_24bppYCbCrP010;
2108 uhdrRawImg.cg = map_internal_cg_to_cg(mP010ColorGamut);
2109 uhdrRawImg.ct = map_internal_ct_to_ct(ultrahdr_transfer_function::ULTRAHDR_TF_HLG);
2110 uhdrRawImg.range = UHDR_CR_UNSPECIFIED;
2111 uhdrRawImg.w = kImageWidth;
2112 uhdrRawImg.h = kImageHeight;
2113 uhdrRawImg.planes[UHDR_PLANE_Y] = rawImgP010.getImageHandle()->data;
2114 uhdrRawImg.stride[UHDR_PLANE_Y] = kImageWidth;
2115 uhdrRawImg.planes[UHDR_PLANE_UV] =
2116 ((uint8_t*)(rawImgP010.getImageHandle()->data)) + kImageWidth * kImageHeight * 2;
2117 uhdrRawImg.stride[UHDR_PLANE_UV] = kImageWidth;
2118 uhdr_error_info_t status = uhdr_enc_set_raw_image(obj, &uhdrRawImg, UHDR_HDR_IMG);
2119 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
2120
2121 uhdr_compressed_image_t uhdrCompressedImg;
2122 uhdrCompressedImg.data = sdr->data;
2123 uhdrCompressedImg.data_sz = sdr->length;
2124 uhdrCompressedImg.capacity = sdr->length;
2125 uhdrCompressedImg.cg = map_internal_cg_to_cg(sdr->colorGamut);
2126 uhdrCompressedImg.ct = UHDR_CT_UNSPECIFIED;
2127 uhdrCompressedImg.range = UHDR_CR_UNSPECIFIED;
2128 status = uhdr_enc_set_compressed_image(obj, &uhdrCompressedImg, UHDR_SDR_IMG);
2129 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
2130
2131 status = uhdr_enc_set_quality(obj, kQuality, UHDR_BASE_IMG);
2132 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
2133 status = uhdr_encode(obj);
2134 ASSERT_EQ(UHDR_CODEC_OK, status.error_code) << status.detail;
2135 uhdr_compressed_image_t* compressedImage = uhdr_get_encoded_stream(obj);
2136 ASSERT_NE(nullptr, compressedImage);
2137 ASSERT_EQ(jpgImg.getImageHandle()->length, compressedImage->data_sz);
2138 ASSERT_EQ(
2139 0, memcmp(jpgImg.getImageHandle()->data, compressedImage->data, compressedImage->data_sz));
2140 uhdr_release_encoder(obj);
2141 }
2142
2143 auto jpg1 = jpgImg.getImageHandle();
2144
2145 #ifdef DUMP_OUTPUT
2146 if (!writeFile("encode_api3_output.jpeg", jpg1->data, jpg1->length)) {
2147 std::cerr << "unable to write output file" << std::endl;
2148 }
2149 #endif
2150
2151 ASSERT_NO_FATAL_FAILURE(decodeJpegRImg(jpg1, "decode_api3_output.rgb"));
2152 }
2153
2154 INSTANTIATE_TEST_SUITE_P(
2155 JpegRAPIParameterizedTests, JpegRAPIEncodeAndDecodeTest,
2156 ::testing::Combine(::testing::Values(ULTRAHDR_COLORGAMUT_BT709, ULTRAHDR_COLORGAMUT_P3,
2157 ULTRAHDR_COLORGAMUT_BT2100),
2158 ::testing::Values(ULTRAHDR_COLORGAMUT_BT709, ULTRAHDR_COLORGAMUT_P3,
2159 ULTRAHDR_COLORGAMUT_BT2100)));
2160
2161 // ============================================================================
2162 // Profiling
2163 // ============================================================================
2164 #ifdef _WIN32
2165 class Profiler {
2166 public:
timerStart()2167 void timerStart() { QueryPerformanceCounter(&mStartingTime); }
2168
timerStop()2169 void timerStop() { QueryPerformanceCounter(&mEndingTime); }
2170
elapsedTime()2171 int64_t elapsedTime() {
2172 LARGE_INTEGER frequency;
2173 LARGE_INTEGER elapsedMicroseconds;
2174 QueryPerformanceFrequency(&frequency);
2175 elapsedMicroseconds.QuadPart = mEndingTime.QuadPart - mStartingTime.QuadPart;
2176 return (double)elapsedMicroseconds.QuadPart / (double)frequency.QuadPart * 1000000;
2177 }
2178
2179 private:
2180 LARGE_INTEGER mStartingTime;
2181 LARGE_INTEGER mEndingTime;
2182 };
2183 #else
2184 class Profiler {
2185 public:
timerStart()2186 void timerStart() { gettimeofday(&mStartingTime, nullptr); }
2187
timerStop()2188 void timerStop() { gettimeofday(&mEndingTime, nullptr); }
2189
elapsedTime()2190 int64_t elapsedTime() {
2191 struct timeval elapsedMicroseconds;
2192 elapsedMicroseconds.tv_sec = mEndingTime.tv_sec - mStartingTime.tv_sec;
2193 elapsedMicroseconds.tv_usec = mEndingTime.tv_usec - mStartingTime.tv_usec;
2194 return elapsedMicroseconds.tv_sec * 1000000 + elapsedMicroseconds.tv_usec;
2195 }
2196
2197 private:
2198 struct timeval mStartingTime;
2199 struct timeval mEndingTime;
2200 };
2201 #endif
2202
2203 class JpegRBenchmark : public JpegR {
2204 public:
2205 void BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr p010Image,
2206 ultrahdr_metadata_ptr metadata, jr_uncompressed_ptr map);
2207 void BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr map,
2208 ultrahdr_metadata_ptr metadata, jr_uncompressed_ptr dest);
2209
2210 private:
2211 const int kProfileCount = 10;
2212 };
2213
BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image,jr_uncompressed_ptr p010Image,ultrahdr_metadata_ptr metadata,jr_uncompressed_ptr map)2214 void JpegRBenchmark::BenchmarkGenerateGainMap(jr_uncompressed_ptr yuv420Image,
2215 jr_uncompressed_ptr p010Image,
2216 ultrahdr_metadata_ptr metadata,
2217 jr_uncompressed_ptr map) {
2218 ASSERT_EQ(yuv420Image->width, p010Image->width);
2219 ASSERT_EQ(yuv420Image->height, p010Image->height);
2220 Profiler profileGenerateMap;
2221 profileGenerateMap.timerStart();
2222 for (auto i = 0; i < kProfileCount; i++) {
2223 ASSERT_EQ(JPEGR_NO_ERROR,
2224 generateGainMap(yuv420Image, p010Image, ultrahdr_transfer_function::ULTRAHDR_TF_HLG,
2225 metadata, map));
2226 if (i != kProfileCount - 1) {
2227 delete[] static_cast<uint8_t*>(map->data);
2228 map->data = nullptr;
2229 }
2230 }
2231 profileGenerateMap.timerStop();
2232 ALOGE("Generate Gain Map:- Res = %zu x %zu, time = %f ms", yuv420Image->width,
2233 yuv420Image->height, profileGenerateMap.elapsedTime() / (kProfileCount * 1000.f));
2234 }
2235
BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image,jr_uncompressed_ptr map,ultrahdr_metadata_ptr metadata,jr_uncompressed_ptr dest)2236 void JpegRBenchmark::BenchmarkApplyGainMap(jr_uncompressed_ptr yuv420Image, jr_uncompressed_ptr map,
2237 ultrahdr_metadata_ptr metadata,
2238 jr_uncompressed_ptr dest) {
2239 Profiler profileRecMap;
2240 profileRecMap.timerStart();
2241 for (auto i = 0; i < kProfileCount; i++) {
2242 ASSERT_EQ(JPEGR_NO_ERROR, applyGainMap(yuv420Image, map, metadata, ULTRAHDR_OUTPUT_HDR_HLG,
2243 metadata->maxContentBoost /* displayBoost */, dest));
2244 }
2245 profileRecMap.timerStop();
2246 ALOGE("Apply Gain Map:- Res = %zu x %zu, time = %f ms", yuv420Image->width, yuv420Image->height,
2247 profileRecMap.elapsedTime() / (kProfileCount * 1000.f));
2248 }
2249
TEST(JpegRTest,ProfileGainMapFuncs)2250 TEST(JpegRTest, ProfileGainMapFuncs) {
2251 UhdrUnCompressedStructWrapper rawImgP010(kImageWidth, kImageHeight, YCbCr_p010);
2252 ASSERT_TRUE(rawImgP010.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT2100));
2253 ASSERT_TRUE(rawImgP010.allocateMemory());
2254 ASSERT_TRUE(rawImgP010.loadRawResource(kYCbCrP010FileName));
2255 UhdrUnCompressedStructWrapper rawImg420(kImageWidth, kImageHeight, YCbCr_420);
2256 ASSERT_TRUE(rawImg420.setImageColorGamut(ultrahdr_color_gamut::ULTRAHDR_COLORGAMUT_BT709));
2257 ASSERT_TRUE(rawImg420.allocateMemory());
2258 ASSERT_TRUE(rawImg420.loadRawResource(kYCbCr420FileName));
2259 ultrahdr_metadata_struct metadata;
2260 metadata.version = kJpegrVersion;
2261 jpegr_uncompressed_struct map;
2262 map.data = NULL;
2263 map.width = 0;
2264 map.height = 0;
2265 map.colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED;
2266 map.pixelFormat = UHDR_IMG_FMT_8bppYCbCr400;
2267
2268 {
2269 auto rawImg = rawImgP010.getImageHandle();
2270 if (rawImg->luma_stride == 0) rawImg->luma_stride = rawImg->width;
2271 if (!rawImg->chroma_data) {
2272 uint16_t* data = reinterpret_cast<uint16_t*>(rawImg->data);
2273 rawImg->chroma_data = data + rawImg->luma_stride * rawImg->height;
2274 rawImg->chroma_stride = rawImg->luma_stride;
2275 }
2276 }
2277 {
2278 auto rawImg = rawImg420.getImageHandle();
2279 if (rawImg->luma_stride == 0) rawImg->luma_stride = rawImg->width;
2280 if (!rawImg->chroma_data) {
2281 uint8_t* data = reinterpret_cast<uint8_t*>(rawImg->data);
2282 rawImg->chroma_data = data + rawImg->luma_stride * rawImg->height;
2283 rawImg->chroma_stride = rawImg->luma_stride / 2;
2284 }
2285 }
2286
2287 JpegRBenchmark benchmark;
2288 ASSERT_NO_FATAL_FAILURE(benchmark.BenchmarkGenerateGainMap(
2289 rawImg420.getImageHandle(), rawImgP010.getImageHandle(), &metadata, &map));
2290
2291 const int dstSize = kImageWidth * kImageWidth * 4;
2292 auto bufferDst = std::make_unique<uint8_t[]>(dstSize);
2293 jpegr_uncompressed_struct dest;
2294 dest.data = bufferDst.get();
2295 dest.width = 0;
2296 dest.height = 0;
2297 dest.colorGamut = ULTRAHDR_COLORGAMUT_UNSPECIFIED;
2298
2299 ASSERT_NO_FATAL_FAILURE(
2300 benchmark.BenchmarkApplyGainMap(rawImg420.getImageHandle(), &map, &metadata, &dest));
2301
2302 if (map.data) {
2303 delete[] static_cast<uint8_t*>(map.data);
2304 map.data = nullptr;
2305 }
2306 }
2307
2308 } // namespace ultrahdr
2309