diff options
author | dan <[email protected]> | 2023-03-12 22:43:08 -0400 |
---|---|---|
committer | dan <[email protected]> | 2023-03-12 22:43:08 -0400 |
commit | dc363d950e8d3b3c05f4cd0062d9dd59cc74e37e (patch) | |
tree | 04ab261209fdb310b74d54806edf863f696e915b | |
parent | 06cdec8ea15a275281e003782676ce42d2748f80 (diff) | |
download | 54-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.cpp | 82 | ||||
-rw-r--r-- | lib/exif_wrapper.h | 4 |
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); |