-
Notifications
You must be signed in to change notification settings - Fork 4
/
extract_xmp.cpp
119 lines (95 loc) · 2.97 KB
/
extract_xmp.cpp
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
#include <cstdlib>
#include <string>
// Must be defined to instantiate template classes
#define TXMP_STRING_TYPE std::string
// Must be defined to give access to XMPFiles
#define XMP_INCLUDE_XMPFILES 1
#define XMP_StaticBuild 1
// Ensure XMP templates are instantiated
#include <XMP.incl_cpp>
#include <iostream>
#include <fstream>
using namespace std;
static void write_RDF(string *rdf, const string &szInputFile)
{
ofstream oOutFile;
oOutFile.open(szInputFile.c_str(), ios::out);
oOutFile << *rdf;
oOutFile.close();
}
static int process_file(const string &szInputFile)
{
int iRet = EXIT_SUCCESS;
try {
// Options to open the file with - read only and use a file handler
XMP_OptionBits opts = kXMPFiles_OpenForRead | kXMPFiles_OpenUseSmartHandler;
bool bOk;
SXMPFiles oFile;
string szStatus;
// First we try and open the file
bOk = oFile.OpenFile(szInputFile, kXMP_UnknownFile, opts);
if (!bOk) {
szStatus += "No smart handler available for " + szInputFile + "\nTrying packet scanning.\n";
opts = kXMPFiles_OpenForUpdate | kXMPFiles_OpenUsePacketScanning;
bOk = oFile.OpenFile(szInputFile, kXMP_UnknownFile, opts);
}
// If the file is open then read the metadata
if (bOk) {
// Form output filename
string szBaseFilename;
size_t unIndex = szInputFile.find_last_of(".");
if (unIndex == string::npos) {
szBaseFilename = szInputFile;
} else {
szBaseFilename = szInputFile.substr(0, unIndex);
}
string szOutputFile;
szOutputFile.reserve(szBaseFilename.size() + sizeof(".xmp"));
szOutputFile = szBaseFilename;
szOutputFile.append(".xmp");
cout << szStatus << endl;
cout << szInputFile << " is opened successfully" << endl;
// Create the xmp object and get the xmp data
SXMPMeta oMeta;
oFile.GetXMP(&oMeta);
string sMetaBuffer;
oMeta.SerializeToBuffer(&sMetaBuffer, kXMP_OmitPacketWrapper | kXMP_UseCompactFormat, 0, "\n");
write_RDF(&sMetaBuffer, szOutputFile);
cout << "XMP written to " << szOutputFile << endl;
oFile.CloseFile();
} else {
cout << "Unable to open " << szInputFile << endl;
iRet = EXIT_FAILURE;
}
} catch (XMP_Error &e) {
cout << "ERROR: " << e.GetErrMsg() << endl;
iRet = EXIT_FAILURE;
}
return iRet;
}
int main(int argc, const char *argv[])
{
if (argc != 2) // 2 := command and 1 parameter
{
cout << "usage: extract_xmp <filename>" << endl;
return EXIT_SUCCESS;
}
if (!SXMPMeta::Initialize()) {
cout << "Could not initialize toolkit!";
return EXIT_FAILURE;
}
XMP_OptionBits options = 0;
#if UNIX_ENV
options |= kXMPFiles_ServerMode;
#endif
// Must initialize SXMPFiles before we use it
if (!SXMPFiles::Initialize(options)) {
cout << "Could not initialize SXMPFiles.";
return EXIT_FAILURE;
}
int ret = process_file(argv[1]);
// Terminate the toolkit
SXMPFiles::Terminate();
SXMPMeta::Terminate();
return ret;
}