jpegrecoverymap: propagate EXIF to upper level

Test: manual
Bug: b/252835416
Change-Id: I83afd787d2d689a03d1adc4205b29f8e53c6e0dc
diff --git a/libs/jpegrecoverymap/include/jpegrecoverymap/jpegdecoder.h b/libs/jpegrecoverymap/include/jpegrecoverymap/jpegdecoder.h
index 5993546..d0de48f 100644
--- a/libs/jpegrecoverymap/include/jpegrecoverymap/jpegdecoder.h
+++ b/libs/jpegrecoverymap/include/jpegrecoverymap/jpegdecoder.h
@@ -86,12 +86,12 @@
      */
     int getEXIFPos() { return mExifPos; }
     /*
-     * Decompresses metadata of the image.
+     * Decompresses metadata of the image. All vectors are owned by the caller.
      */
     bool getCompressedImageParameters(const void* image, int length,
                                       size_t* pWidth, size_t* pHeight,
-                                      std::vector<uint8_t>* &iccData,
-                                      std::vector<uint8_t>* &exifData);
+                                      std::vector<uint8_t>* iccData,
+                                      std::vector<uint8_t>* exifData);
     /*
      * Extracts EXIF package and updates the EXIF position / length without decoding the image.
      */
diff --git a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h
index 905bf16..c44a92a 100644
--- a/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h
+++ b/libs/jpegrecoverymap/include/jpegrecoverymap/recoverymap.h
@@ -244,7 +244,8 @@
     *
     * The output is filled jpegr_info structure
     * @param compressed_jpegr_image compressed JPEGR image
-    * @param jpegr_info pointer to output JPEGR info
+    * @param jpegr_info pointer to output JPEGR info. Members of jpegr_info
+    *         are owned by the caller
     * @return NO_ERROR if JPEGR parsing succeeds, error code otherwise
     */
     status_t getJPEGRInfo(jr_compressed_ptr compressed_jpegr_image,
diff --git a/libs/jpegrecoverymap/jpegdecoder.cpp b/libs/jpegrecoverymap/jpegdecoder.cpp
index 07b527c..0ae6a63 100644
--- a/libs/jpegrecoverymap/jpegdecoder.cpp
+++ b/libs/jpegrecoverymap/jpegdecoder.cpp
@@ -311,7 +311,7 @@
 
 bool JpegDecoder::getCompressedImageParameters(const void* image, int length,
                               size_t *pWidth, size_t *pHeight,
-                              std::vector<uint8_t> *&iccData , std::vector<uint8_t> *&exifData) {
+                              std::vector<uint8_t> *iccData , std::vector<uint8_t> *exifData) {
     jpeg_decompress_struct cinfo;
     jpegr_source_mgr mgr(static_cast<const uint8_t*>(image), length);
     jpegrerror_mgr myerr;
@@ -336,10 +336,27 @@
     *pWidth = cinfo.image_width;
     *pHeight = cinfo.image_height;
 
-    //TODO: Parse iccProfile and exifData
+    //TODO: Parse iccProfile
     (void)iccData;
-    (void)exifData;
 
+    if (exifData != nullptr) {
+        bool exifAppears = false;
+        for (jpeg_marker_struct* marker = cinfo.marker_list; marker && !exifAppears;
+             marker = marker->next) {
+            if (marker->marker != kAPP1Marker) {
+                continue;
+            }
+
+            const unsigned int len = marker->data_length;
+            if (len >= kExifIdCode.size() &&
+                !strncmp(reinterpret_cast<const char*>(marker->data), kExifIdCode.c_str(),
+                         kExifIdCode.size())) {
+                exifData->resize(len, 0);
+                memcpy(static_cast<void*>(exifData->data()), marker->data, len);
+                exifAppears = true;
+            }
+        }
+    }
 
     jpeg_destroy_decompress(&cinfo);
     return true;