1b8bc0d8aSopenharmony_ci/* exif-content.c
2b8bc0d8aSopenharmony_ci *
3b8bc0d8aSopenharmony_ci * Copyright  2002,2003 Hans Meine <hans_meine@gmx.net>
4b8bc0d8aSopenharmony_ci *
5b8bc0d8aSopenharmony_ci * This library is free software; you can redistribute it and/or
6b8bc0d8aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
7b8bc0d8aSopenharmony_ci * License as published by the Free Software Foundation; either
8b8bc0d8aSopenharmony_ci * version 2 of the License, or (at your option) any later version.
9b8bc0d8aSopenharmony_ci *
10b8bc0d8aSopenharmony_ci * This library is distributed in the hope that it will be useful,
11b8bc0d8aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
12b8bc0d8aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13b8bc0d8aSopenharmony_ci * Lesser General Public License for more details.
14b8bc0d8aSopenharmony_ci *
15b8bc0d8aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
16b8bc0d8aSopenharmony_ci * License along with this library; if not, write to the
17b8bc0d8aSopenharmony_ci * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18b8bc0d8aSopenharmony_ci * Boston, MA  02110-1301  USA.
19b8bc0d8aSopenharmony_ci */
20b8bc0d8aSopenharmony_ci
21b8bc0d8aSopenharmony_ci#include "exif.hxx"
22b8bc0d8aSopenharmony_ci#include <string>
23b8bc0d8aSopenharmony_ci#include <iostream>
24b8bc0d8aSopenharmony_ci
25b8bc0d8aSopenharmony_ci#include <Python.h>
26b8bc0d8aSopenharmony_ci#include <boost/python.hpp>
27b8bc0d8aSopenharmony_ciusing namespace boost::python;
28b8bc0d8aSopenharmony_ci
29b8bc0d8aSopenharmony_citemplate<class Wrapper, class Pointer>
30b8bc0d8aSopenharmony_cistruct WrappedObjectIterator
31b8bc0d8aSopenharmony_ci{
32b8bc0d8aSopenharmony_ci	//typedef Wrapper value_type;
33b8bc0d8aSopenharmony_ci	Pointer *it_, *end_;
34b8bc0d8aSopenharmony_ci
35b8bc0d8aSopenharmony_ci	WrappedObjectIterator(Pointer *it, Pointer *end)
36b8bc0d8aSopenharmony_ci		: it_(it), end_(end)
37b8bc0d8aSopenharmony_ci	{}
38b8bc0d8aSopenharmony_ci
39b8bc0d8aSopenharmony_ci	Wrapper next()
40b8bc0d8aSopenharmony_ci	{
41b8bc0d8aSopenharmony_ci		if(it_ == end_)
42b8bc0d8aSopenharmony_ci		{
43b8bc0d8aSopenharmony_ci			PyErr_SetString(PyExc_StopIteration, "iterator exhausted");
44b8bc0d8aSopenharmony_ci			throw_error_already_set();
45b8bc0d8aSopenharmony_ci		}
46b8bc0d8aSopenharmony_ci		return Wrapper(*it_++);
47b8bc0d8aSopenharmony_ci	}
48b8bc0d8aSopenharmony_ci};
49b8bc0d8aSopenharmony_ci
50b8bc0d8aSopenharmony_cistruct PythonEntry : public Exif::Entry
51b8bc0d8aSopenharmony_ci{
52b8bc0d8aSopenharmony_ci	PythonEntry() {}
53b8bc0d8aSopenharmony_ci	PythonEntry(Exif::Entry const &other) : Exif::Entry(other) {}
54b8bc0d8aSopenharmony_ci
55b8bc0d8aSopenharmony_ci	object component(long index) const
56b8bc0d8aSopenharmony_ci	{
57b8bc0d8aSopenharmony_ci		switch(format())
58b8bc0d8aSopenharmony_ci		{
59b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_BYTE:
60b8bc0d8aSopenharmony_ci			return object(getByte(index));
61b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_SHORT:
62b8bc0d8aSopenharmony_ci			return object(getShort(index));
63b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_LONG:
64b8bc0d8aSopenharmony_ci			return object(getLong(index));
65b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_SLONG:
66b8bc0d8aSopenharmony_ci			return object(getSLong(index));
67b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_RATIONAL:
68b8bc0d8aSopenharmony_ci			return object(getRational(index));
69b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_SRATIONAL:
70b8bc0d8aSopenharmony_ci			return object(getSRational(index));
71b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_ASCII:
72b8bc0d8aSopenharmony_ci			//std::cerr << "returning " << entry_->size << " bytes of data..\n";
73b8bc0d8aSopenharmony_ci			//std::cerr << " (copied into " << std::string((char *)data, entry_->size).size() << "-character string)\n";
74b8bc0d8aSopenharmony_ci			return object(std::string((char *)entry_->data, entry_->size));
75b8bc0d8aSopenharmony_ci		default:
76b8bc0d8aSopenharmony_ci			break;
77b8bc0d8aSopenharmony_ci		}
78b8bc0d8aSopenharmony_ci		return object();
79b8bc0d8aSopenharmony_ci	}
80b8bc0d8aSopenharmony_ci
81b8bc0d8aSopenharmony_ci	object data() const
82b8bc0d8aSopenharmony_ci	{
83b8bc0d8aSopenharmony_ci		if((format() == EXIF_FORMAT_ASCII) || (components()==1))
84b8bc0d8aSopenharmony_ci			return component(0);
85b8bc0d8aSopenharmony_ci		else
86b8bc0d8aSopenharmony_ci		{
87b8bc0d8aSopenharmony_ci			list result;
88b8bc0d8aSopenharmony_ci			for(unsigned int i=0; i<components(); ++i)
89b8bc0d8aSopenharmony_ci				result.append(component(i));
90b8bc0d8aSopenharmony_ci			return result;
91b8bc0d8aSopenharmony_ci		}
92b8bc0d8aSopenharmony_ci	}
93b8bc0d8aSopenharmony_ci
94b8bc0d8aSopenharmony_ci	template<class Type>
95b8bc0d8aSopenharmony_ci	Type extractComponent(unsigned int index, object value,
96b8bc0d8aSopenharmony_ci						  const char *errorString)
97b8bc0d8aSopenharmony_ci	{
98b8bc0d8aSopenharmony_ci		extract<Type> extr(value);
99b8bc0d8aSopenharmony_ci		if(!extr.check())
100b8bc0d8aSopenharmony_ci		{
101b8bc0d8aSopenharmony_ci			PyErr_SetString(PyExc_TypeError, errorString);
102b8bc0d8aSopenharmony_ci			throw_error_already_set();
103b8bc0d8aSopenharmony_ci		}
104b8bc0d8aSopenharmony_ci		return extr();
105b8bc0d8aSopenharmony_ci	}
106b8bc0d8aSopenharmony_ci
107b8bc0d8aSopenharmony_ci	void setComponent(unsigned int index, object value)
108b8bc0d8aSopenharmony_ci	{
109b8bc0d8aSopenharmony_ci		unsigned char *data= entry_->data
110b8bc0d8aSopenharmony_ci							 + index * exif_format_get_size(format());
111b8bc0d8aSopenharmony_ci		ExifByteOrder bo = exif_data_get_byte_order(entry_->parent->parent);
112b8bc0d8aSopenharmony_ci
113b8bc0d8aSopenharmony_ci		switch(format())
114b8bc0d8aSopenharmony_ci		{
115b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_BYTE:
116b8bc0d8aSopenharmony_ci			*data= extractComponent<ExifByte>(index, value, "invalid assignment to data: could not convert value to byte format");
117b8bc0d8aSopenharmony_ci			break;
118b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_SHORT:
119b8bc0d8aSopenharmony_ci			exif_set_short(data, bo, extractComponent<ExifShort>(index, value, "invalid assignment to data: could not convert value to short format"));
120b8bc0d8aSopenharmony_ci			break;
121b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_LONG:
122b8bc0d8aSopenharmony_ci			exif_set_long(data, bo, extractComponent<ExifLong>(index, value, "invalid assignment to data: could not convert value to long format"));
123b8bc0d8aSopenharmony_ci			break;
124b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_SLONG:
125b8bc0d8aSopenharmony_ci			exif_set_slong(data, bo, extractComponent<ExifSLong>(index, value, "invalid assignment to data: could not convert value to signed long format"));
126b8bc0d8aSopenharmony_ci			break;
127b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_RATIONAL:
128b8bc0d8aSopenharmony_ci			exif_set_rational(data, bo, extractComponent<ExifRational>(index, value, "invalid assignment to data: could not convert value to rational format (2-tuple expected)"));
129b8bc0d8aSopenharmony_ci			break;
130b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_SRATIONAL:
131b8bc0d8aSopenharmony_ci			exif_set_srational(data, bo, extractComponent<ExifSRational>(index, value, "invalid assignment to data: could not convert value to signed rational format (2-tuple expected)"));
132b8bc0d8aSopenharmony_ci			break;
133b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_ASCII: // handled in setData directly
134b8bc0d8aSopenharmony_ci		case EXIF_FORMAT_UNDEFINED:
135b8bc0d8aSopenharmony_ci			break;
136b8bc0d8aSopenharmony_ci		}
137b8bc0d8aSopenharmony_ci		return;
138b8bc0d8aSopenharmony_ci	}
139b8bc0d8aSopenharmony_ci
140b8bc0d8aSopenharmony_ci	void setData(object data)
141b8bc0d8aSopenharmony_ci	{
142b8bc0d8aSopenharmony_ci		if(format() == EXIF_FORMAT_ASCII)
143b8bc0d8aSopenharmony_ci		{
144b8bc0d8aSopenharmony_ci			extract<std::string> xstr(data);
145b8bc0d8aSopenharmony_ci			if(xstr.check())
146b8bc0d8aSopenharmony_ci			{
147b8bc0d8aSopenharmony_ci				std::string s= xstr();
148b8bc0d8aSopenharmony_ci				if(entry_->data)
149b8bc0d8aSopenharmony_ci					free(entry_->data);
150b8bc0d8aSopenharmony_ci				entry_->components= s.size();
151b8bc0d8aSopenharmony_ci				//std::cerr << "assigning " << s.size() << "-character string..\n";
152b8bc0d8aSopenharmony_ci				entry_->size=
153b8bc0d8aSopenharmony_ci					exif_format_get_size(format()) * entry_->components;
154b8bc0d8aSopenharmony_ci				entry_->data= (unsigned char *)malloc(entry_->size);
155b8bc0d8aSopenharmony_ci				memcpy(entry_->data, s.data(), entry_->size);
156b8bc0d8aSopenharmony_ci				entry_->data[entry_->size]= 0;
157b8bc0d8aSopenharmony_ci			}
158b8bc0d8aSopenharmony_ci			else
159b8bc0d8aSopenharmony_ci			{
160b8bc0d8aSopenharmony_ci				PyErr_SetString(PyExc_TypeError,
161b8bc0d8aSopenharmony_ci								"invalid assignment to data of ASCII format entry: string expected");
162b8bc0d8aSopenharmony_ci				throw_error_already_set();
163b8bc0d8aSopenharmony_ci			}
164b8bc0d8aSopenharmony_ci		}
165b8bc0d8aSopenharmony_ci		else
166b8bc0d8aSopenharmony_ci		{
167b8bc0d8aSopenharmony_ci			if(components()==1)
168b8bc0d8aSopenharmony_ci				setComponent(0, data);
169b8bc0d8aSopenharmony_ci			else
170b8bc0d8aSopenharmony_ci			{
171b8bc0d8aSopenharmony_ci				extract<list> xlist(data);
172b8bc0d8aSopenharmony_ci				if(xlist.check())
173b8bc0d8aSopenharmony_ci				{
174b8bc0d8aSopenharmony_ci					list l= xlist();
175b8bc0d8aSopenharmony_ci					for(unsigned i=0; i<components(); ++i)
176b8bc0d8aSopenharmony_ci						setComponent(i, l[i]);
177b8bc0d8aSopenharmony_ci				}
178b8bc0d8aSopenharmony_ci				else
179b8bc0d8aSopenharmony_ci				{
180b8bc0d8aSopenharmony_ci					PyErr_SetString(PyExc_TypeError,
181b8bc0d8aSopenharmony_ci									"invalid assignment to data of entry with more than one component: list expected");
182b8bc0d8aSopenharmony_ci					throw_error_already_set();
183b8bc0d8aSopenharmony_ci				}
184b8bc0d8aSopenharmony_ci			}
185b8bc0d8aSopenharmony_ci		}
186b8bc0d8aSopenharmony_ci	}
187b8bc0d8aSopenharmony_ci};
188b8bc0d8aSopenharmony_ci
189b8bc0d8aSopenharmony_cistruct PythonContent : public Exif::Content
190b8bc0d8aSopenharmony_ci{
191b8bc0d8aSopenharmony_ci	typedef WrappedObjectIterator<PythonEntry, ExifEntry *> iterator;
192b8bc0d8aSopenharmony_ci
193b8bc0d8aSopenharmony_ci	PythonContent() {}
194b8bc0d8aSopenharmony_ci	PythonContent(Exif::Content const &other) : Exif::Content(other) {}
195b8bc0d8aSopenharmony_ci
196b8bc0d8aSopenharmony_ci	PythonEntry entry(object index)
197b8bc0d8aSopenharmony_ci	{
198b8bc0d8aSopenharmony_ci		// TODO: use Exif::Content::entry() functions
199b8bc0d8aSopenharmony_ci
200b8bc0d8aSopenharmony_ci		extract<ExifTag> xtag(index);
201b8bc0d8aSopenharmony_ci		if(xtag.check())
202b8bc0d8aSopenharmony_ci		{
203b8bc0d8aSopenharmony_ci			ExifTag index= xtag();
204b8bc0d8aSopenharmony_ci			for(unsigned int i=0; i<size(); i++)
205b8bc0d8aSopenharmony_ci			{
206b8bc0d8aSopenharmony_ci				if(content_->entries[i]->tag == index)
207b8bc0d8aSopenharmony_ci					return Exif::Entry(content_->entries[i]);
208b8bc0d8aSopenharmony_ci			}
209b8bc0d8aSopenharmony_ci			PyErr_SetString(PyExc_KeyError,
210b8bc0d8aSopenharmony_ci							"tag not present in IFD content");
211b8bc0d8aSopenharmony_ci			throw_error_already_set();
212b8bc0d8aSopenharmony_ci		}
213b8bc0d8aSopenharmony_ci		extract<int> xint(index);
214b8bc0d8aSopenharmony_ci		if(xint.check())
215b8bc0d8aSopenharmony_ci		{
216b8bc0d8aSopenharmony_ci			int index= xint();
217b8bc0d8aSopenharmony_ci			if((index>=0) && (index<(long)size()))
218b8bc0d8aSopenharmony_ci				return Exif::Entry(content_->entries[index]);
219b8bc0d8aSopenharmony_ci			if((index<0) && (index>=-(long)size()))
220b8bc0d8aSopenharmony_ci				return Exif::Entry(content_->entries[size()+index]);
221b8bc0d8aSopenharmony_ci			PyErr_SetString(PyExc_IndexError,
222b8bc0d8aSopenharmony_ci							"invalid integer index into IFD content");
223b8bc0d8aSopenharmony_ci			throw_error_already_set();
224b8bc0d8aSopenharmony_ci		}
225b8bc0d8aSopenharmony_ci		PyErr_SetString(PyExc_TypeError,
226b8bc0d8aSopenharmony_ci						"invalid index into EXIF data (integer or IFD expected)");
227b8bc0d8aSopenharmony_ci		throw_error_already_set();
228b8bc0d8aSopenharmony_ci		return Exif::Entry(); // never reached
229b8bc0d8aSopenharmony_ci	}
230b8bc0d8aSopenharmony_ci
231b8bc0d8aSopenharmony_ci	iterator __iter__()
232b8bc0d8aSopenharmony_ci	{
233b8bc0d8aSopenharmony_ci		// FIXME: the public API is exif_content_foreach,
234b8bc0d8aSopenharmony_ci		// relying on memory layout here!
235b8bc0d8aSopenharmony_ci		return iterator(content_->entries,
236b8bc0d8aSopenharmony_ci						content_->entries + content_->count);
237b8bc0d8aSopenharmony_ci	}
238b8bc0d8aSopenharmony_ci};
239b8bc0d8aSopenharmony_ci
240b8bc0d8aSopenharmony_cistruct PythonData : public Exif::Data
241b8bc0d8aSopenharmony_ci{
242b8bc0d8aSopenharmony_ci	typedef WrappedObjectIterator<PythonContent, ExifContent *> iterator;
243b8bc0d8aSopenharmony_ci	bool success_;
244b8bc0d8aSopenharmony_ci
245b8bc0d8aSopenharmony_ci	PythonData() {}
246b8bc0d8aSopenharmony_ci	PythonData(const char *path)
247b8bc0d8aSopenharmony_ci	: Exif::Data(path, &success_)
248b8bc0d8aSopenharmony_ci	{
249b8bc0d8aSopenharmony_ci		if(!success_)
250b8bc0d8aSopenharmony_ci		{
251b8bc0d8aSopenharmony_ci			PyErr_SetFromErrno(PyExc_IOError);
252b8bc0d8aSopenharmony_ci			//PyErr_SetString(PyExc_IOError, "");
253b8bc0d8aSopenharmony_ci			throw_error_already_set();
254b8bc0d8aSopenharmony_ci		}
255b8bc0d8aSopenharmony_ci	}
256b8bc0d8aSopenharmony_ci	PythonData(const unsigned char *data,
257b8bc0d8aSopenharmony_ci			   unsigned int size) : Exif::Data(data, size) {}
258b8bc0d8aSopenharmony_ci	PythonData(Exif::Data const &other) : Exif::Data(other) {}
259b8bc0d8aSopenharmony_ci
260b8bc0d8aSopenharmony_ci	PythonContent ifdContent(object index)
261b8bc0d8aSopenharmony_ci	{
262b8bc0d8aSopenharmony_ci		extract<ExifIfd> xifd(index);
263b8bc0d8aSopenharmony_ci		if(xifd.check())
264b8bc0d8aSopenharmony_ci		{
265b8bc0d8aSopenharmony_ci			ExifIfd index= xifd();
266b8bc0d8aSopenharmony_ci			if(index<EXIF_IFD_COUNT)
267b8bc0d8aSopenharmony_ci				return Exif::Content(data_->ifd[index]);
268b8bc0d8aSopenharmony_ci			PyErr_SetString(PyExc_IndexError,
269b8bc0d8aSopenharmony_ci							"invalid IFD index into EXIF data");
270b8bc0d8aSopenharmony_ci			throw_error_already_set();
271b8bc0d8aSopenharmony_ci		}
272b8bc0d8aSopenharmony_ci		extract<int> xint(index);
273b8bc0d8aSopenharmony_ci		if(xint.check())
274b8bc0d8aSopenharmony_ci		{
275b8bc0d8aSopenharmony_ci			int index= xint();
276b8bc0d8aSopenharmony_ci			if((index>=0) && (index<(long)size()))
277b8bc0d8aSopenharmony_ci				return Exif::Content(data_->ifd[index]);
278b8bc0d8aSopenharmony_ci			if((index<0) && (index>=-(long)size()))
279b8bc0d8aSopenharmony_ci				return Exif::Content(data_->ifd[size()+index]);
280b8bc0d8aSopenharmony_ci			PyErr_SetString(PyExc_IndexError,
281b8bc0d8aSopenharmony_ci							"invalid integer index into EXIF data");
282b8bc0d8aSopenharmony_ci			throw_error_already_set();
283b8bc0d8aSopenharmony_ci		}
284b8bc0d8aSopenharmony_ci		PyErr_SetString(PyExc_TypeError,
285b8bc0d8aSopenharmony_ci						"invalid index into EXIF data (integer or IFD expected)");
286b8bc0d8aSopenharmony_ci		throw_error_already_set();
287b8bc0d8aSopenharmony_ci		return Exif::Content(); // never reached
288b8bc0d8aSopenharmony_ci	}
289b8bc0d8aSopenharmony_ci
290b8bc0d8aSopenharmony_ci	iterator __iter__()
291b8bc0d8aSopenharmony_ci	{
292b8bc0d8aSopenharmony_ci		return iterator(data_->ifd, data_->ifd + EXIF_IFD_COUNT);
293b8bc0d8aSopenharmony_ci	}
294b8bc0d8aSopenharmony_ci};
295b8bc0d8aSopenharmony_ci
296b8bc0d8aSopenharmony_citemplate<class Rational, class Component>
297b8bc0d8aSopenharmony_cistruct RationalConverter
298b8bc0d8aSopenharmony_ci{
299b8bc0d8aSopenharmony_ci	RationalConverter()
300b8bc0d8aSopenharmony_ci	{
301b8bc0d8aSopenharmony_ci		converter::registry::insert(&convertible, &construct,
302b8bc0d8aSopenharmony_ci									type_id<Rational>());
303b8bc0d8aSopenharmony_ci	}
304b8bc0d8aSopenharmony_ci
305b8bc0d8aSopenharmony_ci    static void* convertible(PyObject* obj)
306b8bc0d8aSopenharmony_ci    {
307b8bc0d8aSopenharmony_ci		extract<tuple> xtup(obj);
308b8bc0d8aSopenharmony_ci		if(xtup.check())
309b8bc0d8aSopenharmony_ci		{
310b8bc0d8aSopenharmony_ci			tuple t= xtup();
311b8bc0d8aSopenharmony_ci			if((t.attr("__len__")() == 2) &&
312b8bc0d8aSopenharmony_ci			   extract<Component>(t[0]).check() &&
313b8bc0d8aSopenharmony_ci			   extract<Component>(t[1]).check())
314b8bc0d8aSopenharmony_ci			{
315b8bc0d8aSopenharmony_ci				Rational *result = new Rational;
316b8bc0d8aSopenharmony_ci				result->numerator =   extract<Component>(t[0])();
317b8bc0d8aSopenharmony_ci				result->denominator = extract<Component>(t[1])();
318b8bc0d8aSopenharmony_ci				return result;
319b8bc0d8aSopenharmony_ci			}
320b8bc0d8aSopenharmony_ci		}
321b8bc0d8aSopenharmony_ci		return NULL;
322b8bc0d8aSopenharmony_ci    }
323b8bc0d8aSopenharmony_ci
324b8bc0d8aSopenharmony_ci    static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data)
325b8bc0d8aSopenharmony_ci    {
326b8bc0d8aSopenharmony_ci		Rational const* r =
327b8bc0d8aSopenharmony_ci			static_cast<Rational*>(data->convertible);
328b8bc0d8aSopenharmony_ci        void* storage =
329b8bc0d8aSopenharmony_ci			((converter::rvalue_from_python_storage<Rational>*)data)->storage.bytes;
330b8bc0d8aSopenharmony_ci        new (storage) Rational();
331b8bc0d8aSopenharmony_ci		((Rational*)storage)->numerator = r->numerator;
332b8bc0d8aSopenharmony_ci		((Rational*)storage)->denominator = r->denominator;
333b8bc0d8aSopenharmony_ci        data->convertible = storage;
334b8bc0d8aSopenharmony_ci		delete r;
335b8bc0d8aSopenharmony_ci	}
336b8bc0d8aSopenharmony_ci
337b8bc0d8aSopenharmony_ci	static PyObject *convert(Rational r)
338b8bc0d8aSopenharmony_ci	{
339b8bc0d8aSopenharmony_ci		tuple t= make_tuple(r.numerator, r.denominator);
340b8bc0d8aSopenharmony_ci		PyObject *result= t.ptr();
341b8bc0d8aSopenharmony_ci		Py_INCREF(result);
342b8bc0d8aSopenharmony_ci		return result;
343b8bc0d8aSopenharmony_ci	}
344b8bc0d8aSopenharmony_ci};
345b8bc0d8aSopenharmony_ci
346b8bc0d8aSopenharmony_ciBOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(entrydumps, Exif::Entry::dump, 0, 1)
347b8bc0d8aSopenharmony_ciBOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(contentdumps, Exif::Content::dump, 0, 1)
348b8bc0d8aSopenharmony_ci
349b8bc0d8aSopenharmony_ciBOOST_PYTHON_MODULE(exif)
350b8bc0d8aSopenharmony_ci{
351b8bc0d8aSopenharmony_ci	RationalConverter<ExifRational, ExifLong>();
352b8bc0d8aSopenharmony_ci	RationalConverter<ExifSRational, ExifSLong>();
353b8bc0d8aSopenharmony_ci	to_python_converter<ExifRational,
354b8bc0d8aSopenharmony_ci		RationalConverter<ExifRational, ExifLong> >();
355b8bc0d8aSopenharmony_ci	to_python_converter<ExifSRational,
356b8bc0d8aSopenharmony_ci		RationalConverter<ExifSRational, ExifSLong> >();
357b8bc0d8aSopenharmony_ci
358b8bc0d8aSopenharmony_ci	enum_<ExifByteOrder>("ByteOrder")
359b8bc0d8aSopenharmony_ci		.value("MOTOROLA", EXIF_BYTE_ORDER_MOTOROLA)
360b8bc0d8aSopenharmony_ci		.value("INTEL", EXIF_BYTE_ORDER_INTEL);
361b8bc0d8aSopenharmony_ci
362b8bc0d8aSopenharmony_ci	def("name", &exif_byte_order_get_name);
363b8bc0d8aSopenharmony_ci
364b8bc0d8aSopenharmony_ci	enum_<ExifIfd>("IFD")
365b8bc0d8aSopenharmony_ci		.value("ZERO", EXIF_IFD_0)
366b8bc0d8aSopenharmony_ci		.value("ONE", EXIF_IFD_1)
367b8bc0d8aSopenharmony_ci		.value("EXIF", EXIF_IFD_EXIF)
368b8bc0d8aSopenharmony_ci		.value("GPS", EXIF_IFD_GPS)
369b8bc0d8aSopenharmony_ci		.value("INTEROPERABILITY", EXIF_IFD_INTEROPERABILITY);
370b8bc0d8aSopenharmony_ci	//.value("COUNT", EXIF_IFD_COUNT)
371b8bc0d8aSopenharmony_ci
372b8bc0d8aSopenharmony_ci	def("name", &exif_ifd_get_name);
373b8bc0d8aSopenharmony_ci
374b8bc0d8aSopenharmony_ci	enum_<ExifFormat>("Format")
375b8bc0d8aSopenharmony_ci		.value("BYTE", EXIF_FORMAT_BYTE)
376b8bc0d8aSopenharmony_ci		.value("ASCII", EXIF_FORMAT_ASCII)
377b8bc0d8aSopenharmony_ci		.value("SHORT", EXIF_FORMAT_SHORT)
378b8bc0d8aSopenharmony_ci		.value("LONG", EXIF_FORMAT_LONG)
379b8bc0d8aSopenharmony_ci		.value("RATIONAL", EXIF_FORMAT_RATIONAL)
380b8bc0d8aSopenharmony_ci		.value("UNDEFINED", EXIF_FORMAT_UNDEFINED)
381b8bc0d8aSopenharmony_ci		.value("SLONG", EXIF_FORMAT_SLONG)
382b8bc0d8aSopenharmony_ci		.value("SRATIONAL", EXIF_FORMAT_SRATIONAL);
383b8bc0d8aSopenharmony_ci
384b8bc0d8aSopenharmony_ci	def("name", &exif_format_get_name);
385b8bc0d8aSopenharmony_ci	def("size", &exif_format_get_size);
386b8bc0d8aSopenharmony_ci
387b8bc0d8aSopenharmony_ci	enum_<ExifTag>("Tag")
388b8bc0d8aSopenharmony_ci		.value("INTEROPERABILITY_INDEX", EXIF_TAG_INTEROPERABILITY_INDEX)
389b8bc0d8aSopenharmony_ci		.value("INTEROPERABILITY_VERSION", EXIF_TAG_INTEROPERABILITY_VERSION)
390b8bc0d8aSopenharmony_ci		.value("IMAGE_WIDTH", EXIF_TAG_IMAGE_WIDTH)
391b8bc0d8aSopenharmony_ci		.value("IMAGE_LENGTH", EXIF_TAG_IMAGE_LENGTH)
392b8bc0d8aSopenharmony_ci		.value("BITS_PER_SAMPLE", EXIF_TAG_BITS_PER_SAMPLE)
393b8bc0d8aSopenharmony_ci		.value("COMPRESSION", EXIF_TAG_COMPRESSION)
394b8bc0d8aSopenharmony_ci		.value("PHOTOMETRIC_INTERPRETATION", EXIF_TAG_PHOTOMETRIC_INTERPRETATION)
395b8bc0d8aSopenharmony_ci		.value("FILL_ORDER", EXIF_TAG_FILL_ORDER)
396b8bc0d8aSopenharmony_ci		.value("DOCUMENT_NAME", EXIF_TAG_DOCUMENT_NAME)
397b8bc0d8aSopenharmony_ci		.value("IMAGE_DESCRIPTION", EXIF_TAG_IMAGE_DESCRIPTION)
398b8bc0d8aSopenharmony_ci		.value("MAKE", EXIF_TAG_MAKE)
399b8bc0d8aSopenharmony_ci		.value("MODEL", EXIF_TAG_MODEL)
400b8bc0d8aSopenharmony_ci		.value("STRIP_OFFSETS", EXIF_TAG_STRIP_OFFSETS)
401b8bc0d8aSopenharmony_ci		.value("ORIENTATION", EXIF_TAG_ORIENTATION)
402b8bc0d8aSopenharmony_ci		.value("SAMPLES_PER_PIXEL", EXIF_TAG_SAMPLES_PER_PIXEL)
403b8bc0d8aSopenharmony_ci		.value("ROWS_PER_STRIP", EXIF_TAG_ROWS_PER_STRIP)
404b8bc0d8aSopenharmony_ci		.value("STRIP_BYTE_COUNTS", EXIF_TAG_STRIP_BYTE_COUNTS)
405b8bc0d8aSopenharmony_ci		.value("X_RESOLUTION", EXIF_TAG_X_RESOLUTION)
406b8bc0d8aSopenharmony_ci		.value("Y_RESOLUTION", EXIF_TAG_Y_RESOLUTION)
407b8bc0d8aSopenharmony_ci		.value("PLANAR_CONFIGURATION", EXIF_TAG_PLANAR_CONFIGURATION)
408b8bc0d8aSopenharmony_ci		.value("RESOLUTION_UNIT", EXIF_TAG_RESOLUTION_UNIT)
409b8bc0d8aSopenharmony_ci		.value("TRANSFER_FUNCTION", EXIF_TAG_TRANSFER_FUNCTION)
410b8bc0d8aSopenharmony_ci		.value("SOFTWARE", EXIF_TAG_SOFTWARE)
411b8bc0d8aSopenharmony_ci		.value("DATE_TIME", EXIF_TAG_DATE_TIME)
412b8bc0d8aSopenharmony_ci		.value("ARTIST", EXIF_TAG_ARTIST)
413b8bc0d8aSopenharmony_ci		.value("WHITE_POINT", EXIF_TAG_WHITE_POINT)
414b8bc0d8aSopenharmony_ci		.value("PRIMARY_CHROMATICITIES", EXIF_TAG_PRIMARY_CHROMATICITIES)
415b8bc0d8aSopenharmony_ci		.value("TRANSFER_RANGE", EXIF_TAG_TRANSFER_RANGE)
416b8bc0d8aSopenharmony_ci		.value("JPEG_PROC", EXIF_TAG_JPEG_PROC)
417b8bc0d8aSopenharmony_ci		.value("JPEG_INTERCHANGE_FORMAT", EXIF_TAG_JPEG_INTERCHANGE_FORMAT)
418b8bc0d8aSopenharmony_ci		.value("JPEG_INTERCHANGE_FORMAT_LENGTH", EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH)
419b8bc0d8aSopenharmony_ci		.value("YCBCR_COEFFICIENTS", EXIF_TAG_YCBCR_COEFFICIENTS)
420b8bc0d8aSopenharmony_ci		.value("YCBCR_SUB_SAMPLING", EXIF_TAG_YCBCR_SUB_SAMPLING)
421b8bc0d8aSopenharmony_ci		.value("YCBCR_POSITIONING", EXIF_TAG_YCBCR_POSITIONING)
422b8bc0d8aSopenharmony_ci		.value("REFERENCE_BLACK_WHITE", EXIF_TAG_REFERENCE_BLACK_WHITE)
423b8bc0d8aSopenharmony_ci		.value("RELATED_IMAGE_FILE_FORMAT", EXIF_TAG_RELATED_IMAGE_FILE_FORMAT)
424b8bc0d8aSopenharmony_ci		.value("RELATED_IMAGE_WIDTH", EXIF_TAG_RELATED_IMAGE_WIDTH)
425b8bc0d8aSopenharmony_ci		.value("RELATED_IMAGE_LENGTH", EXIF_TAG_RELATED_IMAGE_LENGTH)
426b8bc0d8aSopenharmony_ci		.value("CFA_REPEAT_PATTERN_DIM", EXIF_TAG_CFA_REPEAT_PATTERN_DIM)
427b8bc0d8aSopenharmony_ci		.value("CFA_PATTERN", EXIF_TAG_CFA_PATTERN)
428b8bc0d8aSopenharmony_ci		.value("BATTERY_LEVEL", EXIF_TAG_BATTERY_LEVEL)
429b8bc0d8aSopenharmony_ci		.value("COPYRIGHT", EXIF_TAG_COPYRIGHT)
430b8bc0d8aSopenharmony_ci		.value("EXPOSURE_TIME", EXIF_TAG_EXPOSURE_TIME)
431b8bc0d8aSopenharmony_ci		.value("FNUMBER", EXIF_TAG_FNUMBER)
432b8bc0d8aSopenharmony_ci		.value("IPTC_NAA", EXIF_TAG_IPTC_NAA)
433b8bc0d8aSopenharmony_ci		.value("EXIF_IFD_POINTER", EXIF_TAG_EXIF_IFD_POINTER)
434b8bc0d8aSopenharmony_ci		.value("INTER_COLOR_PROFILE", EXIF_TAG_INTER_COLOR_PROFILE)
435b8bc0d8aSopenharmony_ci		.value("EXPOSURE_PROGRAM", EXIF_TAG_EXPOSURE_PROGRAM)
436b8bc0d8aSopenharmony_ci		.value("SPECTRAL_SENSITIVITY", EXIF_TAG_SPECTRAL_SENSITIVITY)
437b8bc0d8aSopenharmony_ci		.value("GPS_INFO_IFD_POINTER", EXIF_TAG_GPS_INFO_IFD_POINTER)
438b8bc0d8aSopenharmony_ci		.value("ISO_SPEED_RATINGS", EXIF_TAG_ISO_SPEED_RATINGS)
439b8bc0d8aSopenharmony_ci		.value("OECF", EXIF_TAG_OECF)
440b8bc0d8aSopenharmony_ci		.value("EXIF_VERSION", EXIF_TAG_EXIF_VERSION)
441b8bc0d8aSopenharmony_ci		.value("DATE_TIME_ORIGINAL", EXIF_TAG_DATE_TIME_ORIGINAL)
442b8bc0d8aSopenharmony_ci		.value("DATE_TIME_DIGITIZED", EXIF_TAG_DATE_TIME_DIGITIZED)
443b8bc0d8aSopenharmony_ci		.value("COMPONENTS_CONFIGURATION", EXIF_TAG_COMPONENTS_CONFIGURATION)
444b8bc0d8aSopenharmony_ci		.value("COMPRESSED_BITS_PER_PIXEL", EXIF_TAG_COMPRESSED_BITS_PER_PIXEL)
445b8bc0d8aSopenharmony_ci		.value("SHUTTER_SPEED_VALUE", EXIF_TAG_SHUTTER_SPEED_VALUE)
446b8bc0d8aSopenharmony_ci		.value("APERTURE_VALUE", EXIF_TAG_APERTURE_VALUE)
447b8bc0d8aSopenharmony_ci		.value("BRIGHTNESS_VALUE", EXIF_TAG_BRIGHTNESS_VALUE)
448b8bc0d8aSopenharmony_ci		.value("EXPOSURE_BIAS_VALUE", EXIF_TAG_EXPOSURE_BIAS_VALUE)
449b8bc0d8aSopenharmony_ci		.value("MAX_APERTURE_VALUE", EXIF_TAG_MAX_APERTURE_VALUE)
450b8bc0d8aSopenharmony_ci		.value("SUBJECT_DISTANCE", EXIF_TAG_SUBJECT_DISTANCE)
451b8bc0d8aSopenharmony_ci		.value("METERING_MODE", EXIF_TAG_METERING_MODE)
452b8bc0d8aSopenharmony_ci		.value("LIGHT_SOURCE", EXIF_TAG_LIGHT_SOURCE)
453b8bc0d8aSopenharmony_ci		.value("FLASH", EXIF_TAG_FLASH)
454b8bc0d8aSopenharmony_ci		.value("FOCAL_LENGTH", EXIF_TAG_FOCAL_LENGTH)
455b8bc0d8aSopenharmony_ci		.value("SUBJECT_AREA", EXIF_TAG_SUBJECT_AREA)
456b8bc0d8aSopenharmony_ci		.value("MAKER_NOTE", EXIF_TAG_MAKER_NOTE)
457b8bc0d8aSopenharmony_ci		.value("USER_COMMENT", EXIF_TAG_USER_COMMENT)
458b8bc0d8aSopenharmony_ci		.value("SUBSEC_TIME", EXIF_TAG_SUBSEC_TIME)
459b8bc0d8aSopenharmony_ci		.value("SUB_SEC_TIME_ORIGINAL", EXIF_TAG_SUB_SEC_TIME_ORIGINAL)
460b8bc0d8aSopenharmony_ci		.value("SUB_SEC_TIME_DIGITIZED", EXIF_TAG_SUB_SEC_TIME_DIGITIZED)
461b8bc0d8aSopenharmony_ci		.value("FLASH_PIX_VERSION", EXIF_TAG_FLASH_PIX_VERSION)
462b8bc0d8aSopenharmony_ci		.value("COLOR_SPACE", EXIF_TAG_COLOR_SPACE)
463b8bc0d8aSopenharmony_ci		.value("PIXEL_X_DIMENSION", EXIF_TAG_PIXEL_X_DIMENSION)
464b8bc0d8aSopenharmony_ci		.value("PIXEL_Y_DIMENSION", EXIF_TAG_PIXEL_Y_DIMENSION)
465b8bc0d8aSopenharmony_ci		.value("RELATED_SOUND_FILE", EXIF_TAG_RELATED_SOUND_FILE)
466b8bc0d8aSopenharmony_ci		.value("INTEROPERABILITY_IFD_POINTER", EXIF_TAG_INTEROPERABILITY_IFD_POINTER)
467b8bc0d8aSopenharmony_ci		.value("FLASH_ENERGY", EXIF_TAG_FLASH_ENERGY)
468b8bc0d8aSopenharmony_ci		.value("SPATIAL_FREQUENCY_RESPONSE", EXIF_TAG_SPATIAL_FREQUENCY_RESPONSE)
469b8bc0d8aSopenharmony_ci		.value("FOCAL_PLANE_X_RESOLUTION", EXIF_TAG_FOCAL_PLANE_X_RESOLUTION)
470b8bc0d8aSopenharmony_ci		.value("FOCAL_PLANE_Y_RESOLUTION", EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION)
471b8bc0d8aSopenharmony_ci		.value("FOCAL_PLANE_RESOLUTION_UNIT", EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT)
472b8bc0d8aSopenharmony_ci		.value("SUBJECT_LOCATION", EXIF_TAG_SUBJECT_LOCATION)
473b8bc0d8aSopenharmony_ci		.value("EXPOSURE_INDEX", EXIF_TAG_EXPOSURE_INDEX)
474b8bc0d8aSopenharmony_ci		.value("SENSING_METHOD", EXIF_TAG_SENSING_METHOD)
475b8bc0d8aSopenharmony_ci		.value("FILE_SOURCE", EXIF_TAG_FILE_SOURCE)
476b8bc0d8aSopenharmony_ci		.value("SCENE_TYPE", EXIF_TAG_SCENE_TYPE)
477b8bc0d8aSopenharmony_ci		.value("NEW_CFA_PATTERN", EXIF_TAG_NEW_CFA_PATTERN)
478b8bc0d8aSopenharmony_ci		.value("CUSTOM_RENDERED", EXIF_TAG_CUSTOM_RENDERED)
479b8bc0d8aSopenharmony_ci		.value("EXPOSURE_MODE", EXIF_TAG_EXPOSURE_MODE)
480b8bc0d8aSopenharmony_ci		.value("WHITE_BALANCE", EXIF_TAG_WHITE_BALANCE)
481b8bc0d8aSopenharmony_ci		.value("DIGITAL_ZOOM_RATIO", EXIF_TAG_DIGITAL_ZOOM_RATIO)
482b8bc0d8aSopenharmony_ci		.value("FOCAL_LENGTH_IN_35MM_FILM", EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM)
483b8bc0d8aSopenharmony_ci		.value("SCENE_CAPTURE_TYPE", EXIF_TAG_SCENE_CAPTURE_TYPE)
484b8bc0d8aSopenharmony_ci		.value("GAIN_CONTROL", EXIF_TAG_GAIN_CONTROL)
485b8bc0d8aSopenharmony_ci		.value("CONTRAST", EXIF_TAG_CONTRAST)
486b8bc0d8aSopenharmony_ci		.value("SATURATION", EXIF_TAG_SATURATION)
487b8bc0d8aSopenharmony_ci		.value("SHARPNESS", EXIF_TAG_SHARPNESS)
488b8bc0d8aSopenharmony_ci		.value("DEVICE_SETTING_DESCRIPTION", EXIF_TAG_DEVICE_SETTING_DESCRIPTION)
489b8bc0d8aSopenharmony_ci		.value("SUBJECT_DISTANCE_RANGE", EXIF_TAG_SUBJECT_DISTANCE_RANGE)
490b8bc0d8aSopenharmony_ci		.value("IMAGE_UNIQUE_ID", EXIF_TAG_IMAGE_UNIQUE_ID);
491b8bc0d8aSopenharmony_ci
492b8bc0d8aSopenharmony_ci	def("name", &exif_tag_get_name);
493b8bc0d8aSopenharmony_ci	def("title", &exif_tag_get_title);
494b8bc0d8aSopenharmony_ci	def("description", &exif_tag_get_description);
495b8bc0d8aSopenharmony_ci
496b8bc0d8aSopenharmony_ci	class_<PythonEntry>("Entry")
497b8bc0d8aSopenharmony_ci		.add_property("tag", &Exif::Entry::tag)
498b8bc0d8aSopenharmony_ci		.add_property("format", &Exif::Entry::format)
499b8bc0d8aSopenharmony_ci		.add_property("components", &Exif::Entry::components)
500b8bc0d8aSopenharmony_ci		.add_property("data", &PythonEntry::data,
501b8bc0d8aSopenharmony_ci					  &PythonEntry::setData)
502b8bc0d8aSopenharmony_ci		.def("value", &Exif::Entry::value)
503b8bc0d8aSopenharmony_ci		.def("briefValue", &Exif::Entry::briefValue)
504b8bc0d8aSopenharmony_ci		.def("dump", &Exif::Entry::dump);//, entrydumps());
505b8bc0d8aSopenharmony_ci
506b8bc0d8aSopenharmony_ci	class_<PythonContent::iterator>("ContentIterator", no_init)
507b8bc0d8aSopenharmony_ci		.def("next", &PythonContent::iterator::next);
508b8bc0d8aSopenharmony_ci	class_<PythonContent>("Content")
509b8bc0d8aSopenharmony_ci		.def("__len__", &Exif::Content::size)
510b8bc0d8aSopenharmony_ci		.def("__getitem__", &PythonContent::entry)
511b8bc0d8aSopenharmony_ci		.def("__iter__", &PythonContent::__iter__)
512b8bc0d8aSopenharmony_ci 		.def("dump", &Exif::Content::dump);//, contentdumps());
513b8bc0d8aSopenharmony_ci
514b8bc0d8aSopenharmony_ci	class_<PythonData::iterator>("DataIterator", no_init)
515b8bc0d8aSopenharmony_ci		.def("next", &PythonData::iterator::next);
516b8bc0d8aSopenharmony_ci	class_<PythonData>("Data")
517b8bc0d8aSopenharmony_ci		.def(init<const char *>())
518b8bc0d8aSopenharmony_ci		.def(init<const unsigned char *, unsigned int>())
519b8bc0d8aSopenharmony_ci		.def("__len__", &Exif::Data::size)
520b8bc0d8aSopenharmony_ci		.def("__getitem__", &PythonData::ifdContent)
521b8bc0d8aSopenharmony_ci		.def("__iter__", &PythonData::__iter__)
522b8bc0d8aSopenharmony_ci		.def("byteOrder", &Exif::Data::byteOrder)
523b8bc0d8aSopenharmony_ci		.def("dump", &Exif::Data::dump);
524b8bc0d8aSopenharmony_ci}
525