summaryrefslogtreecommitdiffstats
path: root/lib/exif_wrapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/exif_wrapper.cpp')
-rw-r--r--lib/exif_wrapper.cpp82
1 files changed, 82 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";
+ }
+}