libjpegrecoverymap refactor: move EXIF stuffs into utils.

Test: recoverymap_test
Bug: b/264715926
Change-Id: Ie4c3632c03ac34867cb9e4f50fb782578ad8c8da
diff --git a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h
index 164ea64..f8ae30a 100644
--- a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h
+++ b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymaputils.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_JPEGRECOVERYMAP_RECOVERYMAPUTILS_H
 #define ANDROID_JPEGRECOVERYMAP_RECOVERYMAPUTILS_H
 
+#include <jpegrecoverymap/recoverymap.h>
+
 #include <sstream>
 #include <stdint.h>
 #include <string>
@@ -26,6 +28,26 @@
 
 struct jpegr_metadata;
 
+// If the EXIF package doesn't exist in the input JPEG, we'll create one with one entry
+// where the length is represented by this value.
+const size_t PSEUDO_EXIF_PACKAGE_LENGTH = 28;
+// If the EXIF package exists in the input JPEG, we'll add an "JR" entry where the length is
+// represented by this value.
+const size_t EXIF_J_R_ENTRY_LENGTH = 12;
+
+/*
+ * Helper function used for writing data to destination.
+ *
+ * @param destination destination of the data to be written.
+ * @param source source of data being written.
+ * @param length length of the data to be written.
+ * @param position cursor in desitination where the data is to be written.
+ * @return status of succeed or error code.
+ */
+status_t Write(jr_compressed_ptr destination, const void* source, size_t length, int &position);
+status_t Write(jr_exif_ptr destination, const void* source, size_t length, int &position);
+
+
 /*
  * Parses XMP packet and fills metadata with data from XMP
  *
@@ -83,6 +105,42 @@
  * @return XMP metadata in type of string
  */
 std::string generateXmp(int secondary_image_length, jpegr_metadata& metadata);
+
+/*
+ * Helper function
+ * Add J R entry to existing exif, or create a new one with J R entry if it's null.
+ * EXIF syntax / change:
+ * ori:
+ * FF E1 - APP1
+ * 01 FC - size of APP1 (to be calculated)
+ * -----------------------------------------------------
+ * 45 78 69 66 00 00 - Exif\0\0 "Exif header"
+ * 49 49 2A 00 - TIFF Header
+ * 08 00 00 00 - offset to the IFD (image file directory)
+ * 06 00 - 6 entries
+ * 00 01 - Width Tag
+ * 03 00 - 'Short' type
+ * 01 00 00 00 - one entry
+ * 00 05 00 00 - image with 0x500
+ *--------------------------------------------------------------------------
+ * new:
+ * FF E1 - APP1
+ * 02 08 - new size, equals to old size + EXIF_J_R_ENTRY_LENGTH (12)
+ *-----------------------------------------------------
+ * 45 78 69 66 00 00 - Exif\0\0 "Exif header"
+ * 49 49 2A 00 - TIFF Header
+ * 08 00 00 00 - offset to the IFD (image file directory)
+ * 07 00 - +1 entry
+ * 4A 52   Custom ('J''R') Tag
+ * 07 00 - Unknown type
+ * 01 00 00 00 - one element
+ * 00 00 00 00 - empty data
+ * 00 01 - Width Tag
+ * 03 00 - 'Short' type
+ * 01 00 00 00 - one entry
+ * 00 05 00 00 - image with 0x500
+ */
+status_t updateExif(jr_exif_ptr exif, jr_exif_ptr dest);
 }
 
 #endif //ANDROID_JPEGRECOVERYMAP_RECOVERYMAPUTILS_H
diff --git a/libs/jpegrecoverymap/recoverymap.cpp b/libs/jpegrecoverymap/recoverymap.cpp
index eb557e5..22289de 100644
--- a/libs/jpegrecoverymap/recoverymap.cpp
+++ b/libs/jpegrecoverymap/recoverymap.cpp
@@ -94,135 +94,6 @@
 }
 
 /*
- * Helper function used for writing data to destination.
- *
- * @param destination destination of the data to be written.
- * @param source source of data being written.
- * @param length length of the data to be written.
- * @param position cursor in desitination where the data is to be written.
- * @return status of succeed or error code.
- */
-status_t Write(jr_compressed_ptr destination, const void* source, size_t length, int &position) {
-  if (position + length > destination->maxLength) {
-    return ERROR_JPEGR_BUFFER_TOO_SMALL;
-  }
-
-  memcpy((uint8_t*)destination->data + sizeof(uint8_t) * position, source, length);
-  position += length;
-  return NO_ERROR;
-}
-
-status_t Write(jr_exif_ptr destination, const void* source, size_t length, int &position) {
-  memcpy((uint8_t*)destination->data + sizeof(uint8_t) * position, source, length);
-  position += length;
-  return NO_ERROR;
-}
-
-// If the EXIF package doesn't exist in the input JPEG, we'll create one with one entry
-// where the length is represented by this value.
-const size_t PSEUDO_EXIF_PACKAGE_LENGTH = 28;
-// If the EXIF package exists in the input JPEG, we'll add an "JR" entry where the length is
-// represented by this value.
-const size_t EXIF_J_R_ENTRY_LENGTH = 12;
-
-/*
- * Helper function
- * Add J R entry to existing exif, or create a new one with J R entry if it's null.
- * EXIF syntax / change:
- * ori:
- * FF E1 - APP1
- * 01 FC - size of APP1 (to be calculated)
- * -----------------------------------------------------
- * 45 78 69 66 00 00 - Exif\0\0 "Exif header"
- * 49 49 2A 00 - TIFF Header
- * 08 00 00 00 - offset to the IFD (image file directory)
- * 06 00 - 6 entries
- * 00 01 - Width Tag
- * 03 00 - 'Short' type
- * 01 00 00 00 - one entry
- * 00 05 00 00 - image with 0x500
- *--------------------------------------------------------------------------
- * new:
- * FF E1 - APP1
- * 02 08 - new size, equals to old size + EXIF_J_R_ENTRY_LENGTH (12)
- *-----------------------------------------------------
- * 45 78 69 66 00 00 - Exif\0\0 "Exif header"
- * 49 49 2A 00 - TIFF Header
- * 08 00 00 00 - offset to the IFD (image file directory)
- * 07 00 - +1 entry
- * 4A 52   Custom ('J''R') Tag
- * 07 00 - Unknown type
- * 01 00 00 00 - one element
- * 00 00 00 00 - empty data
- * 00 01 - Width Tag
- * 03 00 - 'Short' type
- * 01 00 00 00 - one entry
- * 00 05 00 00 - image with 0x500
- */
-status_t updateExif(jr_exif_ptr exif, jr_exif_ptr dest) {
-  if (exif == nullptr || exif->data == nullptr) {
-    uint8_t data[PSEUDO_EXIF_PACKAGE_LENGTH] = {
-        0x45, 0x78, 0x69, 0x66, 0x00, 0x00,
-        0x49, 0x49, 0x2A, 0x00,
-        0x08, 0x00, 0x00, 0x00,
-        0x01, 0x00,
-        0x4A, 0x52,
-        0x07, 0x00,
-        0x01, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00};
-    int pos = 0;
-    Write(dest, data, PSEUDO_EXIF_PACKAGE_LENGTH, pos);
-    return NO_ERROR;
-  }
-
-  int num_entry = 0;
-  uint8_t num_entry_low = 0;
-  uint8_t num_entry_high = 0;
-  bool use_big_endian = false;
-  if (reinterpret_cast<uint16_t*>(exif->data)[3] == 0x4949) {
-      num_entry_low = reinterpret_cast<uint8_t*>(exif->data)[14];
-      num_entry_high = reinterpret_cast<uint8_t*>(exif->data)[15];
-  } else if (reinterpret_cast<uint16_t*>(exif->data)[3] == 0x4d4d) {
-      use_big_endian = true;
-      num_entry_high = reinterpret_cast<uint8_t*>(exif->data)[14];
-      num_entry_low = reinterpret_cast<uint8_t*>(exif->data)[15];
-  } else {
-      return ERROR_JPEGR_METADATA_ERROR;
-  }
-  num_entry = (num_entry_high << 8) | num_entry_low;
-  num_entry += 1;
-  num_entry_low = num_entry & 0xff;
-  num_entry_high = (num_entry << 8) & 0xff;
-
-  int pos = 0;
-  Write(dest, (uint8_t*)exif->data, 14, pos);
-
-  if (use_big_endian) {
-    Write(dest, &num_entry_high, 1, pos);
-    Write(dest, &num_entry_low, 1, pos);
-    uint8_t data[EXIF_J_R_ENTRY_LENGTH] = {
-          0x4A, 0x52,
-          0x07, 0x00,
-          0x01, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00};
-    Write(dest, data, EXIF_J_R_ENTRY_LENGTH, pos);
-  } else {
-    Write(dest, &num_entry_low, 1, pos);
-    Write(dest, &num_entry_high, 1, pos);
-    uint8_t data[EXIF_J_R_ENTRY_LENGTH] = {
-          0x4A, 0x52,
-          0x00, 0x07,
-          0x00, 0x00, 0x00, 0x01,
-          0x00, 0x00, 0x00, 0x00};
-    Write(dest, data, EXIF_J_R_ENTRY_LENGTH, pos);
-  }
-
-  Write(dest, (uint8_t*)exif->data + 16, exif->length - 16, pos);
-
-  return NO_ERROR;
-}
-
-/*
  * Helper function copies the JPEG image from without EXIF.
  *
  * @param dest destination of the data to be written.
diff --git a/libs/jpegrecoverymap/recoverymaputils.cpp b/libs/jpegrecoverymap/recoverymaputils.cpp
index 8997b4d..78edd27 100644
--- a/libs/jpegrecoverymap/recoverymaputils.cpp
+++ b/libs/jpegrecoverymap/recoverymaputils.cpp
@@ -15,7 +15,6 @@
  */
 
 #include <jpegrecoverymap/recoverymaputils.h>
-#include <jpegrecoverymap/recoverymap.h>
 #include <image_io/xml/xml_reader.h>
 #include <image_io/xml/xml_writer.h>
 #include <image_io/base/message_handler.h>
@@ -41,6 +40,25 @@
   return ss.str();
 }
 
+/*
+ * Helper function used for writing data to destination.
+ */
+status_t Write(jr_compressed_ptr destination, const void* source, size_t length, int &position) {
+  if (position + length > destination->maxLength) {
+    return ERROR_JPEGR_BUFFER_TOO_SMALL;
+  }
+
+  memcpy((uint8_t*)destination->data + sizeof(uint8_t) * position, source, length);
+  position += length;
+  return NO_ERROR;
+}
+
+status_t Write(jr_exif_ptr destination, const void* source, size_t length, int &position) {
+  memcpy((uint8_t*)destination->data + sizeof(uint8_t) * position, source, length);
+  position += length;
+  return NO_ERROR;
+}
+
 // Extremely simple XML Handler - just searches for interesting elements
 class XMPXmlHandler : public XmlHandler {
 public:
@@ -324,4 +342,71 @@
   return ss.str();
 }
 
+/*
+ * Helper function
+ * Add J R entry to existing exif, or create a new one with J R entry if it's null.
+ */
+status_t updateExif(jr_exif_ptr exif, jr_exif_ptr dest) {
+  if (exif == nullptr || exif->data == nullptr) {
+    uint8_t data[PSEUDO_EXIF_PACKAGE_LENGTH] = {
+        0x45, 0x78, 0x69, 0x66, 0x00, 0x00,
+        0x49, 0x49, 0x2A, 0x00,
+        0x08, 0x00, 0x00, 0x00,
+        0x01, 0x00,
+        0x4A, 0x52,
+        0x07, 0x00,
+        0x01, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00};
+    int pos = 0;
+    Write(dest, data, PSEUDO_EXIF_PACKAGE_LENGTH, pos);
+    return NO_ERROR;
+  }
+
+  int num_entry = 0;
+  uint8_t num_entry_low = 0;
+  uint8_t num_entry_high = 0;
+  bool use_big_endian = false;
+  if (reinterpret_cast<uint16_t*>(exif->data)[3] == 0x4949) {
+      num_entry_low = reinterpret_cast<uint8_t*>(exif->data)[14];
+      num_entry_high = reinterpret_cast<uint8_t*>(exif->data)[15];
+  } else if (reinterpret_cast<uint16_t*>(exif->data)[3] == 0x4d4d) {
+      use_big_endian = true;
+      num_entry_high = reinterpret_cast<uint8_t*>(exif->data)[14];
+      num_entry_low = reinterpret_cast<uint8_t*>(exif->data)[15];
+  } else {
+      return ERROR_JPEGR_METADATA_ERROR;
+  }
+  num_entry = (num_entry_high << 8) | num_entry_low;
+  num_entry += 1;
+  num_entry_low = num_entry & 0xff;
+  num_entry_high = (num_entry >> 8) & 0xff;
+
+  int pos = 0;
+  Write(dest, (uint8_t*)exif->data, 14, pos);
+
+  if (use_big_endian) {
+    Write(dest, &num_entry_high, 1, pos);
+    Write(dest, &num_entry_low, 1, pos);
+    uint8_t data[EXIF_J_R_ENTRY_LENGTH] = {
+          0x4A, 0x52,
+          0x00, 0x07,
+          0x00, 0x00, 0x00, 0x01,
+          0x00, 0x00, 0x00, 0x00};
+    Write(dest, data, EXIF_J_R_ENTRY_LENGTH, pos);
+  } else {
+    Write(dest, &num_entry_low, 1, pos);
+    Write(dest, &num_entry_high, 1, pos);
+    uint8_t data[EXIF_J_R_ENTRY_LENGTH] = {
+          0x4A, 0x52,
+          0x07, 0x00,
+          0x01, 0x00, 0x00, 0x00,
+          0x00, 0x00, 0x00, 0x00};
+    Write(dest, data, EXIF_J_R_ENTRY_LENGTH, pos);
+  }
+
+  Write(dest, (uint8_t*)exif->data + 16, exif->length - 16, pos);
+
+  return NO_ERROR;
+}
+
 } // namespace android::recoverymap