1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
#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(char* fileName, unsigned int orientation) {
try {
// 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(fileName);
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();
}
catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e.what() << "'\n";
}
}
/*
extern "C" void setExifOrientation(uint8_t* imgBytes, unsigned int size, unsigned int orientation) {
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.
// tmpFileName gets overwritten with the actual filename by mkstemp
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";
}
}*/
|