101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1 |
// *****************************************************************************
|
2 |
/*
|
|
373
by Olivier Tilloy
Simplify and optimize ExifTag::setParentImage(…) and XmpTag::setParentImage(…) |
3 |
* Copyright (C) 2006-2012 Olivier Tilloy <olivier@tilloy.net>
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
4 |
*
|
5 |
* This file is part of the pyexiv2 distribution.
|
|
6 |
*
|
|
7 |
* pyexiv2 is free software; you can redistribute it and/or
|
|
8 |
* modify it under the terms of the GNU General Public License
|
|
9 |
* as published by the Free Software Foundation; either version 2
|
|
10 |
* of the License, or (at your option) any later version.
|
|
11 |
*
|
|
12 |
* pyexiv2 is distributed in the hope that it will be useful,
|
|
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 |
* GNU General Public License for more details.
|
|
16 |
*
|
|
17 |
* You should have received a copy of the GNU General Public License
|
|
18 |
* along with pyexiv2; if not, write to the Free Software
|
|
19 |
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
|
20 |
*/
|
|
21 |
/*
|
|
163
by Olivier Tilloy
Removed unused code. |
22 |
Author: Olivier Tilloy <olivier@tilloy.net>
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
23 |
*/
|
24 |
// *****************************************************************************
|
|
25 |
||
26 |
#include "exiv2wrapper.hpp" |
|
27 |
||
235.1.13
by Olivier Tilloy
Implemented IptcTag::setRawValues. |
28 |
#include "boost/python/stl_iterator.hpp" |
29 |
||
243.1.4
by Olivier Tilloy
Preview::writeToFile dumps the preview data to a file. |
30 |
#include <fstream> |
31 |
||
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
32 |
// Custom error codes for Exiv2 exceptions
|
33 |
#define METADATA_NOT_READ 101
|
|
34 |
#define NON_REPEATABLE 102
|
|
35 |
#define KEY_NOT_FOUND 103
|
|
327.1.2
by Olivier Tilloy
Throw an exception instead of silently failing when unable to parse the raw value for EXIF and IPTC tags. |
36 |
#define INVALID_VALUE 104
|
334.2.1
by Olivier Tilloy
Functions in the xmp module to register and unregister custom namespaces. |
37 |
#define EXISTING_PREFIX 105
|
38 |
#define BUILTIN_NS 106
|
|
39 |
#define NOT_REGISTERED 107
|
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
40 |
|
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
41 |
// Custom macros
|
42 |
#define CHECK_METADATA_READ \
|
|
43 |
if (!_dataRead) throw Exiv2::Error(METADATA_NOT_READ);
|
|
44 |
||
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
45 |
namespace exiv2wrapper |
46 |
{
|
|
47 |
||
300
by Olivier Tilloy
Do not leak the data passed to ImageMetadata.from_buffer. |
48 |
void Image::_instantiate_image() |
272
by Olivier Tilloy
Raise an IOError when trying to read an image of an unknown type. |
49 |
{
|
332.1.1
by Olivier Tilloy
Access to the read-only properties of the EXIF thumbnail optionally embedded in an image. |
50 |
_exifThumbnail = 0; |
51 |
||
279.1.4
by Olivier Tilloy
Comment to explain the exception handling |
52 |
// If an exception is thrown, it has to be done outside of the
|
53 |
// Py_{BEGIN,END}_ALLOW_THREADS block.
|
|
279.1.1
by Olivier Tilloy
Copy the error instead of instantiating a new one from its code. |
54 |
Exiv2::Error error(0); |
272
by Olivier Tilloy
Raise an IOError when trying to read an image of an unknown type. |
55 |
|
56 |
// Release the GIL to allow other python threads to run
|
|
57 |
// while opening the file.
|
|
58 |
Py_BEGIN_ALLOW_THREADS
|
|
59 |
||
60 |
try
|
|
61 |
{
|
|
300
by Olivier Tilloy
Do not leak the data passed to ImageMetadata.from_buffer. |
62 |
if (_data != 0) |
280.1.1
by Olivier Tilloy
Instantiate an image from a data buffer. |
63 |
{
|
300
by Olivier Tilloy
Do not leak the data passed to ImageMetadata.from_buffer. |
64 |
_image = Exiv2::ImageFactory::open(_data, _size); |
280.1.1
by Olivier Tilloy
Instantiate an image from a data buffer. |
65 |
}
|
66 |
else
|
|
67 |
{
|
|
68 |
_image = Exiv2::ImageFactory::open(_filename); |
|
69 |
}
|
|
272
by Olivier Tilloy
Raise an IOError when trying to read an image of an unknown type. |
70 |
}
|
279.1.1
by Olivier Tilloy
Copy the error instead of instantiating a new one from its code. |
71 |
catch (Exiv2::Error& err) |
272
by Olivier Tilloy
Raise an IOError when trying to read an image of an unknown type. |
72 |
{
|
279.1.1
by Olivier Tilloy
Copy the error instead of instantiating a new one from its code. |
73 |
error = err; |
272
by Olivier Tilloy
Raise an IOError when trying to read an image of an unknown type. |
74 |
}
|
75 |
||
76 |
// Re-acquire the GIL
|
|
77 |
Py_END_ALLOW_THREADS
|
|
78 |
||
279.1.2
by Olivier Tilloy
No need for a boolean to test for error. |
79 |
if (error.code() == 0) |
272
by Olivier Tilloy
Raise an IOError when trying to read an image of an unknown type. |
80 |
{
|
81 |
assert(_image.get() != 0); |
|
82 |
_dataRead = false; |
|
83 |
}
|
|
84 |
else
|
|
85 |
{
|
|
279.1.1
by Olivier Tilloy
Copy the error instead of instantiating a new one from its code. |
86 |
throw error; |
272
by Olivier Tilloy
Raise an IOError when trying to read an image of an unknown type. |
87 |
}
|
88 |
}
|
|
89 |
||
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
90 |
// Base constructor
|
91 |
Image::Image(const std::string& filename) |
|
92 |
{
|
|
93 |
_filename = filename; |
|
300
by Olivier Tilloy
Do not leak the data passed to ImageMetadata.from_buffer. |
94 |
_data = 0; |
272
by Olivier Tilloy
Raise an IOError when trying to read an image of an unknown type. |
95 |
_instantiate_image(); |
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
96 |
}
|
97 |
||
280.1.1
by Olivier Tilloy
Instantiate an image from a data buffer. |
98 |
// From buffer constructor
|
319
by Olivier Tilloy
Fixed some harmless compilation warnings |
99 |
Image::Image(const std::string& buffer, unsigned long size) |
280.1.1
by Olivier Tilloy
Instantiate an image from a data buffer. |
100 |
{
|
101 |
// Deep copy of the data buffer
|
|
300
by Olivier Tilloy
Do not leak the data passed to ImageMetadata.from_buffer. |
102 |
_data = new Exiv2::byte[size]; |
280.1.1
by Olivier Tilloy
Instantiate an image from a data buffer. |
103 |
for (unsigned long i = 0; i < size; ++i) |
104 |
{
|
|
300
by Olivier Tilloy
Do not leak the data passed to ImageMetadata.from_buffer. |
105 |
_data[i] = buffer[i]; |
280.1.1
by Olivier Tilloy
Instantiate an image from a data buffer. |
106 |
}
|
107 |
||
300
by Olivier Tilloy
Do not leak the data passed to ImageMetadata.from_buffer. |
108 |
_size = size; |
109 |
_instantiate_image(); |
|
280.1.1
by Olivier Tilloy
Instantiate an image from a data buffer. |
110 |
}
|
111 |
||
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
112 |
// Copy constructor
|
113 |
Image::Image(const Image& image) |
|
114 |
{
|
|
115 |
_filename = image._filename; |
|
272
by Olivier Tilloy
Raise an IOError when trying to read an image of an unknown type. |
116 |
_instantiate_image(); |
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
117 |
}
|
118 |
||
300
by Olivier Tilloy
Do not leak the data passed to ImageMetadata.from_buffer. |
119 |
Image::~Image() |
120 |
{
|
|
121 |
if (_data != 0) |
|
122 |
{
|
|
305
by Olivier Tilloy
Use the proper delete[] operator to deallocate the memory block pointed by _data. |
123 |
delete[] _data; |
300
by Olivier Tilloy
Do not leak the data passed to ImageMetadata.from_buffer. |
124 |
}
|
332.1.1
by Olivier Tilloy
Access to the read-only properties of the EXIF thumbnail optionally embedded in an image. |
125 |
if (_exifThumbnail != 0) |
126 |
{
|
|
127 |
delete _exifThumbnail; |
|
128 |
}
|
|
300
by Olivier Tilloy
Do not leak the data passed to ImageMetadata.from_buffer. |
129 |
}
|
130 |
||
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
131 |
void Image::readMetadata() |
132 |
{
|
|
279.1.4
by Olivier Tilloy
Comment to explain the exception handling |
133 |
// If an exception is thrown, it has to be done outside of the
|
134 |
// Py_{BEGIN,END}_ALLOW_THREADS block.
|
|
279.1.3
by Olivier Tilloy
Clean error handling outside of the Py_{BEGIN,END}_ALLOW_THREADS blocks. |
135 |
Exiv2::Error error(0); |
136 |
||
238.1.1
by Olivier Tilloy
Release the GIL while reading/writing metadata. |
137 |
// Release the GIL to allow other python threads to run
|
138 |
// while reading metadata.
|
|
139 |
Py_BEGIN_ALLOW_THREADS
|
|
140 |
||
279.1.3
by Olivier Tilloy
Clean error handling outside of the Py_{BEGIN,END}_ALLOW_THREADS blocks. |
141 |
try
|
142 |
{
|
|
143 |
_image->readMetadata(); |
|
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
144 |
_exifData = &_image->exifData(); |
145 |
_iptcData = &_image->iptcData(); |
|
146 |
_xmpData = &_image->xmpData(); |
|
279.1.3
by Olivier Tilloy
Clean error handling outside of the Py_{BEGIN,END}_ALLOW_THREADS blocks. |
147 |
_dataRead = true; |
148 |
}
|
|
149 |
catch (Exiv2::Error& err) |
|
150 |
{
|
|
151 |
error = err; |
|
152 |
}
|
|
238.1.1
by Olivier Tilloy
Release the GIL while reading/writing metadata. |
153 |
|
154 |
// Re-acquire the GIL
|
|
155 |
Py_END_ALLOW_THREADS
|
|
279.1.3
by Olivier Tilloy
Clean error handling outside of the Py_{BEGIN,END}_ALLOW_THREADS blocks. |
156 |
|
157 |
if (error.code() != 0) |
|
158 |
{
|
|
159 |
throw error; |
|
160 |
}
|
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
161 |
}
|
162 |
||
165
by Olivier Tilloy
Expose writeMetadata in the C++ wrapper. |
163 |
void Image::writeMetadata() |
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
164 |
{
|
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
165 |
CHECK_METADATA_READ
|
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
166 |
|
279.1.4
by Olivier Tilloy
Comment to explain the exception handling |
167 |
// If an exception is thrown, it has to be done outside of the
|
168 |
// Py_{BEGIN,END}_ALLOW_THREADS block.
|
|
279.1.3
by Olivier Tilloy
Clean error handling outside of the Py_{BEGIN,END}_ALLOW_THREADS blocks. |
169 |
Exiv2::Error error(0); |
170 |
||
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
171 |
// Release the GIL to allow other python threads to run
|
172 |
// while writing metadata.
|
|
173 |
Py_BEGIN_ALLOW_THREADS
|
|
174 |
||
279.1.3
by Olivier Tilloy
Clean error handling outside of the Py_{BEGIN,END}_ALLOW_THREADS blocks. |
175 |
try
|
176 |
{
|
|
177 |
_image->writeMetadata(); |
|
178 |
}
|
|
179 |
catch (Exiv2::Error& err) |
|
180 |
{
|
|
181 |
error = err; |
|
182 |
}
|
|
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
183 |
|
184 |
// Re-acquire the GIL
|
|
185 |
Py_END_ALLOW_THREADS
|
|
279.1.3
by Olivier Tilloy
Clean error handling outside of the Py_{BEGIN,END}_ALLOW_THREADS blocks. |
186 |
|
187 |
if (error.code() != 0) |
|
188 |
{
|
|
189 |
throw error; |
|
190 |
}
|
|
165
by Olivier Tilloy
Expose writeMetadata in the C++ wrapper. |
191 |
}
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
192 |
|
260.1.1
by Olivier Tilloy
Read-only access to the dimensions of an image. |
193 |
unsigned int Image::pixelWidth() const |
194 |
{
|
|
195 |
CHECK_METADATA_READ
|
|
196 |
return _image->pixelWidth(); |
|
197 |
}
|
|
198 |
||
199 |
unsigned int Image::pixelHeight() const |
|
200 |
{
|
|
201 |
CHECK_METADATA_READ
|
|
202 |
return _image->pixelHeight(); |
|
203 |
}
|
|
204 |
||
260.1.2
by Olivier Tilloy
Read-only access to the mime type of an image. |
205 |
std::string Image::mimeType() const |
206 |
{
|
|
207 |
CHECK_METADATA_READ
|
|
208 |
return _image->mimeType(); |
|
209 |
}
|
|
210 |
||
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
211 |
boost::python::list Image::exifKeys() |
212 |
{
|
|
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
213 |
CHECK_METADATA_READ
|
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
214 |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
215 |
boost::python::list keys; |
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
216 |
for(Exiv2::ExifMetadata::iterator i = _exifData->begin(); |
217 |
i != _exifData->end(); |
|
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
218 |
++i) |
219 |
{
|
|
220 |
keys.append(i->key()); |
|
221 |
}
|
|
222 |
return keys; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
223 |
}
|
224 |
||
235.1.6
by Olivier Tilloy
Make Image::getExifTag return an ExifTag. |
225 |
const ExifTag Image::getExifTag(std::string key) |
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
226 |
{
|
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
227 |
CHECK_METADATA_READ
|
235.1.6
by Olivier Tilloy
Make Image::getExifTag return an ExifTag. |
228 |
|
229 |
Exiv2::ExifKey exifKey = Exiv2::ExifKey(key); |
|
230 |
||
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
231 |
if(_exifData->findKey(exifKey) == _exifData->end()) |
235.1.6
by Olivier Tilloy
Make Image::getExifTag return an ExifTag. |
232 |
{
|
233 |
throw Exiv2::Error(KEY_NOT_FOUND, key); |
|
234 |
}
|
|
235 |
||
341.1.1
by Olivier Tilloy
Try and decode Exif.Photo.UserComment according to its charset if specified. |
236 |
return ExifTag(key, &(*_exifData)[key], _exifData, _image->byteOrder()); |
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
237 |
}
|
238 |
||
168
by Olivier Tilloy
Delete an EXIF tag. |
239 |
void Image::deleteExifTag(std::string key) |
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
240 |
{
|
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
241 |
CHECK_METADATA_READ
|
235.1.10
by Olivier Tilloy
Cosmetics. |
242 |
|
243 |
Exiv2::ExifKey exifKey = Exiv2::ExifKey(key); |
|
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
244 |
Exiv2::ExifMetadata::iterator datum = _exifData->findKey(exifKey); |
245 |
if(datum == _exifData->end()) |
|
235.1.10
by Olivier Tilloy
Cosmetics. |
246 |
{
|
247 |
throw Exiv2::Error(KEY_NOT_FOUND, key); |
|
248 |
}
|
|
249 |
||
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
250 |
_exifData->erase(datum); |
168
by Olivier Tilloy
Delete an EXIF tag. |
251 |
}
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
252 |
|
253 |
boost::python::list Image::iptcKeys() |
|
254 |
{
|
|
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
255 |
CHECK_METADATA_READ
|
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
256 |
|
104
by Olivier Tilloy
Retrieve more data for an IPTC tag (low-level). |
257 |
boost::python::list keys; |
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
258 |
for(Exiv2::IptcMetadata::iterator i = _iptcData->begin(); |
259 |
i != _iptcData->end(); |
|
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
260 |
++i) |
104
by Olivier Tilloy
Retrieve more data for an IPTC tag (low-level). |
261 |
{
|
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
262 |
// The key is appended to the list if and only if it is not already
|
263 |
// present.
|
|
264 |
if (keys.count(i->key()) == 0) |
|
104
by Olivier Tilloy
Retrieve more data for an IPTC tag (low-level). |
265 |
{
|
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
266 |
keys.append(i->key()); |
104
by Olivier Tilloy
Retrieve more data for an IPTC tag (low-level). |
267 |
}
|
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
268 |
}
|
269 |
return keys; |
|
104
by Olivier Tilloy
Retrieve more data for an IPTC tag (low-level). |
270 |
}
|
271 |
||
235.1.16
by Olivier Tilloy
Make Image::getIptcTag return an IptcTag. |
272 |
const IptcTag Image::getIptcTag(std::string key) |
104
by Olivier Tilloy
Retrieve more data for an IPTC tag (low-level). |
273 |
{
|
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
274 |
CHECK_METADATA_READ
|
235.1.16
by Olivier Tilloy
Make Image::getIptcTag return an IptcTag. |
275 |
|
276 |
Exiv2::IptcKey iptcKey = Exiv2::IptcKey(key); |
|
277 |
||
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
278 |
if(_iptcData->findKey(iptcKey) == _iptcData->end()) |
235.1.16
by Olivier Tilloy
Make Image::getIptcTag return an IptcTag. |
279 |
{
|
280 |
throw Exiv2::Error(KEY_NOT_FOUND, key); |
|
281 |
}
|
|
282 |
||
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
283 |
return IptcTag(key, _iptcData); |
104
by Olivier Tilloy
Retrieve more data for an IPTC tag (low-level). |
284 |
}
|
285 |
||
177
by Olivier Tilloy
Really delete all repetitions of an IPTC tag. |
286 |
void Image::deleteIptcTag(std::string key) |
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
287 |
{
|
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
288 |
CHECK_METADATA_READ
|
177
by Olivier Tilloy
Really delete all repetitions of an IPTC tag. |
289 |
|
290 |
Exiv2::IptcKey iptcKey = Exiv2::IptcKey(key); |
|
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
291 |
Exiv2::IptcMetadata::iterator dataIterator = _iptcData->findKey(iptcKey); |
177
by Olivier Tilloy
Really delete all repetitions of an IPTC tag. |
292 |
|
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
293 |
if (dataIterator == _iptcData->end()) |
177
by Olivier Tilloy
Really delete all repetitions of an IPTC tag. |
294 |
{
|
295 |
throw Exiv2::Error(KEY_NOT_FOUND, key); |
|
296 |
}
|
|
297 |
||
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
298 |
while (dataIterator != _iptcData->end()) |
177
by Olivier Tilloy
Really delete all repetitions of an IPTC tag. |
299 |
{
|
307.1.4
by Olivier Tilloy
Do not copy a subset of the IptcData, instead pass around a pointer to it and do the required arithmetics. |
300 |
if (dataIterator->key() == key) |
301 |
{
|
|
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
302 |
dataIterator = _iptcData->erase(dataIterator); |
307.1.4
by Olivier Tilloy
Do not copy a subset of the IptcData, instead pass around a pointer to it and do the required arithmetics. |
303 |
}
|
304 |
else
|
|
305 |
{
|
|
306 |
++dataIterator; |
|
307 |
}
|
|
177
by Olivier Tilloy
Really delete all repetitions of an IPTC tag. |
308 |
}
|
309 |
}
|
|
107
by Olivier Tilloy
First basic support for XMP metadata: listing XMP keys. |
310 |
|
311 |
boost::python::list Image::xmpKeys() |
|
312 |
{
|
|
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
313 |
CHECK_METADATA_READ
|
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
314 |
|
107
by Olivier Tilloy
First basic support for XMP metadata: listing XMP keys. |
315 |
boost::python::list keys; |
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
316 |
for(Exiv2::XmpMetadata::iterator i = _xmpData->begin(); |
317 |
i != _xmpData->end(); |
|
239.1.1
by Olivier Tilloy
Always check if the metadata has been read beforehand. |
318 |
++i) |
319 |
{
|
|
320 |
keys.append(i->key()); |
|
321 |
}
|
|
322 |
return keys; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
323 |
}
|
324 |
||
235.1.19
by Olivier Tilloy
Make Image::getXmpTag return an XmpTag. |
325 |
const XmpTag Image::getXmpTag(std::string key) |
110
by Olivier Tilloy
Retrieve XMP tag values (without python type conversion atm). |
326 |
{
|
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
327 |
CHECK_METADATA_READ
|
178
by Olivier Tilloy
Unlike IPTC tags, XMP tags are not repeatable. |
328 |
|
329 |
Exiv2::XmpKey xmpKey = Exiv2::XmpKey(key); |
|
330 |
||
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
331 |
if(_xmpData->findKey(xmpKey) == _xmpData->end()) |
178
by Olivier Tilloy
Unlike IPTC tags, XMP tags are not repeatable. |
332 |
{
|
333 |
throw Exiv2::Error(KEY_NOT_FOUND, key); |
|
334 |
}
|
|
335 |
||
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
336 |
return XmpTag(key, &(*_xmpData)[key]); |
178
by Olivier Tilloy
Unlike IPTC tags, XMP tags are not repeatable. |
337 |
}
|
338 |
||
182
by Olivier Tilloy
Delete an XMP tag. |
339 |
void Image::deleteXmpTag(std::string key) |
340 |
{
|
|
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
341 |
CHECK_METADATA_READ
|
182
by Olivier Tilloy
Delete an XMP tag. |
342 |
|
343 |
Exiv2::XmpKey xmpKey = Exiv2::XmpKey(key); |
|
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
344 |
Exiv2::XmpMetadata::iterator i = _xmpData->findKey(xmpKey); |
345 |
if(i != _xmpData->end()) |
|
182
by Olivier Tilloy
Delete an XMP tag. |
346 |
{
|
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
347 |
_xmpData->erase(i); |
182
by Olivier Tilloy
Delete an XMP tag. |
348 |
}
|
349 |
else
|
|
350 |
throw Exiv2::Error(KEY_NOT_FOUND, key); |
|
351 |
}
|
|
352 |
||
312.1.1
by Olivier Tilloy
Get, set and delete the image comment. |
353 |
const std::string Image::getComment() const |
354 |
{
|
|
355 |
CHECK_METADATA_READ
|
|
356 |
return _image->comment(); |
|
357 |
}
|
|
358 |
||
359 |
void Image::setComment(const std::string& comment) |
|
360 |
{
|
|
361 |
CHECK_METADATA_READ
|
|
362 |
_image->setComment(comment); |
|
363 |
}
|
|
364 |
||
365 |
void Image::clearComment() |
|
366 |
{
|
|
367 |
CHECK_METADATA_READ
|
|
368 |
_image->clearComment(); |
|
369 |
}
|
|
370 |
||
371 |
||
243.1.1
by Olivier Tilloy
Preview (thumbnail) extraction. |
372 |
boost::python::list Image::previews() |
373 |
{
|
|
374 |
CHECK_METADATA_READ
|
|
375 |
||
376 |
boost::python::list previews; |
|
377 |
Exiv2::PreviewManager pm(*_image); |
|
378 |
Exiv2::PreviewPropertiesList props = pm.getPreviewProperties(); |
|
379 |
for (Exiv2::PreviewPropertiesList::const_iterator i = props.begin(); |
|
380 |
i != props.end(); |
|
381 |
++i) |
|
382 |
{
|
|
383 |
previews.append(Preview(pm.getPreviewImage(*i))); |
|
384 |
}
|
|
385 |
||
386 |
return previews; |
|
387 |
}
|
|
388 |
||
262
by Olivier Tilloy
Copy metadata to another image. |
389 |
void Image::copyMetadata(Image& other, bool exif, bool iptc, bool xmp) const |
390 |
{
|
|
391 |
CHECK_METADATA_READ
|
|
392 |
if (!other._dataRead) throw Exiv2::Error(METADATA_NOT_READ); |
|
393 |
||
394 |
if (exif) |
|
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
395 |
other._image->setExifData(*_exifData); |
262
by Olivier Tilloy
Copy metadata to another image. |
396 |
if (iptc) |
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
397 |
other._image->setIptcData(*_iptcData); |
262
by Olivier Tilloy
Copy metadata to another image. |
398 |
if (xmp) |
314
by Olivier Tilloy
Don't copy the metadata internally, just keep a pointer to it. |
399 |
other._image->setXmpData(*_xmpData); |
262
by Olivier Tilloy
Copy metadata to another image. |
400 |
}
|
401 |
||
280.1.2
by Olivier Tilloy
New data_buffer() method to get the image buffer. |
402 |
std::string Image::getDataBuffer() const |
403 |
{
|
|
280.1.5
by Olivier Tilloy
getDataBuffer() now releases the GIL to allow other python threads to run |
404 |
std::string buffer; |
405 |
||
406 |
// Release the GIL to allow other python threads to run
|
|
407 |
// while reading the image data.
|
|
408 |
Py_BEGIN_ALLOW_THREADS
|
|
409 |
||
280.1.2
by Olivier Tilloy
New data_buffer() method to get the image buffer. |
410 |
Exiv2::BasicIo& io = _image->io(); |
319
by Olivier Tilloy
Fixed some harmless compilation warnings |
411 |
unsigned long size = io.size(); |
280.1.2
by Olivier Tilloy
New data_buffer() method to get the image buffer. |
412 |
long pos = -1; |
413 |
||
414 |
if (io.isopen()) |
|
415 |
{
|
|
416 |
// Remember the current position in the stream
|
|
417 |
pos = io.tell(); |
|
418 |
// Go to the beginning of the stream
|
|
419 |
io.seek(0, Exiv2::BasicIo::beg); |
|
420 |
}
|
|
421 |
else
|
|
422 |
{
|
|
423 |
io.open(); |
|
424 |
}
|
|
425 |
||
426 |
// Copy the data buffer in a string. Since the data buffer can contain null
|
|
427 |
// characters ('\x00'), the string cannot be simply constructed like that:
|
|
428 |
// _data = std::string((char*) previewImage.pData());
|
|
429 |
// because it would be truncated after the first occurence of a null
|
|
430 |
// character. Therefore, it has to be copied character by character.
|
|
431 |
// First allocate the memory for the whole string...
|
|
280.1.5
by Olivier Tilloy
getDataBuffer() now releases the GIL to allow other python threads to run |
432 |
buffer.resize(size, ' '); |
280.1.2
by Olivier Tilloy
New data_buffer() method to get the image buffer. |
433 |
// ... then fill it with the raw data.
|
434 |
for (unsigned long i = 0; i < size; ++i) |
|
435 |
{
|
|
436 |
io.read((Exiv2::byte*) &buffer[i], 1); |
|
437 |
}
|
|
438 |
||
439 |
if (pos == -1) |
|
440 |
{
|
|
441 |
// The stream was initially closed
|
|
442 |
io.close(); |
|
443 |
}
|
|
444 |
else
|
|
445 |
{
|
|
446 |
// Reset to the initial position in the stream
|
|
447 |
io.seek(pos, Exiv2::BasicIo::beg); |
|
448 |
}
|
|
449 |
||
280.1.5
by Olivier Tilloy
getDataBuffer() now releases the GIL to allow other python threads to run |
450 |
// Re-acquire the GIL
|
451 |
Py_END_ALLOW_THREADS
|
|
452 |
||
280.1.2
by Olivier Tilloy
New data_buffer() method to get the image buffer. |
453 |
return buffer; |
454 |
}
|
|
455 |
||
341.1.1
by Olivier Tilloy
Try and decode Exif.Photo.UserComment according to its charset if specified. |
456 |
Exiv2::ByteOrder Image::getByteOrder() const |
457 |
{
|
|
458 |
CHECK_METADATA_READ
|
|
459 |
return _image->byteOrder(); |
|
460 |
}
|
|
461 |
||
332.1.1
by Olivier Tilloy
Access to the read-only properties of the EXIF thumbnail optionally embedded in an image. |
462 |
Exiv2::ExifThumb* Image::_getExifThumbnail() |
463 |
{
|
|
464 |
CHECK_METADATA_READ
|
|
465 |
if (_exifThumbnail == 0) |
|
466 |
{
|
|
467 |
_exifThumbnail = new Exiv2::ExifThumb(*_exifData); |
|
468 |
}
|
|
469 |
return _exifThumbnail; |
|
470 |
}
|
|
471 |
||
472 |
const std::string Image::getExifThumbnailMimeType() |
|
473 |
{
|
|
474 |
return std::string(_getExifThumbnail()->mimeType()); |
|
475 |
}
|
|
476 |
||
477 |
const std::string Image::getExifThumbnailExtension() |
|
478 |
{
|
|
479 |
return std::string(_getExifThumbnail()->extension()); |
|
480 |
}
|
|
481 |
||
482 |
void Image::writeExifThumbnailToFile(const std::string& path) |
|
483 |
{
|
|
484 |
_getExifThumbnail()->writeFile(path); |
|
485 |
}
|
|
486 |
||
487 |
const std::string Image::getExifThumbnailData() |
|
488 |
{
|
|
489 |
Exiv2::DataBuf buffer = _getExifThumbnail()->copy(); |
|
490 |
// Copy the data buffer in a string. Since the data buffer can contain null
|
|
491 |
// characters ('\x00'), the string cannot be simply constructed like that:
|
|
492 |
// data = std::string((char*) buffer.pData_);
|
|
493 |
// because it would be truncated after the first occurence of a null
|
|
494 |
// character. Therefore, it has to be copied character by character.
|
|
495 |
// First allocate the memory for the whole string...
|
|
496 |
std::string data = std::string(buffer.size_, ' '); |
|
497 |
// ... then fill it with the raw data.
|
|
498 |
for(unsigned int i = 0; i < buffer.size_; ++i) |
|
499 |
{
|
|
500 |
data[i] = buffer.pData_[i]; |
|
501 |
}
|
|
502 |
return data; |
|
503 |
}
|
|
504 |
||
332.1.2
by Olivier Tilloy
Complete implementation of the EXIF thumbnail, including write accessors. |
505 |
void Image::eraseExifThumbnail() |
506 |
{
|
|
507 |
_getExifThumbnail()->erase(); |
|
508 |
}
|
|
509 |
||
510 |
void Image::setExifThumbnailFromFile(const std::string& path) |
|
511 |
{
|
|
512 |
_getExifThumbnail()->setJpegThumbnail(path); |
|
513 |
}
|
|
514 |
||
515 |
void Image::setExifThumbnailFromData(const std::string& data) |
|
516 |
{
|
|
517 |
const Exiv2::byte* buffer = (const Exiv2::byte*) data.c_str(); |
|
518 |
_getExifThumbnail()->setJpegThumbnail(buffer, data.size()); |
|
519 |
}
|
|
520 |
||
344.1.1
by Olivier Tilloy
Added an iptc_charset property to the ImageMetadata class, |
521 |
const std::string Image::getIptcCharset() const |
522 |
{
|
|
523 |
CHECK_METADATA_READ
|
|
524 |
const char* charset = _iptcData->detectCharset(); |
|
525 |
if (charset != 0) |
|
526 |
{
|
|
527 |
return std::string(charset); |
|
528 |
}
|
|
529 |
else
|
|
530 |
{
|
|
531 |
return std::string(); |
|
532 |
}
|
|
533 |
}
|
|
534 |
||
243.1.1
by Olivier Tilloy
Preview (thumbnail) extraction. |
535 |
|
341.1.1
by Olivier Tilloy
Try and decode Exif.Photo.UserComment according to its charset if specified. |
536 |
ExifTag::ExifTag(const std::string& key, |
537 |
Exiv2::Exifdatum* datum, Exiv2::ExifData* data, |
|
538 |
Exiv2::ByteOrder byteOrder): |
|
539 |
_key(key), _byteOrder(byteOrder) |
|
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
540 |
{
|
249.1.1
by Olivier Tilloy
Always provide the EXIF interpreted value if possible. |
541 |
if (datum != 0 && data != 0) |
235.1.6
by Olivier Tilloy
Make Image::getExifTag return an ExifTag. |
542 |
{
|
543 |
_datum = datum; |
|
249.1.1
by Olivier Tilloy
Always provide the EXIF interpreted value if possible. |
544 |
_data = data; |
235.1.6
by Olivier Tilloy
Make Image::getExifTag return an ExifTag. |
545 |
}
|
546 |
else
|
|
547 |
{
|
|
548 |
_datum = new Exiv2::Exifdatum(_key); |
|
249.1.1
by Olivier Tilloy
Always provide the EXIF interpreted value if possible. |
549 |
_data = 0; |
235.1.6
by Olivier Tilloy
Make Image::getExifTag return an ExifTag. |
550 |
}
|
551 |
||
335.1.1
by Olivier Tilloy
Fix build against libexiv2 0.21. |
552 |
// Conditional code, exiv2 0.21 changed APIs we need
|
553 |
// (see https://bugs.launchpad.net/pyexiv2/+bug/684177).
|
|
554 |
#if EXIV2_TEST_VERSION(0,21,0)
|
|
555 |
Exiv2::ExifKey exifKey(key); |
|
363.1.5
by Olivier Tilloy
Special case for the 'Comment' type. |
556 |
_type = Exiv2::TypeInfo::typeName(exifKey.defaultTypeId()); |
557 |
// Where available, extract the type from the metadata, it is more reliable
|
|
558 |
// than static type information. The exception is for user comments, for
|
|
559 |
// which we’d rather keep the 'Comment' type instead of 'Undefined'.
|
|
560 |
if ((_data != 0) && (_type != "Comment")) |
|
363.1.2
by Olivier Tilloy
Correctly extract the type of an EXIF tag when read from an image. |
561 |
{
|
374.1.1
by Olivier Tilloy
Check typeName for nullness. |
562 |
const char* typeName = _datum->typeName(); |
563 |
if (typeName != 0) |
|
564 |
{
|
|
565 |
_type = typeName; |
|
566 |
}
|
|
363.1.2
by Olivier Tilloy
Correctly extract the type of an EXIF tag when read from an image. |
567 |
}
|
335.1.1
by Olivier Tilloy
Fix build against libexiv2 0.21. |
568 |
_name = exifKey.tagName(); |
569 |
_label = exifKey.tagLabel(); |
|
570 |
_description = exifKey.tagDesc(); |
|
571 |
_sectionName = Exiv2::ExifTags::sectionName(exifKey); |
|
572 |
// The section description is not exposed in the API any longer
|
|
573 |
// (see http://dev.exiv2.org/issues/744). For want of anything better,
|
|
574 |
// fall back on the section’s name.
|
|
575 |
_sectionDescription = _sectionName; |
|
576 |
#else
|
|
235.1.6
by Olivier Tilloy
Make Image::getExifTag return an ExifTag. |
577 |
const uint16_t tag = _datum->tag(); |
578 |
const Exiv2::IfdId ifd = _datum->ifdId(); |
|
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
579 |
_type = Exiv2::TypeInfo::typeName(Exiv2::ExifTags::tagType(tag, ifd)); |
363.1.6
by Olivier Tilloy
Replicate the fix for type extraction when compiling against libexiv2 < 0.21. |
580 |
// Where available, extract the type from the metadata, it is more reliable
|
581 |
// than static type information. The exception is for user comments, for
|
|
582 |
// which we’d rather keep the 'Comment' type instead of 'Undefined'.
|
|
583 |
if ((_data != 0) && (_type != "Comment")) |
|
584 |
{
|
|
374.1.1
by Olivier Tilloy
Check typeName for nullness. |
585 |
const char* typeName = _datum->typeName(); |
586 |
if (typeName != 0) |
|
587 |
{
|
|
588 |
_type = typeName; |
|
589 |
}
|
|
363.1.6
by Olivier Tilloy
Replicate the fix for type extraction when compiling against libexiv2 < 0.21. |
590 |
}
|
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
591 |
_name = Exiv2::ExifTags::tagName(tag, ifd); |
592 |
_label = Exiv2::ExifTags::tagLabel(tag, ifd); |
|
593 |
_description = Exiv2::ExifTags::tagDesc(tag, ifd); |
|
594 |
_sectionName = Exiv2::ExifTags::sectionName(tag, ifd); |
|
595 |
_sectionDescription = Exiv2::ExifTags::sectionDesc(tag, ifd); |
|
335.1.1
by Olivier Tilloy
Fix build against libexiv2 0.21. |
596 |
#endif
|
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
597 |
}
|
598 |
||
307.1.1
by Olivier Tilloy
Free the allocated memory when deleting an ExifTag. |
599 |
ExifTag::~ExifTag() |
600 |
{
|
|
601 |
if (_data == 0) |
|
602 |
{
|
|
603 |
delete _datum; |
|
604 |
}
|
|
605 |
}
|
|
606 |
||
235.1.2
by Olivier Tilloy
Renamed ExifTag's _value to _raw_value. |
607 |
void ExifTag::setRawValue(const std::string& value) |
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
608 |
{
|
327.1.2
by Olivier Tilloy
Throw an exception instead of silently failing when unable to parse the raw value for EXIF and IPTC tags. |
609 |
int result = _datum->setValue(value); |
610 |
if (result != 0) |
|
611 |
{
|
|
612 |
throw Exiv2::Error(INVALID_VALUE); |
|
613 |
}
|
|
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
614 |
}
|
615 |
||
310.1.2
by Olivier Tilloy
Attach the image's ExifData to a tag when it is assigned to an image. |
616 |
void ExifTag::setParentImage(Image& image) |
617 |
{
|
|
320.1.1
by Olivier Tilloy
Sanity check when setting the parent image of a tag: |
618 |
Exiv2::ExifData* data = image.getExifData(); |
619 |
if (data == _data) |
|
620 |
{
|
|
621 |
// The parent image is already the one passed as a parameter.
|
|
622 |
// This happens when replacing a tag by itself. In this case, don’t do
|
|
623 |
// anything (see https://bugs.launchpad.net/pyexiv2/+bug/622739).
|
|
624 |
return; |
|
625 |
}
|
|
626 |
_data = data; |
|
373
by Olivier Tilloy
Simplify and optimize ExifTag::setParentImage(…) and XmpTag::setParentImage(…) |
627 |
Exiv2::Value::AutoPtr value = _datum->getValue(); |
310.1.2
by Olivier Tilloy
Attach the image's ExifData to a tag when it is assigned to an image. |
628 |
delete _datum; |
629 |
_datum = &(*_data)[_key.key()]; |
|
373
by Olivier Tilloy
Simplify and optimize ExifTag::setParentImage(…) and XmpTag::setParentImage(…) |
630 |
_datum->setValue(value.get()); |
341.1.1
by Olivier Tilloy
Try and decode Exif.Photo.UserComment according to its charset if specified. |
631 |
|
632 |
_byteOrder = image.getByteOrder(); |
|
310.1.2
by Olivier Tilloy
Attach the image's ExifData to a tag when it is assigned to an image. |
633 |
}
|
634 |
||
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
635 |
const std::string ExifTag::getKey() |
636 |
{
|
|
637 |
return _key.key(); |
|
638 |
}
|
|
639 |
||
640 |
const std::string ExifTag::getType() |
|
641 |
{
|
|
642 |
return _type; |
|
643 |
}
|
|
644 |
||
645 |
const std::string ExifTag::getName() |
|
646 |
{
|
|
647 |
return _name; |
|
648 |
}
|
|
649 |
||
650 |
const std::string ExifTag::getLabel() |
|
651 |
{
|
|
652 |
return _label; |
|
653 |
}
|
|
654 |
||
655 |
const std::string ExifTag::getDescription() |
|
656 |
{
|
|
657 |
return _description; |
|
658 |
}
|
|
659 |
||
660 |
const std::string ExifTag::getSectionName() |
|
661 |
{
|
|
662 |
return _sectionName; |
|
663 |
}
|
|
664 |
||
665 |
const std::string ExifTag::getSectionDescription() |
|
666 |
{
|
|
667 |
return _sectionDescription; |
|
668 |
}
|
|
669 |
||
235.1.2
by Olivier Tilloy
Renamed ExifTag's _value to _raw_value. |
670 |
const std::string ExifTag::getRawValue() |
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
671 |
{
|
235.1.14
by Olivier Tilloy
Do not cache the raw values. |
672 |
return _datum->toString(); |
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
673 |
}
|
674 |
||
235.1.5
by Olivier Tilloy
Also expose the EXIF tags' human readable value. |
675 |
const std::string ExifTag::getHumanValue() |
676 |
{
|
|
249.1.1
by Olivier Tilloy
Always provide the EXIF interpreted value if possible. |
677 |
return _datum->print(_data); |
235.1.5
by Olivier Tilloy
Also expose the EXIF tags' human readable value. |
678 |
}
|
679 |
||
341.1.1
by Olivier Tilloy
Try and decode Exif.Photo.UserComment according to its charset if specified. |
680 |
int ExifTag::getByteOrder() |
681 |
{
|
|
682 |
return _byteOrder; |
|
683 |
}
|
|
684 |
||
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
685 |
|
307.1.4
by Olivier Tilloy
Do not copy a subset of the IptcData, instead pass around a pointer to it and do the required arithmetics. |
686 |
IptcTag::IptcTag(const std::string& key, Exiv2::IptcData* data): _key(key) |
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
687 |
{
|
307.1.2
by Olivier Tilloy
Free the allocated memory when deleting an IptcTag. |
688 |
_from_data = (data != 0); |
689 |
||
690 |
if (_from_data) |
|
235.1.12
by Olivier Tilloy
Instantiate an _IptcTag from an Exiv2::IptcMetadata (vector of Iptcdatum). |
691 |
{
|
692 |
_data = data; |
|
693 |
}
|
|
694 |
else
|
|
695 |
{
|
|
307.1.4
by Olivier Tilloy
Do not copy a subset of the IptcData, instead pass around a pointer to it and do the required arithmetics. |
696 |
_data = new Exiv2::IptcData(); |
697 |
_data->add(Exiv2::Iptcdatum(_key)); |
|
235.1.12
by Olivier Tilloy
Instantiate an _IptcTag from an Exiv2::IptcMetadata (vector of Iptcdatum). |
698 |
}
|
699 |
||
307.1.4
by Olivier Tilloy
Do not copy a subset of the IptcData, instead pass around a pointer to it and do the required arithmetics. |
700 |
Exiv2::IptcMetadata::iterator iterator = _data->findKey(_key); |
235.1.12
by Olivier Tilloy
Instantiate an _IptcTag from an Exiv2::IptcMetadata (vector of Iptcdatum). |
701 |
const uint16_t tag = iterator->tag(); |
702 |
const uint16_t record = iterator->record(); |
|
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
703 |
_type = Exiv2::TypeInfo::typeName(Exiv2::IptcDataSets::dataSetType(tag, record)); |
704 |
_name = Exiv2::IptcDataSets::dataSetName(tag, record); |
|
705 |
_title = Exiv2::IptcDataSets::dataSetTitle(tag, record); |
|
706 |
_description = Exiv2::IptcDataSets::dataSetDesc(tag, record); |
|
707 |
// What is the photoshop name anyway? Where is it used?
|
|
708 |
_photoshopName = Exiv2::IptcDataSets::dataSetPsName(tag, record); |
|
709 |
_repeatable = Exiv2::IptcDataSets::dataSetRepeatable(tag, record); |
|
710 |
_recordName = Exiv2::IptcDataSets::recordName(record); |
|
711 |
_recordDescription = Exiv2::IptcDataSets::recordDesc(record); |
|
235.1.15
by Olivier Tilloy
Throw an exception when trying to set multiple values on non repeatable IPTC tags. |
712 |
|
307.1.4
by Olivier Tilloy
Do not copy a subset of the IptcData, instead pass around a pointer to it and do the required arithmetics. |
713 |
if (_from_data) |
235.1.15
by Olivier Tilloy
Throw an exception when trying to set multiple values on non repeatable IPTC tags. |
714 |
{
|
307.1.4
by Olivier Tilloy
Do not copy a subset of the IptcData, instead pass around a pointer to it and do the required arithmetics. |
715 |
// Check that we are not trying to assign multiple values to a tag that
|
716 |
// is not repeatable.
|
|
717 |
unsigned int nb_values = 0; |
|
718 |
for(Exiv2::IptcMetadata::iterator iterator = _data->begin(); |
|
719 |
iterator != _data->end(); ++iterator) |
|
720 |
{
|
|
721 |
if (iterator->key() == key) |
|
722 |
{
|
|
723 |
++nb_values; |
|
724 |
if (!_repeatable && (nb_values > 1)) |
|
725 |
{
|
|
726 |
throw Exiv2::Error(NON_REPEATABLE); |
|
727 |
}
|
|
728 |
}
|
|
729 |
}
|
|
235.1.15
by Olivier Tilloy
Throw an exception when trying to set multiple values on non repeatable IPTC tags. |
730 |
}
|
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
731 |
}
|
732 |
||
307.1.2
by Olivier Tilloy
Free the allocated memory when deleting an IptcTag. |
733 |
IptcTag::~IptcTag() |
734 |
{
|
|
735 |
if (!_from_data) |
|
736 |
{
|
|
737 |
delete _data; |
|
738 |
}
|
|
739 |
}
|
|
740 |
||
235.1.12
by Olivier Tilloy
Instantiate an _IptcTag from an Exiv2::IptcMetadata (vector of Iptcdatum). |
741 |
void IptcTag::setRawValues(const boost::python::list& values) |
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
742 |
{
|
235.1.15
by Olivier Tilloy
Throw an exception when trying to set multiple values on non repeatable IPTC tags. |
743 |
if (!_repeatable && (boost::python::len(values) > 1)) |
744 |
{
|
|
745 |
// The tag is not repeatable but we are trying to assign it more than
|
|
746 |
// one value.
|
|
747 |
throw Exiv2::Error(NON_REPEATABLE); |
|
748 |
}
|
|
749 |
||
310.1.4
by Olivier Tilloy
Moving around the code that writes IPTC tag values, |
750 |
unsigned int index = 0; |
751 |
unsigned int max = boost::python::len(values); |
|
752 |
Exiv2::IptcMetadata::iterator iterator = _data->findKey(_key); |
|
753 |
while (index < max) |
|
754 |
{
|
|
755 |
std::string value = boost::python::extract<std::string>(values[index++]); |
|
756 |
if (iterator != _data->end()) |
|
757 |
{
|
|
758 |
// Override an existing value
|
|
327.1.2
by Olivier Tilloy
Throw an exception instead of silently failing when unable to parse the raw value for EXIF and IPTC tags. |
759 |
int result = iterator->setValue(value); |
760 |
if (result != 0) |
|
761 |
{
|
|
762 |
throw Exiv2::Error(INVALID_VALUE); |
|
763 |
}
|
|
310.1.4
by Olivier Tilloy
Moving around the code that writes IPTC tag values, |
764 |
// Jump to the next datum matching the key
|
765 |
++iterator; |
|
766 |
while ((iterator != _data->end()) && (iterator->key() != _key.key())) |
|
767 |
{
|
|
768 |
++iterator; |
|
769 |
}
|
|
770 |
}
|
|
771 |
else
|
|
772 |
{
|
|
773 |
// Append a new value
|
|
774 |
Exiv2::Iptcdatum datum(_key); |
|
327.1.2
by Olivier Tilloy
Throw an exception instead of silently failing when unable to parse the raw value for EXIF and IPTC tags. |
775 |
int result = datum.setValue(value); |
776 |
if (result != 0) |
|
777 |
{
|
|
778 |
throw Exiv2::Error(INVALID_VALUE); |
|
779 |
}
|
|
310.1.4
by Olivier Tilloy
Moving around the code that writes IPTC tag values, |
780 |
int state = _data->add(datum); |
781 |
if (state == 6) |
|
782 |
{
|
|
783 |
throw Exiv2::Error(NON_REPEATABLE); |
|
784 |
}
|
|
785 |
// Reset iterator that has been invalidated by appending a datum
|
|
786 |
iterator = _data->end(); |
|
787 |
}
|
|
788 |
}
|
|
789 |
// Erase the remaining values if any
|
|
790 |
while (iterator != _data->end()) |
|
791 |
{
|
|
792 |
if (iterator->key() == _key.key()) |
|
793 |
{
|
|
794 |
iterator = _data->erase(iterator); |
|
795 |
}
|
|
796 |
else
|
|
797 |
{
|
|
798 |
++iterator; |
|
799 |
}
|
|
800 |
}
|
|
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
801 |
}
|
802 |
||
310.1.3
by Olivier Tilloy
Attach the image's IptcData to a tag when it is assigned to an image. |
803 |
void IptcTag::setParentImage(Image& image) |
804 |
{
|
|
320.1.1
by Olivier Tilloy
Sanity check when setting the parent image of a tag: |
805 |
Exiv2::IptcData* data = image.getIptcData(); |
806 |
if (data == _data) |
|
807 |
{
|
|
808 |
// The parent image is already the one passed as a parameter.
|
|
809 |
// This happens when replacing a tag by itself. In this case, don’t do
|
|
810 |
// anything (see https://bugs.launchpad.net/pyexiv2/+bug/622739).
|
|
811 |
return; |
|
812 |
}
|
|
310.1.3
by Olivier Tilloy
Attach the image's IptcData to a tag when it is assigned to an image. |
813 |
const boost::python::list values = getRawValues(); |
814 |
delete _data; |
|
815 |
_from_data = true; |
|
320.1.1
by Olivier Tilloy
Sanity check when setting the parent image of a tag: |
816 |
_data = data; |
310.1.3
by Olivier Tilloy
Attach the image's IptcData to a tag when it is assigned to an image. |
817 |
setRawValues(values); |
818 |
}
|
|
819 |
||
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
820 |
const std::string IptcTag::getKey() |
821 |
{
|
|
822 |
return _key.key(); |
|
823 |
}
|
|
824 |
||
825 |
const std::string IptcTag::getType() |
|
826 |
{
|
|
827 |
return _type; |
|
828 |
}
|
|
829 |
||
830 |
const std::string IptcTag::getName() |
|
831 |
{
|
|
832 |
return _name; |
|
833 |
}
|
|
834 |
||
835 |
const std::string IptcTag::getTitle() |
|
836 |
{
|
|
837 |
return _title; |
|
838 |
}
|
|
839 |
||
840 |
const std::string IptcTag::getDescription() |
|
841 |
{
|
|
842 |
return _description; |
|
843 |
}
|
|
844 |
||
845 |
const std::string IptcTag::getPhotoshopName() |
|
846 |
{
|
|
847 |
return _photoshopName; |
|
848 |
}
|
|
849 |
||
850 |
const bool IptcTag::isRepeatable() |
|
851 |
{
|
|
852 |
return _repeatable; |
|
853 |
}
|
|
854 |
||
855 |
const std::string IptcTag::getRecordName() |
|
856 |
{
|
|
857 |
return _recordName; |
|
858 |
}
|
|
859 |
||
860 |
const std::string IptcTag::getRecordDescription() |
|
861 |
{
|
|
862 |
return _recordDescription; |
|
863 |
}
|
|
864 |
||
235.1.12
by Olivier Tilloy
Instantiate an _IptcTag from an Exiv2::IptcMetadata (vector of Iptcdatum). |
865 |
const boost::python::list IptcTag::getRawValues() |
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
866 |
{
|
235.1.14
by Olivier Tilloy
Do not cache the raw values. |
867 |
boost::python::list values; |
868 |
for(Exiv2::IptcMetadata::iterator iterator = _data->begin(); |
|
869 |
iterator != _data->end(); ++iterator) |
|
870 |
{
|
|
307.1.4
by Olivier Tilloy
Do not copy a subset of the IptcData, instead pass around a pointer to it and do the required arithmetics. |
871 |
if (iterator->key() == _key.key()) |
872 |
{
|
|
873 |
values.append(iterator->toString()); |
|
874 |
}
|
|
235.1.14
by Olivier Tilloy
Do not cache the raw values. |
875 |
}
|
876 |
return values; |
|
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
877 |
}
|
878 |
||
879 |
||
235.1.18
by Olivier Tilloy
Added the _XmpTag class in the low-level wrapper. |
880 |
XmpTag::XmpTag(const std::string& key, Exiv2::Xmpdatum* datum): _key(key) |
881 |
{
|
|
307.1.3
by Olivier Tilloy
Free the allocated memory when deleting an XmpTag. |
882 |
_from_datum = (datum != 0); |
883 |
||
884 |
if (_from_datum) |
|
235.1.18
by Olivier Tilloy
Added the _XmpTag class in the low-level wrapper. |
885 |
{
|
886 |
_datum = datum; |
|
330
by Olivier Tilloy
Use the typename from the XMP datum when available |
887 |
_exiv2_type = datum->typeName(); |
235.1.18
by Olivier Tilloy
Added the _XmpTag class in the low-level wrapper. |
888 |
}
|
889 |
else
|
|
890 |
{
|
|
891 |
_datum = new Exiv2::Xmpdatum(_key); |
|
330
by Olivier Tilloy
Use the typename from the XMP datum when available |
892 |
_exiv2_type = Exiv2::TypeInfo::typeName(Exiv2::XmpProperties::propertyType(_key)); |
235.1.18
by Olivier Tilloy
Added the _XmpTag class in the low-level wrapper. |
893 |
}
|
894 |
||
235.1.28
by Olivier Tilloy
Handle XMP tags for which static property information is not available. |
895 |
const char* title = Exiv2::XmpProperties::propertyTitle(_key); |
896 |
if (title != 0) |
|
897 |
{
|
|
898 |
_title = title; |
|
899 |
}
|
|
900 |
||
901 |
const char* description = Exiv2::XmpProperties::propertyDesc(_key); |
|
902 |
if (description != 0) |
|
903 |
{
|
|
904 |
_description = description; |
|
905 |
}
|
|
906 |
||
235.1.23
by Olivier Tilloy
Do not store the XMP info for a given tag statically. |
907 |
const Exiv2::XmpPropertyInfo* info = Exiv2::XmpProperties::propertyInfo(_key); |
235.1.28
by Olivier Tilloy
Handle XMP tags for which static property information is not available. |
908 |
if (info != 0) |
909 |
{
|
|
910 |
_name = info->name_; |
|
911 |
_type = info->xmpValueType_; |
|
912 |
}
|
|
235.1.18
by Olivier Tilloy
Added the _XmpTag class in the low-level wrapper. |
913 |
}
|
914 |
||
307.1.3
by Olivier Tilloy
Free the allocated memory when deleting an XmpTag. |
915 |
XmpTag::~XmpTag() |
916 |
{
|
|
917 |
if (!_from_datum) |
|
918 |
{
|
|
919 |
delete _datum; |
|
920 |
}
|
|
921 |
}
|
|
922 |
||
235.1.34
by Olivier Tilloy
Separate _XmpTag value setters for text, array and lang alt. |
923 |
void XmpTag::setTextValue(const std::string& value) |
235.1.18
by Olivier Tilloy
Added the _XmpTag class in the low-level wrapper. |
924 |
{
|
925 |
_datum->setValue(value); |
|
235.1.34
by Olivier Tilloy
Separate _XmpTag value setters for text, array and lang alt. |
926 |
}
|
927 |
||
928 |
void XmpTag::setArrayValue(const boost::python::list& values) |
|
929 |
{
|
|
930 |
// Reset the value
|
|
931 |
_datum->setValue(0); |
|
932 |
||
933 |
for(boost::python::stl_input_iterator<std::string> iterator(values); |
|
934 |
iterator != boost::python::stl_input_iterator<std::string>(); |
|
935 |
++iterator) |
|
936 |
{
|
|
937 |
_datum->setValue(*iterator); |
|
938 |
}
|
|
939 |
}
|
|
940 |
||
941 |
void XmpTag::setLangAltValue(const boost::python::dict& values) |
|
942 |
{
|
|
943 |
// Reset the value
|
|
944 |
_datum->setValue(0); |
|
945 |
||
946 |
for(boost::python::stl_input_iterator<std::string> iterator(values); |
|
947 |
iterator != boost::python::stl_input_iterator<std::string>(); |
|
948 |
++iterator) |
|
949 |
{
|
|
950 |
std::string key = *iterator; |
|
951 |
std::string value = boost::python::extract<std::string>(values.get(key)); |
|
952 |
_datum->setValue("lang=\"" + key + "\" " + value); |
|
953 |
}
|
|
954 |
}
|
|
235.1.18
by Olivier Tilloy
Added the _XmpTag class in the low-level wrapper. |
955 |
|
310.1.5
by Olivier Tilloy
Attach the image's XmpData to a tag when it is assigned to an image. |
956 |
void XmpTag::setParentImage(Image& image) |
957 |
{
|
|
320.1.1
by Olivier Tilloy
Sanity check when setting the parent image of a tag: |
958 |
Exiv2::Xmpdatum* datum = &(*image.getXmpData())[_key.key()]; |
959 |
if (datum == _datum) |
|
960 |
{
|
|
961 |
// The parent image is already the one passed as a parameter.
|
|
962 |
// This happens when replacing a tag by itself. In this case, don’t do
|
|
963 |
// anything (see https://bugs.launchpad.net/pyexiv2/+bug/622739).
|
|
964 |
return; |
|
965 |
}
|
|
373
by Olivier Tilloy
Simplify and optimize ExifTag::setParentImage(…) and XmpTag::setParentImage(…) |
966 |
Exiv2::Value::AutoPtr value = _datum->getValue(); |
967 |
delete _datum; |
|
968 |
_from_datum = true; |
|
969 |
_datum = &(*image.getXmpData())[_key.key()]; |
|
970 |
_datum->setValue(value.get()); |
|
310.1.5
by Olivier Tilloy
Attach the image's XmpData to a tag when it is assigned to an image. |
971 |
}
|
972 |
||
235.1.18
by Olivier Tilloy
Added the _XmpTag class in the low-level wrapper. |
973 |
const std::string XmpTag::getKey() |
974 |
{
|
|
975 |
return _key.key(); |
|
976 |
}
|
|
977 |
||
235.1.30
by Olivier Tilloy
Use the (much more reliable) exiv2 type of the XMP tag to get its correct value. |
978 |
const std::string XmpTag::getExiv2Type() |
979 |
{
|
|
980 |
return _exiv2_type; |
|
981 |
}
|
|
982 |
||
235.1.18
by Olivier Tilloy
Added the _XmpTag class in the low-level wrapper. |
983 |
const std::string XmpTag::getType() |
984 |
{
|
|
985 |
return _type; |
|
986 |
}
|
|
987 |
||
988 |
const std::string XmpTag::getName() |
|
989 |
{
|
|
990 |
return _name; |
|
991 |
}
|
|
992 |
||
993 |
const std::string XmpTag::getTitle() |
|
994 |
{
|
|
995 |
return _title; |
|
996 |
}
|
|
997 |
||
998 |
const std::string XmpTag::getDescription() |
|
999 |
{
|
|
1000 |
return _description; |
|
1001 |
}
|
|
1002 |
||
235.1.24
by Olivier Tilloy
Separate _XmpTag value getters for text, array and lang alt. |
1003 |
const std::string XmpTag::getTextValue() |
1004 |
{
|
|
1005 |
return dynamic_cast<const Exiv2::XmpTextValue*>(&_datum->value())->value_; |
|
1006 |
}
|
|
1007 |
||
1008 |
const boost::python::list XmpTag::getArrayValue() |
|
1009 |
{
|
|
1010 |
std::vector<std::string> value = |
|
1011 |
dynamic_cast<const Exiv2::XmpArrayValue*>(&_datum->value())->value_; |
|
1012 |
boost::python::list rvalue; |
|
1013 |
for(std::vector<std::string>::const_iterator i = value.begin(); |
|
1014 |
i != value.end(); ++i) |
|
1015 |
{
|
|
1016 |
rvalue.append(*i); |
|
1017 |
}
|
|
1018 |
return rvalue; |
|
1019 |
}
|
|
1020 |
||
1021 |
const boost::python::dict XmpTag::getLangAltValue() |
|
1022 |
{
|
|
1023 |
Exiv2::LangAltValue::ValueType value = |
|
1024 |
dynamic_cast<const Exiv2::LangAltValue*>(&_datum->value())->value_; |
|
1025 |
boost::python::dict rvalue; |
|
1026 |
for (Exiv2::LangAltValue::ValueType::const_iterator i = value.begin(); |
|
1027 |
i != value.end(); ++i) |
|
1028 |
{
|
|
1029 |
rvalue[i->first] = i->second; |
|
1030 |
}
|
|
1031 |
return rvalue; |
|
235.1.18
by Olivier Tilloy
Added the _XmpTag class in the low-level wrapper. |
1032 |
}
|
1033 |
||
235.1.1
by Olivier Tilloy
Preliminary investigation to implement the *Tag classes in C++. |
1034 |
|
243.1.1
by Olivier Tilloy
Preview (thumbnail) extraction. |
1035 |
Preview::Preview(const Exiv2::PreviewImage& previewImage) |
1036 |
{
|
|
1037 |
_mimeType = previewImage.mimeType(); |
|
1038 |
_extension = previewImage.extension(); |
|
1039 |
_size = previewImage.size(); |
|
1040 |
_dimensions = boost::python::make_tuple(previewImage.width(), |
|
1041 |
previewImage.height()); |
|
1042 |
// Copy the data buffer in a string. Since the data buffer can contain null
|
|
1043 |
// characters ('\x00'), the string cannot be simply constructed like that:
|
|
1044 |
// _data = std::string((char*) previewImage.pData());
|
|
1045 |
// because it would be truncated after the first occurence of a null
|
|
1046 |
// character. Therefore, it has to be copied character by character.
|
|
1047 |
const Exiv2::byte* pData = previewImage.pData(); |
|
1048 |
// First allocate the memory for the whole string...
|
|
1049 |
_data = std::string(_size, ' '); |
|
1050 |
// ... then fill it with the raw data.
|
|
1051 |
for(unsigned int i = 0; i < _size; ++i) |
|
1052 |
{
|
|
1053 |
_data[i] = pData[i]; |
|
1054 |
}
|
|
1055 |
}
|
|
1056 |
||
243.1.4
by Olivier Tilloy
Preview::writeToFile dumps the preview data to a file. |
1057 |
void Preview::writeToFile(const std::string& path) const |
1058 |
{
|
|
1059 |
std::string filename = path + _extension; |
|
356.1.1
by Olivier Tilloy
Always write extracted previews as binary files. |
1060 |
std::ofstream fd(filename.c_str(), std::ios::out | std::ios::binary); |
243.1.4
by Olivier Tilloy
Preview::writeToFile dumps the preview data to a file. |
1061 |
fd << _data; |
1062 |
fd.close(); |
|
1063 |
}
|
|
1064 |
||
243.1.1
by Olivier Tilloy
Preview (thumbnail) extraction. |
1065 |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1066 |
void translateExiv2Error(Exiv2::Error const& error) |
1067 |
{
|
|
1068 |
// Use the Python 'C' API to set up an exception object
|
|
257.1.2
by Olivier Tilloy
Removed a compatibility workaround. |
1069 |
const char* message = error.what(); |
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1070 |
|
1071 |
// The type of the Python exception depends on the error code
|
|
1072 |
// Warning: this piece of code should be updated in case the error codes
|
|
1073 |
// defined by Exiv2 (file 'src/error.cpp') are changed
|
|
1074 |
switch (error.code()) |
|
1075 |
{
|
|
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1076 |
// Exiv2 error codes
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1077 |
case 2: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1078 |
// {path}: Call to `{function}' failed: {strerror}
|
1079 |
// May be raised when reading a file
|
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1080 |
PyErr_SetString(PyExc_RuntimeError, message); |
1081 |
break; |
|
1082 |
case 3: |
|
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1083 |
// This does not look like a {image type} image
|
1084 |
// May be raised by readMetadata()
|
|
1085 |
PyErr_SetString(PyExc_IOError, message); |
|
1086 |
break; |
|
1087 |
case 4: |
|
1088 |
// Invalid dataset name `{dataset name}'
|
|
1089 |
// May be raised when instantiating an IptcKey from a string
|
|
1090 |
PyErr_SetString(PyExc_KeyError, message); |
|
1091 |
break; |
|
1092 |
case 5: |
|
1093 |
// Invalid record name `{record name}'
|
|
1094 |
// May be raised when instantiating an IptcKey from a string
|
|
1095 |
PyErr_SetString(PyExc_KeyError, message); |
|
1096 |
break; |
|
1097 |
case 6: |
|
1098 |
// Invalid key `{key}'
|
|
1099 |
// May be raised when instantiating an ExifKey, an IptcKey or an
|
|
1100 |
// XmpKey from a string
|
|
1101 |
PyErr_SetString(PyExc_KeyError, message); |
|
1102 |
break; |
|
1103 |
case 7: |
|
1104 |
// Invalid tag name or ifdId `{tag name}', ifdId {ifdId}
|
|
1105 |
// May be raised when instantiating an ExifKey from a string
|
|
1106 |
PyErr_SetString(PyExc_KeyError, message); |
|
1107 |
break; |
|
1108 |
case 8: |
|
1109 |
// Value not set
|
|
1110 |
// May be raised when calling value() on a datum
|
|
1111 |
PyErr_SetString(PyExc_ValueError, message); |
|
1112 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1113 |
case 9: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1114 |
// {path}: Failed to open the data source: {strerror}
|
1115 |
// May be raised by readMetadata()
|
|
1116 |
PyErr_SetString(PyExc_IOError, message); |
|
1117 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1118 |
case 10: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1119 |
// {path}: Failed to open file ({mode}): {strerror}
|
1120 |
// May be raised by writeMetadata()
|
|
1121 |
PyErr_SetString(PyExc_IOError, message); |
|
1122 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1123 |
case 11: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1124 |
// {path}: The file contains data of an unknown image type
|
1125 |
// May be raised when opening an image
|
|
1126 |
PyErr_SetString(PyExc_IOError, message); |
|
1127 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1128 |
case 12: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1129 |
// The memory contains data of an unknown image type
|
1130 |
// May be raised when instantiating an image from a data buffer
|
|
1131 |
PyErr_SetString(PyExc_IOError, message); |
|
1132 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1133 |
case 13: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1134 |
// Image type {image type} is not supported
|
1135 |
// May be raised when creating a new image
|
|
1136 |
PyErr_SetString(PyExc_IOError, message); |
|
1137 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1138 |
case 14: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1139 |
// Failed to read image data
|
1140 |
// May be raised by readMetadata()
|
|
1141 |
PyErr_SetString(PyExc_IOError, message); |
|
1142 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1143 |
case 15: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1144 |
// This does not look like a JPEG image
|
1145 |
// May be raised by readMetadata()
|
|
1146 |
PyErr_SetString(PyExc_IOError, message); |
|
1147 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1148 |
case 17: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1149 |
// {old path}: Failed to rename file to {new path}: {strerror}
|
1150 |
// May be raised by writeMetadata()
|
|
1151 |
PyErr_SetString(PyExc_IOError, message); |
|
1152 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1153 |
case 18: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1154 |
// {path}: Transfer failed: {strerror}
|
1155 |
// May be raised by writeMetadata()
|
|
1156 |
PyErr_SetString(PyExc_IOError, message); |
|
1157 |
break; |
|
1158 |
case 19: |
|
1159 |
// Memory transfer failed: {strerror}
|
|
1160 |
// May be raised by writeMetadata()
|
|
1161 |
PyErr_SetString(PyExc_IOError, message); |
|
1162 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1163 |
case 20: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1164 |
// Failed to read input data
|
1165 |
// May be raised by writeMetadata()
|
|
1166 |
PyErr_SetString(PyExc_IOError, message); |
|
1167 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1168 |
case 21: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1169 |
// Failed to write image
|
1170 |
// May be raised by writeMetadata()
|
|
1171 |
PyErr_SetString(PyExc_IOError, message); |
|
1172 |
break; |
|
1173 |
case 22: |
|
1174 |
// Input data does not contain a valid image
|
|
1175 |
// May be raised by writeMetadata()
|
|
1176 |
PyErr_SetString(PyExc_IOError, message); |
|
1177 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1178 |
case 23: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1179 |
// Invalid ifdId {ifdId}
|
1180 |
// May be raised when instantiating an ExifKey from a tag and
|
|
1181 |
// IFD item string
|
|
1182 |
PyErr_SetString(PyExc_KeyError, message); |
|
1183 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1184 |
case 26: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1185 |
// Offset out of range
|
1186 |
// May be raised by writeMetadata() (TIFF)
|
|
1187 |
PyErr_SetString(PyExc_IOError, message); |
|
1188 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1189 |
case 27: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1190 |
// Unsupported data area offset type
|
1191 |
// May be raised by writeMetadata() (TIFF)
|
|
1192 |
PyErr_SetString(PyExc_IOError, message); |
|
1193 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1194 |
case 28: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1195 |
// Invalid charset: `{charset name}'
|
1196 |
// May be raised when instantiating a CommentValue from a string
|
|
1197 |
PyErr_SetString(PyExc_ValueError, message); |
|
1198 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1199 |
case 29: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1200 |
// Unsupported date format
|
1201 |
// May be raised when instantiating a DateValue from a string
|
|
1202 |
PyErr_SetString(PyExc_ValueError, message); |
|
1203 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1204 |
case 30: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1205 |
// Unsupported time format
|
1206 |
// May be raised when instantiating a TimeValue from a string
|
|
1207 |
PyErr_SetString(PyExc_ValueError, message); |
|
1208 |
break; |
|
1209 |
case 31: |
|
1210 |
// Writing to {image format} images is not supported
|
|
1211 |
// May be raised by writeMetadata() for certain image types
|
|
1212 |
PyErr_SetString(PyExc_IOError, message); |
|
1213 |
break; |
|
1214 |
case 32: |
|
1215 |
// Setting {metadata type} in {image format} images is not supported
|
|
1216 |
// May be raised when setting certain types of metadata for certain
|
|
1217 |
// image types that don't support them
|
|
1218 |
PyErr_SetString(PyExc_ValueError, message); |
|
1219 |
break; |
|
1220 |
case 33: |
|
1221 |
// This does not look like a CRW image
|
|
1222 |
// May be raised by readMetadata() (CRW)
|
|
1223 |
PyErr_SetString(PyExc_IOError, message); |
|
1224 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1225 |
case 35: |
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1226 |
// No namespace info available for XMP prefix `{prefix}'
|
1227 |
// May be raised when retrieving property info for an XmpKey
|
|
1228 |
PyErr_SetString(PyExc_KeyError, message); |
|
1229 |
break; |
|
1230 |
case 36: |
|
1231 |
// No prefix registered for namespace `{namespace}', needed for
|
|
1232 |
// property path `{property path}'
|
|
1233 |
// May be raised by readMetadata() when reading the XMP data
|
|
1234 |
PyErr_SetString(PyExc_KeyError, message); |
|
1235 |
break; |
|
1236 |
case 37: |
|
1237 |
// Size of {type of metadata} JPEG segment is larger than
|
|
1238 |
// 65535 bytes
|
|
1239 |
// May be raised by writeMetadata() (JPEG)
|
|
1240 |
PyErr_SetString(PyExc_ValueError, message); |
|
1241 |
break; |
|
1242 |
case 38: |
|
1243 |
// Unhandled Xmpdatum {key} of type {value type}
|
|
1244 |
// May be raised by readMetadata() when reading the XMP data
|
|
1245 |
PyErr_SetString(PyExc_TypeError, message); |
|
1246 |
break; |
|
1247 |
case 39: |
|
1248 |
// Unhandled XMP node {key} with opt={XMP Toolkit option flags}
|
|
1249 |
// May be raised by readMetadata() when reading the XMP data
|
|
1250 |
PyErr_SetString(PyExc_TypeError, message); |
|
1251 |
break; |
|
1252 |
case 40: |
|
1253 |
// XMP Toolkit error {error id}: {error message}
|
|
1254 |
// May be raised by readMetadata() when reading the XMP data
|
|
1255 |
PyErr_SetString(PyExc_RuntimeError, message); |
|
1256 |
break; |
|
1257 |
case 41: |
|
1258 |
// Failed to decode Lang Alt property {property path}
|
|
1259 |
// with opt={XMP Toolkit option flags}
|
|
1260 |
// May be raised by readMetadata() when reading the XMP data
|
|
1261 |
PyErr_SetString(PyExc_ValueError, message); |
|
1262 |
break; |
|
1263 |
case 42: |
|
1264 |
// Failed to decode Lang Alt qualifier {qualifier path}
|
|
1265 |
// with opt={XMP Toolkit option flags}
|
|
1266 |
// May be raised by readMetadata() when reading the XMP data
|
|
1267 |
PyErr_SetString(PyExc_ValueError, message); |
|
1268 |
break; |
|
1269 |
case 43: |
|
1270 |
// Failed to encode Lang Alt property {key}
|
|
1271 |
// May be raised by writeMetadata()
|
|
1272 |
PyErr_SetString(PyExc_ValueError, message); |
|
1273 |
break; |
|
1274 |
case 44: |
|
1275 |
// Failed to determine property name from path {property path},
|
|
1276 |
// namespace {namespace}
|
|
1277 |
// May be raised by readMetadata() when reading the XMP data
|
|
1278 |
PyErr_SetString(PyExc_KeyError, message); |
|
1279 |
break; |
|
1280 |
case 45: |
|
1281 |
// Schema namespace {namespace} is not registered with
|
|
1282 |
// the XMP Toolkit
|
|
1283 |
// May be raised by readMetadata() when reading the XMP data
|
|
1284 |
PyErr_SetString(PyExc_ValueError, message); |
|
1285 |
break; |
|
1286 |
case 46: |
|
1287 |
// No namespace registered for prefix `{prefix}'
|
|
1288 |
// May be raised when instantiating an XmpKey from a string
|
|
1289 |
PyErr_SetString(PyExc_KeyError, message); |
|
1290 |
break; |
|
1291 |
case 47: |
|
1292 |
// Aliases are not supported. Please send this XMP packet
|
|
1293 |
// to ahuggel@gmx.net `{namespace}', `{property path}', `{value}'
|
|
1294 |
// May be raised by readMetadata() when reading the XMP data
|
|
1295 |
PyErr_SetString(PyExc_ValueError, message); |
|
1296 |
break; |
|
1297 |
case 48: |
|
1298 |
// Invalid XmpText type `{type}'
|
|
1299 |
// May be raised when instantiating an XmpTextValue from a string
|
|
1300 |
PyErr_SetString(PyExc_TypeError, message); |
|
1301 |
break; |
|
1302 |
case 49: |
|
1303 |
// TIFF directory {TIFF directory name} has too many entries
|
|
1304 |
// May be raised by writeMetadata() (TIFF)
|
|
1305 |
PyErr_SetString(PyExc_IOError, message); |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1306 |
break; |
1307 |
||
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1308 |
// Custom error codes
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1309 |
case METADATA_NOT_READ: |
1310 |
PyErr_SetString(PyExc_IOError, "Image metadata has not been read yet"); |
|
1311 |
break; |
|
1312 |
case NON_REPEATABLE: |
|
1313 |
PyErr_SetString(PyExc_KeyError, "Tag is not repeatable"); |
|
1314 |
break; |
|
1315 |
case KEY_NOT_FOUND: |
|
1316 |
PyErr_SetString(PyExc_KeyError, "Tag not set"); |
|
1317 |
break; |
|
327.1.2
by Olivier Tilloy
Throw an exception instead of silently failing when unable to parse the raw value for EXIF and IPTC tags. |
1318 |
case INVALID_VALUE: |
1319 |
PyErr_SetString(PyExc_ValueError, "Invalid value"); |
|
1320 |
break; |
|
334.2.1
by Olivier Tilloy
Functions in the xmp module to register and unregister custom namespaces. |
1321 |
case EXISTING_PREFIX: |
1322 |
PyErr_SetString(PyExc_KeyError, "A namespace with this prefix already exists"); |
|
1323 |
break; |
|
1324 |
case BUILTIN_NS: |
|
1325 |
PyErr_SetString(PyExc_KeyError, "Cannot unregister a builtin namespace"); |
|
1326 |
break; |
|
1327 |
case NOT_REGISTERED: |
|
1328 |
PyErr_SetString(PyExc_KeyError, "No namespace registered under this name"); |
|
1329 |
break; |
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1330 |
|
257.1.3
by Olivier Tilloy
Updated error codes translation to the errors defined in libexiv2 0.19. |
1331 |
// Default handler
|
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1332 |
default: |
1333 |
PyErr_SetString(PyExc_RuntimeError, message); |
|
1334 |
}
|
|
1335 |
}
|
|
1336 |
||
334.2.1
by Olivier Tilloy
Functions in the xmp module to register and unregister custom namespaces. |
1337 |
|
1338 |
void registerXmpNs(const std::string& name, const std::string& prefix) |
|
1339 |
{
|
|
1340 |
try
|
|
1341 |
{
|
|
1342 |
const std::string& ns = Exiv2::XmpProperties::ns(prefix); |
|
1343 |
}
|
|
1344 |
catch (Exiv2::Error& error) |
|
1345 |
{
|
|
1346 |
// No namespace exists with the requested prefix, it is safe to
|
|
1347 |
// register a new one.
|
|
1348 |
Exiv2::XmpProperties::registerNs(name, prefix); |
|
1349 |
return; |
|
1350 |
}
|
|
1351 |
throw Exiv2::Error(EXISTING_PREFIX, prefix); |
|
1352 |
}
|
|
1353 |
||
1354 |
void unregisterXmpNs(const std::string& name) |
|
1355 |
{
|
|
1356 |
const std::string& prefix = Exiv2::XmpProperties::prefix(name); |
|
1357 |
if (prefix != "") |
|
1358 |
{
|
|
1359 |
Exiv2::XmpProperties::unregisterNs(name); |
|
1360 |
try
|
|
1361 |
{
|
|
1362 |
const Exiv2::XmpNsInfo* info = Exiv2::XmpProperties::nsInfo(prefix); |
|
1363 |
}
|
|
1364 |
catch (Exiv2::Error& error) |
|
1365 |
{
|
|
1366 |
// The namespace has been successfully unregistered.
|
|
1367 |
return; |
|
1368 |
}
|
|
1369 |
// The namespace hasn’t been unregistered because it’s builtin.
|
|
1370 |
throw Exiv2::Error(BUILTIN_NS, name); |
|
1371 |
}
|
|
1372 |
else
|
|
1373 |
{
|
|
1374 |
throw Exiv2::Error(NOT_REGISTERED, name); |
|
1375 |
}
|
|
1376 |
}
|
|
1377 |
||
1378 |
void unregisterAllXmpNs() |
|
1379 |
{
|
|
1380 |
// Unregister all custom namespaces.
|
|
1381 |
Exiv2::XmpProperties::unregisterNs(); |
|
1382 |
}
|
|
1383 |
||
101
by Olivier Tilloy
Refactor the structure of the exiv2 wrapper, retrieve more data for an EXIF tag. |
1384 |
} // End of namespace exiv2wrapper |
239.1.2
by Olivier Tilloy
Replaced all data read checks by a custom macro. |
1385 |