diff options
| -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); | 
