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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include <cstdio>
#include <exiv2/exiv2.hpp>
#include <cassert>
#include <exiv2/image.hpp>
#include <memory>
#include <string>
#include <iostream>
#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::UniquePtr 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].toUint32();
}
//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();
//TODO: fix problem of img file corruption caused by output being a different size
// to the input buffer
FILE *fileptr;
char *buffer;
long filelen;
fileptr = fopen(tmpFileName, "rb");
fseek(fileptr, 0, SEEK_END);
filelen = ftell(fileptr);
rewind(fileptr);
buffer = (char *)malloc(filelen * sizeof(char));
fread(buffer, filelen, 1, fileptr);
fclose(fileptr);
printf("new len: %ld old len: %d", filelen, size);
// reopen temp file, copy result back into byte array
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";
}
}*/
|