summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordan <[email protected]>2023-03-12 22:43:08 -0400
committerdan <[email protected]>2023-03-12 22:43:08 -0400
commitdc363d950e8d3b3c05f4cd0062d9dd59cc74e37e (patch)
tree04ab261209fdb310b74d54806edf863f696e915b
parent06cdec8ea15a275281e003782676ce42d2748f80 (diff)
download54-dc363d950e8d3b3c05f4cd0062d9dd59cc74e37e.tar.gz
54-dc363d950e8d3b3c05f4cd0062d9dd59cc74e37e.tar.bz2
54-dc363d950e8d3b3c05f4cd0062d9dd59cc74e37e.zip
feat: implement cpp functions to get and set exif data
-rw-r--r--lib/exif_wrapper.cpp82
-rw-r--r--lib/exif_wrapper.h4
2 files changed, 86 insertions, 0 deletions
diff --git a/lib/exif_wrapper.cpp b/lib/exif_wrapper.cpp
new file mode 100644
index 0000000..e6b60b1
--- /dev/null
+++ b/lib/exif_wrapper.cpp
@@ -0,0 +1,82 @@
+#include <cstdio>
+#include <exiv2/exiv2.hpp>
+#include <cassert>
+#include <exiv2/image.hpp>
+#include <memory>
+#include <string>
+
+#include <unistd.h>
+
+const char* ORIENTATION_KEY = "Exif.Image.Orientation";
+
+
+extern "C" unsigned int getExifOrientation(uint8_t* imgBytes, unsigned int size) {
+ try {
+ Exiv2::XmpParser::initialize();
+ ::atexit(Exiv2::XmpParser::terminate);
+ Exiv2::enableBMFF();
+
+ Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(imgBytes, size);
+ assert(image.get() != 0);
+ image->readMetadata();
+
+ Exiv2::ExifData &exifData = image->exifData();
+ if (exifData.empty()) {
+ return 9;
+ }
+
+ return (unsigned int) exifData[ORIENTATION_KEY].toLong();
+ }
+ //catch (std::exception& e) {
+ //catch (Exiv2::AnyError& e) {
+ catch (Exiv2::Error& e) {
+ std::cout << "Caught Exiv2 exception '" << e.what() << "'\n";
+ return 9;
+ }
+}
+
+extern "C" void setExifOrientation(uint8_t* imgBytes, unsigned int size, unsigned int orientation) {
+ int chk = 0;
+ for (int i = 0; i < size; i++) {
+ chk = (chk + (int)imgBytes[i] * 13) % 100000;
+ }
+ printf("start chk:%d\n",chk);
+ try {
+ // Hack to work around Exiv2 seeming to refuse to write back to blob, but will write
+ // back to a file. Create temp file -> operate on it -> copy back to blob, unlink file.
+ char tmpFileName[] = "/tmp/image-temp.XXXXXX";
+ int fd = mkstemp(tmpFileName);
+ assert(fd != -1);
+ write(fd, imgBytes, size);
+ close(fd);
+
+ // Exiv init
+ Exiv2::XmpParser::initialize();
+ ::atexit(Exiv2::XmpParser::terminate);
+ Exiv2::enableBMFF();
+
+
+ // using blob works, except that exiv2 won't write back to the blob :(
+ // std::unique_ptr<Exiv2::Image> image = Exiv2::ImageFactory::open(imgBytes, size);
+ // So instead we load from the temp file
+ std::unique_ptr<Exiv2::Image> image = Exiv2::ImageFactory::open(tmpFileName);
+ assert(image.get() != 0);
+ image->readMetadata();
+ Exiv2::ExifData &exifData = image->exifData();
+
+ exifData[ORIENTATION_KEY] = orientation;
+
+ // Save exif to image object & save image back to file
+ image->setExifData(exifData);
+ image->writeMetadata();
+
+ // reopen temp file, copy result back into byte array
+ FILE* fileptr = fopen(tmpFileName, "rb");
+ fread(imgBytes, size, 1, fileptr);
+ fclose(fileptr);
+ unlink(tmpFileName);
+ }
+ catch (Exiv2::Error& e) {
+ std::cout << "Caught Exiv2 exception '" << e.what() << "'\n";
+ }
+}
diff --git a/lib/exif_wrapper.h b/lib/exif_wrapper.h
new file mode 100644
index 0000000..ec51406
--- /dev/null
+++ b/lib/exif_wrapper.h
@@ -0,0 +1,4 @@
+#include <stdint.h>
+
+unsigned int getExifOrientation(uint8_t* imgBytes, unsigned int size);
+void setExifOrientation(uint8_t* imgBytes, unsigned int size, unsigned int orientation);