libjpegrecoverymap: add unit test for encode decode

Bug: b/252835416
Change-Id: Ie3c6dba85ba589cd432f510247caf13ef38371a2
Test: push the input files to `/sdcard/Documents` then run `atest libjpegdecoder_test`
diff --git a/libs/jpegrecoverymap/tests/data/jpeg_image.jpg b/libs/jpegrecoverymap/tests/data/jpeg_image.jpg
new file mode 100644
index 0000000..e285742
--- /dev/null
+++ b/libs/jpegrecoverymap/tests/data/jpeg_image.jpg
Binary files differ
diff --git a/libs/jpegrecoverymap/tests/data/raw_p010_image.p010 b/libs/jpegrecoverymap/tests/data/raw_p010_image.p010
new file mode 100644
index 0000000..01673bf
--- /dev/null
+++ b/libs/jpegrecoverymap/tests/data/raw_p010_image.p010
Binary files differ
diff --git a/libs/jpegrecoverymap/tests/recoverymap_test.cpp b/libs/jpegrecoverymap/tests/recoverymap_test.cpp
index b3cd37e..ade33a0 100644
--- a/libs/jpegrecoverymap/tests/recoverymap_test.cpp
+++ b/libs/jpegrecoverymap/tests/recoverymap_test.cpp
@@ -14,8 +14,19 @@
  * limitations under the License.
  */
 
-#include <gtest/gtest.h>
 #include <jpegrecoverymap/recoverymap.h>
+#include <fcntl.h>
+#include <fstream>
+#include <gtest/gtest.h>
+#include <utils/Log.h>
+
+#define RAW_P010_IMAGE "/sdcard/Documents/raw_p010_image.p010"
+#define RAW_P010_IMAGE_WIDTH 1280
+#define RAW_P010_IMAGE_HEIGHT 720
+#define JPEG_IMAGE "/sdcard/Documents/jpeg_image.jpg"
+
+#define SAVE_ENCODING_RESULT true
+#define SAVE_DECODING_RESULT true
 
 namespace android::recoverymap {
 
@@ -26,13 +37,50 @@
 protected:
   virtual void SetUp();
   virtual void TearDown();
+
+  struct jpegr_uncompressed_struct mRawP010Image;
+  struct jpegr_compressed_struct mJpegImage;
 };
 
 RecoveryMapTest::RecoveryMapTest() {}
 RecoveryMapTest::~RecoveryMapTest() {}
 
 void RecoveryMapTest::SetUp() {}
-void RecoveryMapTest::TearDown() {}
+void RecoveryMapTest::TearDown() {
+  free(mRawP010Image.data);
+  free(mJpegImage.data);
+}
+
+static size_t getFileSize(int fd) {
+  struct stat st;
+  if (fstat(fd, &st) < 0) {
+    ALOGW("%s : fstat failed", __func__);
+    return 0;
+  }
+  return st.st_size; // bytes
+}
+
+static bool loadFile(const char filename[], void*& result, int* fileLength) {
+  int fd = open(filename, O_CLOEXEC);
+  if (fd < 0) {
+    return false;
+  }
+  int length = getFileSize(fd);
+  if (length == 0) {
+    close(fd);
+    return false;
+  }
+  if (fileLength != nullptr) {
+    *fileLength = length;
+  }
+  result = malloc(length);
+  if (read(fd, result, length) != static_cast<ssize_t>(length)) {
+    close(fd);
+    return false;
+  }
+  close(fd);
+  return true;
+}
 
 TEST_F(RecoveryMapTest, build) {
   // Force all of the recovery map lib to be linked by calling all public functions.
@@ -45,4 +93,61 @@
   recovery_map.decodeJPEGR(nullptr, nullptr, nullptr, false);
 }
 
+TEST_F(RecoveryMapTest, encodeFromJpegThenDecode) {
+  int ret;
+
+  // Load input files.
+  if (!loadFile(RAW_P010_IMAGE, mRawP010Image.data, nullptr)) {
+    FAIL() << "Load file " << RAW_P010_IMAGE << " failed";
+  }
+  mRawP010Image.width = RAW_P010_IMAGE_WIDTH;
+  mRawP010Image.height = RAW_P010_IMAGE_HEIGHT;
+  mRawP010Image.colorGamut = jpegr_color_gamut::JPEGR_COLORGAMUT_BT2100;
+
+  if (!loadFile(JPEG_IMAGE, mJpegImage.data, &mJpegImage.length)) {
+    FAIL() << "Load file " << JPEG_IMAGE << " failed";
+  }
+  mJpegImage.colorGamut = jpegr_color_gamut::JPEGR_COLORGAMUT_BT709;
+
+  RecoveryMap recoveryMap;
+
+  jpegr_compressed_struct jpegR;
+  jpegR.maxLength = RAW_P010_IMAGE_WIDTH * RAW_P010_IMAGE_HEIGHT * sizeof(uint8_t);
+  jpegR.data = malloc(jpegR.maxLength);
+  ret = recoveryMap.encodeJPEGR(
+      &mRawP010Image, &mJpegImage, jpegr_transfer_function::JPEGR_TF_HLG, &jpegR);
+  if (ret != OK) {
+    FAIL() << "Error code is " << ret;
+  }
+  if (SAVE_ENCODING_RESULT) {
+    // Output image data to file
+    std::string filePath = "/sdcard/Documents/encoded_from_jpeg_input.jpgr";
+    std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
+    if (!imageFile.is_open()) {
+      ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
+    }
+    imageFile.write((const char*)jpegR.data, jpegR.length);
+  }
+
+  jpegr_uncompressed_struct decodedJpegR;
+  int decodedJpegRSize = RAW_P010_IMAGE_WIDTH * RAW_P010_IMAGE_HEIGHT * 4;
+  decodedJpegR.data = malloc(decodedJpegRSize);
+  ret = recoveryMap.decodeJPEGR(&jpegR, &decodedJpegR);
+  if (ret != OK) {
+    FAIL() << "Error code is " << ret;
+  }
+  if (SAVE_DECODING_RESULT) {
+    // Output image data to file
+    std::string filePath = "/sdcard/Documents/decoded_from_jpeg_input.rgb10";
+    std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
+    if (!imageFile.is_open()) {
+      ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
+    }
+    imageFile.write((const char*)decodedJpegR.data, decodedJpegRSize);
+  }
+
+  free(jpegR.data);
+  free(decodedJpegR.data);
+}
+
 } // namespace android::recoverymap